24784774 Upgrade 11.3-SRU to OpenSSL 1.0.2 s11u3-sru
authorRonald Jordan <ron.jordan@oracle.com>
Wed, 26 Oct 2016 13:19:33 -0700
branchs11u3-sru
changeset 7163 ee09edbd5876
parent 7159 59b406bc4a3a
child 7164 b2abbab8e6d5
24784774 Upgrade 11.3-SRU to OpenSSL 1.0.2 20358335 memory leak in libcrypto 21297601 32-bit FIPS openssl(1) should link to the mediator link 21791492 Workaround to suppress the link check error should be removed 22021385 openssl ts sub-command dumps core 22021787 openssl s_client sub-command dumps core 22445522 openssl makefile contains undeclared dependency on rsync 22859741 Update OpenSSL FIPS module to 2.0.12 23230454 Use DES3 for pkcs12 certificate encryption 23285559 ssh libcrypto`solaris_locking_setup() atfork handler calls malloc() 24377801 solaris_dynlock_create() should check for a ret val of 0 from pthread_mutex_init 24943813 problem in LIBRARY/OPENSSL
components/openssl/README
components/openssl/common/engines/pkcs11/e_pk11.c
components/openssl/common/engines/pkcs11/e_pk11.h
components/openssl/common/engines/pkcs11/e_pk11_err.c
components/openssl/common/engines/pkcs11/e_pk11_err.h
components/openssl/common/engines/pkcs11/e_pk11_pub.c
components/openssl/common/engines/pkcs11/e_pk11_uri.c
components/openssl/common/engines/pkcs11/e_pk11_uri.h
components/openssl/common/patches/008-6193522.patch
components/openssl/common/patches/015-pkcs11_engine-0.9.8a.patch
components/openssl/common/patches/018-compiler_opts.patch
components/openssl/common/patches/020-remove_rpath.patch
components/openssl/common/patches/023-noexstack.patch
components/openssl/common/patches/027-6978791.patch
components/openssl/common/patches/028-enginesdir.patch
components/openssl/common/patches/029-fork_safe.patch
components/openssl/common/patches/032-aes_cbc_len_check.patch
components/openssl/common/patches/036-evp_leak.patch
components/openssl/common/patches/039-internal_tests.patch
components/openssl/common/patches/040-uninitialized_ctx.patch
components/openssl/common/patches/041_rm_sslv2_v3.patch
components/openssl/common/patches/043-x86_wrong_platform.patch
components/openssl/common/patches/044-suppress_v8plus_abi_warnings.patch
components/openssl/common/patches/045-openssl-usage.patch
components/openssl/common/patches/046-pkcs12-default-cipher.patch
components/openssl/common/patches/050-segfault_configfile.patch
components/openssl/common/patches/051-segfault_export.patch
components/openssl/common/patches/054-xmpp-detection.patch
components/openssl/openssl-1.0.1-fips-140/Makefile
components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11.c
components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11.h
components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_err.c
components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_err.h
components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_pub.c
components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_uri.c
components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_uri.h
components/openssl/openssl-1.0.1-fips-140/llib-lcrypto
components/openssl/openssl-1.0.1-fips-140/llib-lssl
components/openssl/openssl-1.0.1-fips-140/openssl-1.0.1-fips-140.license
components/openssl/openssl-1.0.1-fips-140/openssl-1.0.1-fips-140.p5m
components/openssl/openssl-1.0.1-fips-140/patches-post-config/opensslconf.patch
components/openssl/openssl-1.0.1-fips-140/patches/08-6193522.patch
components/openssl/openssl-1.0.1-fips-140/patches/11-6546806.patch
components/openssl/openssl-1.0.1-fips-140/patches/15-pkcs11_engine-0.9.8a.patch
components/openssl/openssl-1.0.1-fips-140/patches/18-compiler_opts.patch
components/openssl/openssl-1.0.1-fips-140/patches/20-remove_rpath.patch
components/openssl/openssl-1.0.1-fips-140/patches/23-noexstack.patch
components/openssl/openssl-1.0.1-fips-140/patches/26-openssl_fips.patch
components/openssl/openssl-1.0.1-fips-140/patches/27-6978791.patch
components/openssl/openssl-1.0.1-fips-140/patches/28-enginesdir.patch
components/openssl/openssl-1.0.1-fips-140/patches/29_fork_safe.patch
components/openssl/openssl-1.0.1-fips-140/patches/32_aes_cbc_len_check.patch
components/openssl/openssl-1.0.1-fips-140/patches/33_cert_chain.patch
components/openssl/openssl-1.0.1-fips-140/patches/36_evp_leak.patch
components/openssl/openssl-1.0.1-fips-140/patches/38_remove_illegal_instruction_calls.patch
components/openssl/openssl-1.0.1-fips-140/patches/39_test.patch
components/openssl/openssl-1.0.1-fips-140/patches/41_uninitialized_ctx.patch
components/openssl/openssl-1.0.1-fips-140/patches/42_rm_sslv2.patch
components/openssl/openssl-1.0.1-fips-140/patches/47_xmpp_detection.patch
components/openssl/openssl-1.0.1/Makefile
components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11.c
components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11.h
components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11_err.c
components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11_err.h
components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11_pub.c
components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11_uri.c
components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11_uri.h
components/openssl/openssl-1.0.1/inline-t4/aest4-sparcv9.pl
components/openssl/openssl-1.0.1/inline-t4/dest4-sparcv9.pl
components/openssl/openssl-1.0.1/inline-t4/md5-sparcv9.pl
components/openssl/openssl-1.0.1/inline-t4/sparc_arch.h
components/openssl/openssl-1.0.1/inline-t4/sparct4-mont.pl
components/openssl/openssl-1.0.1/inline-t4/sparcv9-gf2m.pl
components/openssl/openssl-1.0.1/inline-t4/sparcv9_modes.pl
components/openssl/openssl-1.0.1/inline-t4/vis3-mont.pl
components/openssl/openssl-1.0.1/llib-lcrypto
components/openssl/openssl-1.0.1/llib-lssl
components/openssl/openssl-1.0.1/mapfile.wanboot
components/openssl/openssl-1.0.1/openssl-1.0.1.license
components/openssl/openssl-1.0.1/openssl-1.0.1.p5m
components/openssl/openssl-1.0.1/patches-post-config/opensslconf.patch
components/openssl/openssl-1.0.1/patches/08-6193522.patch
components/openssl/openssl-1.0.1/patches/11-6546806.patch
components/openssl/openssl-1.0.1/patches/14-manpage_openssl.patch
components/openssl/openssl-1.0.1/patches/15-pkcs11_engine-0.9.8a.patch
components/openssl/openssl-1.0.1/patches/18-compiler_opts.patch
components/openssl/openssl-1.0.1/patches/20-remove_rpath.patch
components/openssl/openssl-1.0.1/patches/23-noexstack.patch
components/openssl/openssl-1.0.1/patches/27-6978791.patch
components/openssl/openssl-1.0.1/patches/28-enginesdir.patch
components/openssl/openssl-1.0.1/patches/29_fork_safe.patch
components/openssl/openssl-1.0.1/patches/30_wanboot.patch
components/openssl/openssl-1.0.1/patches/32_aes_cbc_len_check.patch
components/openssl/openssl-1.0.1/patches/33_cert_chain.patch
components/openssl/openssl-1.0.1/patches/36_evp_leak.patch
components/openssl/openssl-1.0.1/patches/37_openssl_t4_inline.patch
components/openssl/openssl-1.0.1/patches/38_remove_illegal_instruction_calls.patch
components/openssl/openssl-1.0.1/patches/39_internal_tests.patch
components/openssl/openssl-1.0.1/patches/40_suppress_v8plus_abi_warnings.patch
components/openssl/openssl-1.0.1/patches/41_uninitialized_ctx.patch
components/openssl/openssl-1.0.1/patches/42_rm_sslv2.patch
components/openssl/openssl-1.0.1/patches/45-use-srln.patch
components/openssl/openssl-1.0.1/patches/47_xmpp_detection.patch
components/openssl/openssl-1.0.1/wanboot-openssl/wanboot-stubs.c
components/openssl/openssl-default/Makefile
components/openssl/openssl-default/llib-lcrypto
components/openssl/openssl-default/llib-lssl
components/openssl/openssl-default/mapfile.wanboot
components/openssl/openssl-default/openssl-default.license
components/openssl/openssl-default/openssl-default.p5m
components/openssl/openssl-default/patches-post-config/opensslconf.patch
components/openssl/openssl-default/patches/101-manpage_openssl.patch
components/openssl/openssl-default/patches/102-wanboot.patch
components/openssl/openssl-default/wanboot-openssl/wanboot-stubs.c
components/openssl/openssl-fips-140/Makefile
components/openssl/openssl-fips-140/llib-lcrypto
components/openssl/openssl-fips-140/llib-lssl
components/openssl/openssl-fips-140/openssl-fips-140.license
components/openssl/openssl-fips-140/openssl-fips-140.p5m
components/openssl/openssl-fips-140/patches-post-config/opensslconf.patch
components/openssl/openssl-fips-140/patches/201-openssl_fips.patch
components/openssl/openssl-fips-140/patches/203-multi-definition.patch
components/openssl/openssl-fips/Makefile
--- a/components/openssl/README	Wed Oct 12 06:26:22 2016 -0700
+++ b/components/openssl/README	Wed Oct 26 13:19:33 2016 -0700
@@ -18,138 +18,37 @@
 #
 # CDDL HEADER END
 #
-# Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
 #
 
 
 Build Layout
 ---
 
-OpenSSL build is run four times. Once for regular dynamic 1.0.1 non-fips, once 
-for static 1.0.1 bits to link with standalone wanboot binary, once for 1.0.1
-fips-140, and once for 1.0.1 FIPS-140 canister (in the openssl-fips component)
-needed to build 1.0.1 FIPS-140 certified libraries. All builds apart from 
+OpenSSL build is run four times. Once for regular dynamic non-fips, once 
+for static bits to link with standalone wanboot binary, once for fips-140,
+and once for FIPS-140 canister (in the openssl-fips component)
+needed to build FIPS-140 certified libraries. All builds apart from 
 static libraries for wanboot are done for 32 and 64 bits. So, in total, OpenSSL
 is built seven times. OpenSSL for wanboot is only built on sparc.
 
 See also comments in all the Makefiles for more information.
 
 OpenSSL Version
----
-
-For non-FIPS build, we currently deliver OpenSSL 1.0.1 with some updates
-from OpenSSL 1.0.2 to make T4 instructions embedded in the OpenSSL
-upstream code.  As of April 2013, 1.0.2 is not yet released, and therefore,
-we have decided to patch the code.
-The following files/code are copied in from 1.0.2.
-added:
-   components/openssl/openssl-1.0.1/inline-t4/aest4-sparcv9.pl
-   components/openssl/openssl-1.0.1/inline-t4/dest4-sparcv9.pl
-   components/openssl/openssl-1.0.1/inline-t4/md5-sparcv9.pl
-   components/openssl/openssl-1.0.1/inline-t4/sparc_arch.h
-   components/openssl/openssl-1.0.1/inline-t4/sparct4-mont.pl
-   components/openssl/openssl-1.0.1/inline-t4/sparcv9_modes.pl
-   components/openssl/openssl-1.0.1/inline-t4/sparcv9-gf2m.pl
-   components/openssl/openssl-1.0.1/inline-t4/vis3-mont.pl
-   components/openssl/openssl-1.0.1/patches/openssl-t4-inline.sparc-patch
-
+--------------
 
 The non-fips Build.
 ---
 
-The non-fips build is the main build of OpenSSL and includes the regular
+The non-fips build is the 'default' build of OpenSSL and includes the regular
 binaries, libraries, man pages, and header files.
 
-Patches
----
-
-08-6193522.patch
-Give CA.pl better defaults. See 6193522 for more information.
-
-11-6546806.patch
-Make sure the HMAC_CTX_init(3) man page gets delivered. See 6546806 for
-more information.
-
-14-manpage_openssl.patch
-Force openssl to install man pages into man[1357]openssl instead of man[1357].
-
-15-pkcs11_engine-0.9.8a.patch
-Patch which adds the pkcs11 engine. See also the engines/pkcs11
-sub-directory. 
-
-18-compiler_opts.patch
-Adds five Solaris specific configurations (both 32bit and 64bit for both sparc
-and x86, plus 64bit sparc for wanboot) to Configure which are then explicitly
-used by the Makefiles. Wanboot configuration is special in that it doesn't link
-with libc and uses -xF=%all to put functions in separate sections, so that
-unused code can be discarded.
-
-Care should be taken if modifying this patch as changes to compile-time options
-can change the ABI. One example of this is the use of RC4_INT vs RC4_CHAR.
-
-20-remove_rpath.patch
-Prevent build binaries having an unnecessary runpath (/lib).
-
-23-noexstack.patch
-Build with non-executable stacks and non-executable data (x86).
-
-27-6978791.patch
-Modifies Makefile.shared so that libssl is built with -znodelete.
-
-28-enginesdir.patch
-Adds a new "enginesdir" option to the Configure script which allows a user to
-specify the engines directory.
-
-30_wanboot.patch:
-Wanboot specific patches.
-- modified Makefiles not to build in engines apps test tools
-- not using vfprintf for error print in crypto/cryptlib.c
-- not using ERR_load_DSO_strings() in crypto/err/err_all.c
-- not using EVP_read_pw_string() in crypto/evp/evp_key.c
-    - reading password is implemented in disabled DES library
-- avoid select() in crypto/rand/rand_unix.c
-- direct reading of IP to avoid sscanf() in crypto/x509v3/v3_utl.c
-- using functions from libsock in e_os.h
-- by-passing version of sparc detection in crypto/sparcv9cap.c
-    - results in not using FPU for big numbers multiplication
-    - should be ok - original detection seems broken, FPU gets never used
-- implementation of atoi()
-- avoid using ssl_fill_hello_random() in s3_clnt.c
-
-36_evp_leak.patch:
-Solaris-specific fix for mem leak caused by EVP_EncryptFinal_ex()
-and EVP_DecryptFinal_ex() not cleaning up properly.
-
-37_openssl_t4_inline.patch
-SPARC-only patch.
-Add patch to support inline T4 instruction in OpenSSL upstream code until
-OpenSSL 1.0.2 is released.
-
-38_remove_illegal_instruction_calls.patch
-SPARC patch. Solaris-only patch.
-Remove _sparcv9_random instruction from sparcv9cap.c.
-It is not supported on any sparc platforms. 
-
-opensslconf.patch
-Modifies opensslconf.h so that it is suitable for both 32bit and 64bit installs.
-OpenSSL either builds for 32bit or 64bit - it doesn't allow for combined 32bit
-and 64bit builds.
 
 The fips Build
 ---
 
-We are now shipping FIPS-140 certified OpenSSL 1.0.1 with S12 and S11.2.
+We are now shipping FIPS-140 certified OpenSSL with S11.2 and later.
 The admin may choose to activate 'openssl-fips' implementation using 'pkg mediator'.
-The change will come soon.
-
-
-Patches
----
-
-All the patches from 1.0.1 (non-fips) are used in 1.0.1(fips) as well aside from
-14-manpage_openssl.patch which is not needed since we do not deliver 1.0.1(fips) man
-pages.  Once we make fips version public, we should deliver man page.
-(coming soon)
 
 The wanboot Build
 ----
@@ -181,7 +80,7 @@
 first build static standalone openssl bits in Userland. As a site effect,
 static libraries libssl.a and libcrypto.a are created in build/sparcv9-wanboot.
 
-    $ cd $USERLAND/components/openssl/openssl-1.0.1 ; gmake build
+    $ cd $USERLAND/components/openssl/openssl-default ; gmake build
 
 Next, collect some information from linking wanboot static libraries in ON.
 This can be done by the following hack.
@@ -189,16 +88,16 @@
     $ cd $ON/usr/src/psm/stand/boot/sparcv9/sun4
     $ touch wanboot.o
     $ LD_OPTIONS="-Dfiles,symbols,output=ld.dbg \
-        -L$USERLAND/components/openssl/openssl-1.0.1/build/sparcv9-wanboot " \
+        -L$USERLAND/components/openssl/openssl-default/build/sparcv9-wanboot " \
         WAN_OPENSSL=" -lwanboot -lssl -lcrypto" dmake all
 
 The following sort of information ends up in ld.dbg (note that the debugging
 output from the link-editor is not considered a 'stable interface' and may
 change in the future):
 
-    debug: file=/builds/tkuthan/ul-wanboot-rebuilt/components/openssl/openssl-1.0.1/build/sparcv9-wanboot/libcrypto.a(sparcv9cap.o)  [ ET_REL ]
+    debug: file=/builds/tkuthan/ul-wanboot-rebuilt/components/openssl/openssl-default/build/sparcv9-wanboot/libcrypto.a(sparcv9cap.o)  [ ET_REL ]
     debug:
-    debug: symbol table processing; file=/builds/tkuthan/ul-wanboot-rebuilt/components/openssl/openssl-1.0.1/build/sparcv9-wanboot/libcrypto.a(sparcv9cap.o)  [ ET_REL ]
+    debug: symbol table processing; file=/builds/tkuthan/ul-wanboot-rebuilt/components/openssl/openssl-default/build/sparcv9-wanboot/libcrypto.a(sparcv9cap.o)  [ ET_REL ]
     debug: symbol[1]=sparcv9cap.c
     ....
 
@@ -210,7 +109,7 @@
     USERLAND=/builds/tkuthan/ul-wanboot-rebuilt
     ON=/builds/tkuthan/on11u1-wanboot-rti
  
-    BUILD=$USERLAND/components/openssl/openssl-1.0.1/build/sparcv9-wanboot
+    BUILD=$USERLAND/components/openssl/openssl-default/build/sparcv9-wanboot
     LD_DBG=$ON/usr/src/psm/stand/boot/sparcv9/sun4/ld.dbg
  
     for i in `find $BUILD/crypto $BUILD/ssl -name '*.o'`
@@ -272,23 +171,22 @@
 ----
 
 With every upgrade of OpenSSL, it is necessary to make sure wanboot builds and
-works well with the new bits.
+works well with the new bits (post lullaby).
 
 Provided you have a freshly built ON workspace, you can link wanboot with new
-OpenSSL bits by redefining WAN_OPENSSL macro:
+OpenSSL bits as follows:
 
     # copy wanboot-openssl.o to ON build machine
     cp wanboot-openssl.o /var/tmp/
 
     # prepare to rebuild wanboot
     cd $ON
-    bldenv developer.sh
     cd usr/src/psm/stand/boot/sparcv9/sun4
 
     # hack to force a rebuild
     touch wanboot.o
 
-    # link new OpenSSL to wanboot
+    # link new OpenSSL to wanboot	    # modify Makefile and assign the WAN_OPENSSL macro to your binary
     WAN_OPENSSL=/var/tmp/wanboot-openssl.o dmake all
 
 Wanboot should build without warning.
@@ -313,3 +211,27 @@
 
 Finally, resulting wanboot binary shall be deployed on some install server and
 wanbooting from this server shall be tested.
+
+===============
+Common Patches
+===============
+
+Common patch files are located in the components/openssl/common/patches dir,
+and they are copied to both FIPS and non-FIPS 'patches' dir as soon as the
+Makefile is parsed.  The Common patch filename has prefix '0',
+
+=========================
+Non-FIPS specific Patches
+=========================
+
+Non-FIPS specific patch files are located in the
+components/openssl/openssl-default/patches dir.
+The Non-FIPS specific patch filename has prefix '1',
+
+=========================
+FIPS specific Patches
+=========================
+
+FIPS specific patch files are located in the
+components/openssl/openssl-fips-140/patches dir.
+The FIPS specific patch filename has prefix '2',
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/engines/pkcs11/e_pk11.c	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,3711 @@
+/*
+ * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* crypto/engine/e_pk11.c */
+/*
+ * This product includes software developed by the OpenSSL Project for
+ * use in the OpenSSL Toolkit (http://www.openssl.org/).
+ *
+ * This project also referenced hw_pkcs11-0.9.7b.patch written by
+ * Afchine Madjlessi.
+ */
+/*
+ * ====================================================================
+ * 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
+ *    [email protected].
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <strings.h>
+
+#include <openssl/e_os2.h>
+#include <openssl/crypto.h>
+#include <openssl/engine.h>
+#include <openssl/dso.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/md5.h>
+#include <openssl/pem.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/aes.h>
+#include <dlfcn.h>
+#include <pthread.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_PK11
+
+/* label for debug messages printed on stderr */
+#define	PK11_DBG	"PKCS#11 ENGINE DEBUG"
+/* prints a lot of debug messages on stderr about slot selection process */
+#undef	DEBUG_SLOT_SELECTION
+/*
+ * Solaris specific code. See comment at check_hw_mechanisms() for more
+ * information.
+ */
+#if defined(__SVR4) && defined(__sun)
+#define	SOLARIS_HW_SLOT_SELECTION
+#endif
+
+#ifdef	SOLARIS_HW_SLOT_SELECTION
+#include <sys/auxv.h>
+#endif
+
+#ifdef DEBUG_SLOT_SELECTION
+#define	DEBUG_SLOT_SEL(...) fprintf(stderr, __VA_ARGS__)
+#else
+#define	DEBUG_SLOT_SEL(...)
+#endif
+
+#include <security/cryptoki.h>
+#include <security/pkcs11.h>
+#include "e_pk11.h"
+#include "e_pk11_uri.h"
+
+static CK_BBOOL pk11_true = CK_TRUE;
+static CK_BBOOL pk11_false = CK_FALSE;
+#define	PK11_ENGINE_LIB_NAME "PKCS#11 engine"
+#include "e_pk11_err.c"
+#include "e_pk11_uri.c"
+#include "e_pk11_pub.c"
+
+/*
+ * We use this lock to prevent multiple C_Login()s, guard getpassphrase(),
+ * uri_struct manipulation, and static token info. All of that is used by the
+ * RSA keys by reference feature.
+ */
+pthread_mutex_t *uri_lock = NULL;
+
+#ifdef	SOLARIS_HW_SLOT_SELECTION
+/*
+ * Tables for symmetric ciphers and digest mechs found in the pkcs11_kernel
+ * library. See comment at check_hw_mechanisms() for more information.
+ */
+int *hw_cnids;
+int *hw_dnids;
+#endif	/* SOLARIS_HW_SLOT_SELECTION */
+
+/* PKCS#11 session caches and their locks for all operation types */
+static PK11_CACHE session_cache[OP_MAX];
+
+/*
+ * We cache the flags so that we do not have to run C_GetTokenInfo() again when
+ * logging into the token.
+ */
+CK_FLAGS pubkey_token_flags;
+
+/*
+ * As stated in v2.20, 11.7 Object Management Function, in section for
+ * C_FindObjectsInit(), at most one search operation may be active at a given
+ * time in a given session. Therefore, C_Find{,Init,Final}Objects() should be
+ * grouped together to form one atomic search operation. This is already
+ * ensured by the property of unique PKCS#11 session handle used for each
+ * PK11_SESSION object.
+ *
+ * This is however not the biggest concern - maintaining consistency of the
+ * underlying object store is more important. The same section of the spec also
+ * says that one thread can be in the middle of a search operation while another
+ * thread destroys the object matching the search template which would result in
+ * invalid handle returned from the search operation.
+ *
+ * Hence, the following locks are used for both protection of the object stores.
+ * They are also used for active list protection.
+ */
+pthread_mutex_t *find_lock[OP_MAX] = { NULL };
+
+/*
+ * lists of asymmetric key handles which are active (referenced by at least one
+ * PK11_SESSION structure, either held by a thread or present in free_session
+ * list) for given algorithm type
+ */
+PK11_active *active_list[OP_MAX] = { NULL };
+
+/*
+ * Create all secret key objects in a global session so that they are available
+ * to use for other sessions. These other sessions may be opened or closed
+ * without losing the secret key objects.
+ */
+static CK_SESSION_HANDLE	global_session = CK_INVALID_HANDLE;
+
+/* Index for the supported ciphers */
+enum pk11_cipher_id {
+	PK11_DES_CBC,
+	PK11_DES3_CBC,
+	PK11_DES_ECB,
+	PK11_DES3_ECB,
+	PK11_RC4,
+	PK11_AES_128_CBC,
+	PK11_AES_192_CBC,
+	PK11_AES_256_CBC,
+	PK11_AES_128_ECB,
+	PK11_AES_192_ECB,
+	PK11_AES_256_ECB,
+	PK11_BLOWFISH_CBC,
+	PK11_AES_128_CTR,
+	PK11_AES_192_CTR,
+	PK11_AES_256_CTR,
+	PK11_CIPHER_MAX
+};
+
+/* Index for the supported digests */
+enum pk11_digest_id {
+	PK11_MD5,
+	PK11_SHA1,
+	PK11_SHA224,
+	PK11_SHA256,
+	PK11_SHA384,
+	PK11_SHA512,
+	PK11_DIGEST_MAX
+};
+
+typedef struct PK11_CIPHER_st
+	{
+	enum pk11_cipher_id	id;
+	int			nid;
+	int			iv_len;
+	int			min_key_len;
+	int			max_key_len;
+	CK_KEY_TYPE		key_type;
+	CK_MECHANISM_TYPE	mech_type;
+	} PK11_CIPHER;
+
+typedef struct PK11_DIGEST_st
+	{
+	enum pk11_digest_id	id;
+	int			nid;
+	CK_MECHANISM_TYPE	mech_type;
+	} PK11_DIGEST;
+
+/* ENGINE level stuff */
+static int pk11_init(ENGINE *e);
+static int pk11_library_init(ENGINE *e);
+static int pk11_finish(ENGINE *e);
+static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
+static int pk11_destroy(ENGINE *e);
+
+/* RAND stuff */
+static void pk11_rand_seed(const void *buf, int num);
+static void pk11_rand_add(const void *buf, int num, double add_entropy);
+static void pk11_rand_cleanup(void);
+static int pk11_rand_bytes(unsigned char *buf, int num);
+static int pk11_rand_status(void);
+
+/* These functions are also used in other files */
+PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
+void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
+
+/* active list manipulation functions used in this file */
+extern int pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type);
+extern void pk11_free_active_list(PK11_OPTYPE type);
+
+#ifndef OPENSSL_NO_RSA
+int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
+int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
+int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
+#endif
+#ifndef OPENSSL_NO_DSA
+int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
+int pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
+int pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
+#endif
+#ifndef OPENSSL_NO_DH
+int pk11_destroy_dh_key_objects(PK11_SESSION *session);
+int pk11_destroy_dh_object(PK11_SESSION *session, CK_BBOOL uselock);
+#endif
+
+/* Local helper functions */
+static int pk11_free_all_sessions(void);
+static int pk11_free_session_list(PK11_OPTYPE optype);
+static int pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype);
+static int pk11_destroy_cipher_key_objects(PK11_SESSION *session);
+static int pk11_destroy_object(CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE oh,
+    CK_BBOOL persistent);
+static const char *get_PK11_LIBNAME(void);
+static void free_PK11_LIBNAME(void);
+static long set_PK11_LIBNAME(const char *name);
+
+/* Symmetric cipher and digest support functions */
+static int cipher_nid_to_pk11(int nid);
+static int pk11_usable_ciphers(const int **nids);
+static int pk11_usable_digests(const int **nids);
+static int pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+	const unsigned char *iv, int enc);
+static int pk11_cipher_final(PK11_SESSION *sp);
+static int pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+	const unsigned char *in, size_t inl);
+static int pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx);
+static int pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
+	const int **nids, int nid);
+static int pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
+	const int **nids, int nid);
+static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
+	const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp);
+static int check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key,
+	int key_len);
+static int md_nid_to_pk11(int nid);
+static int pk11_digest_init(EVP_MD_CTX *ctx);
+static int pk11_digest_update(EVP_MD_CTX *ctx, const void *data,
+	size_t count);
+static int pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md);
+static int pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);
+static int pk11_digest_cleanup(EVP_MD_CTX *ctx);
+
+static int pk11_choose_slots(int *any_slot_found);
+static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
+    CK_SLOT_ID current_slot, int *current_slot_n_cipher,
+    int *local_cipher_nids);
+static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
+    CK_SLOT_ID current_slot, int *current_slot_n_digest,
+    int *local_digest_nids);
+static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR, int slot_id,
+    int *current_slot_n_cipher, int *local_cipher_nids,
+    PK11_CIPHER *cipher);
+static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
+    int *current_slot_n_digest, int *local_digest_nids,
+    PK11_DIGEST *digest);
+
+static int pk11_init_all_locks(void);
+static void pk11_free_all_locks(void);
+
+#ifdef	SOLARIS_HW_SLOT_SELECTION
+static int check_hw_mechanisms(void);
+static int nid_in_table(int nid, int *nid_table);
+static int hw_aes_instruction_set_present(void);
+#endif	/* SOLARIS_HW_SLOT_SELECTION */
+
+#define	TRY_OBJ_DESTROY(sp, obj_hdl, retval, uselock, alg_type)	\
+	{								\
+	if (uselock)							\
+		LOCK_OBJSTORE(alg_type);				\
+	if (pk11_active_delete(obj_hdl, alg_type) == 1)			\
+		{							\
+		retval = pk11_destroy_object(sp->session, obj_hdl,	\
+		    sp->persistent);					\
+		}							\
+	if (uselock)							\
+		UNLOCK_OBJSTORE(alg_type);				\
+	}
+
+static int cipher_nids[PK11_CIPHER_MAX];
+static int digest_nids[PK11_DIGEST_MAX];
+static int cipher_count		= 0;
+static int digest_count		= 0;
+static CK_BBOOL pk11_have_rsa	= CK_FALSE;
+static CK_BBOOL pk11_have_dsa	= CK_FALSE;
+static CK_BBOOL pk11_have_dh	= CK_FALSE;
+static CK_BBOOL pk11_have_random = CK_FALSE;
+
+/*
+ * Static list of ciphers.
+ * Note, that ciphers array is indexed by member PK11_CIPHER.id,
+ * thus ciphers[i].id == i
+ * Rows must be kept in sync with enum pk11_cipher_id.
+ */
+static PK11_CIPHER ciphers[] =
+	{
+	{ PK11_DES_CBC,		NID_des_cbc,		8,	 8,   8,
+		CKK_DES,	CKM_DES_CBC, },
+	{ PK11_DES3_CBC,	NID_des_ede3_cbc,	8,	24,  24,
+		CKK_DES3,	CKM_DES3_CBC, },
+	{ PK11_DES_ECB,		NID_des_ecb,		0,	 8,   8,
+		CKK_DES,	CKM_DES_ECB, },
+	{ PK11_DES3_ECB,	NID_des_ede3_ecb,	0,	24,  24,
+		CKK_DES3,	CKM_DES3_ECB, },
+	{ PK11_RC4,		NID_rc4,		0,	16, 256,
+		CKK_RC4,	CKM_RC4, },
+	{ PK11_AES_128_CBC,	NID_aes_128_cbc,	16,	16,  16,
+		CKK_AES,	CKM_AES_CBC, },
+	{ PK11_AES_192_CBC,	NID_aes_192_cbc,	16,	24,  24,
+		CKK_AES,	CKM_AES_CBC, },
+	{ PK11_AES_256_CBC,	NID_aes_256_cbc,	16,	32,  32,
+		CKK_AES,	CKM_AES_CBC, },
+	{ PK11_AES_128_ECB,	NID_aes_128_ecb,	0,	16,  16,
+		CKK_AES,	CKM_AES_ECB, },
+	{ PK11_AES_192_ECB,	NID_aes_192_ecb,	0,	24,  24,
+		CKK_AES,	CKM_AES_ECB, },
+	{ PK11_AES_256_ECB,	NID_aes_256_ecb,	0,	32,  32,
+		CKK_AES,	CKM_AES_ECB, },
+	{ PK11_BLOWFISH_CBC,	NID_bf_cbc,		8,	16,  16,
+		CKK_BLOWFISH,	CKM_BLOWFISH_CBC, },
+	{ PK11_AES_128_CTR,	NID_aes_128_ctr,	16,	16,  16,
+		CKK_AES,	CKM_AES_CTR, },
+	{ PK11_AES_192_CTR,	NID_aes_192_ctr,	16,	24,  24,
+		CKK_AES,	CKM_AES_CTR, },
+	{ PK11_AES_256_CTR,	NID_aes_256_ctr,	16,	32,  32,
+		CKK_AES,	CKM_AES_CTR, },
+	};
+
+/*
+ * Static list of digests.
+ * Note, that digests array is indexed by member PK11_DIGEST.id,
+ * thus digests[i].id == i
+ * Rows must be kept in sync with enum pk11_digest_id.
+ */
+static PK11_DIGEST digests[] =
+	{
+	{PK11_MD5,	NID_md5,	CKM_MD5, },
+	{PK11_SHA1,	NID_sha1,	CKM_SHA_1, },
+	{PK11_SHA224,	NID_sha224,	CKM_SHA224, },
+	{PK11_SHA256,	NID_sha256,	CKM_SHA256, },
+	{PK11_SHA384,	NID_sha384,	CKM_SHA384, },
+	{PK11_SHA512,	NID_sha512,	CKM_SHA512, },
+	{0,		NID_undef,	0xFFFF, },
+	};
+
+/*
+ * Structure to be used for the cipher_data/md_data in
+ * EVP_CIPHER_CTX/EVP_MD_CTX structures in order to use the same pk11
+ * session in multiple cipher_update calls
+ */
+typedef struct PK11_CIPHER_STATE_st
+	{
+	PK11_SESSION	*sp;
+	} PK11_CIPHER_STATE;
+
+
+/*
+ * libcrypto EVP stuff - this is how we get wired to EVP so the engine gets
+ * called when libcrypto requests a cipher NID.
+ *
+ * Note how the PK11_CIPHER_STATE is used here.
+ */
+
+/* DES CBC EVP */
+static const EVP_CIPHER pk11_des_cbc =
+	{
+	NID_des_cbc,
+	8, 8, 8,
+	EVP_CIPH_CBC_MODE,
+	pk11_cipher_init,
+	pk11_cipher_do_cipher,
+	pk11_cipher_cleanup,
+	sizeof (PK11_CIPHER_STATE),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL
+	};
+
+/* 3DES CBC EVP */
+static const EVP_CIPHER pk11_3des_cbc =
+	{
+	NID_des_ede3_cbc,
+	8, 24, 8,
+	EVP_CIPH_CBC_MODE,
+	pk11_cipher_init,
+	pk11_cipher_do_cipher,
+	pk11_cipher_cleanup,
+	sizeof (PK11_CIPHER_STATE),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL
+	};
+
+/*
+ * ECB modes don't use an Initial Vector so that's why set_asn1_parameters and
+ * get_asn1_parameters fields are set to NULL.
+ */
+static const EVP_CIPHER pk11_des_ecb =
+	{
+	NID_des_ecb,
+	8, 8, 8,
+	EVP_CIPH_ECB_MODE,
+	pk11_cipher_init,
+	pk11_cipher_do_cipher,
+	pk11_cipher_cleanup,
+	sizeof (PK11_CIPHER_STATE),
+	NULL,
+	NULL,
+	NULL
+	};
+
+static const EVP_CIPHER pk11_3des_ecb =
+	{
+	NID_des_ede3_ecb,
+	8, 24, 8,
+	EVP_CIPH_ECB_MODE,
+	pk11_cipher_init,
+	pk11_cipher_do_cipher,
+	pk11_cipher_cleanup,
+	sizeof (PK11_CIPHER_STATE),
+	NULL,
+	NULL,
+	NULL
+	};
+
+
+static const EVP_CIPHER pk11_aes_128_cbc =
+	{
+	NID_aes_128_cbc,
+	16, 16, 16,
+	EVP_CIPH_CBC_MODE,
+	pk11_cipher_init,
+	pk11_cipher_do_cipher,
+	pk11_cipher_cleanup,
+	sizeof (PK11_CIPHER_STATE),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL
+	};
+
+static const EVP_CIPHER pk11_aes_192_cbc =
+	{
+	NID_aes_192_cbc,
+	16, 24, 16,
+	EVP_CIPH_CBC_MODE,
+	pk11_cipher_init,
+	pk11_cipher_do_cipher,
+	pk11_cipher_cleanup,
+	sizeof (PK11_CIPHER_STATE),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL
+	};
+
+static const EVP_CIPHER pk11_aes_256_cbc =
+	{
+	NID_aes_256_cbc,
+	16, 32, 16,
+	EVP_CIPH_CBC_MODE,
+	pk11_cipher_init,
+	pk11_cipher_do_cipher,
+	pk11_cipher_cleanup,
+	sizeof (PK11_CIPHER_STATE),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL
+	};
+
+/*
+ * ECB modes don't use IV so that's why set_asn1_parameters and
+ * get_asn1_parameters are set to NULL.
+ */
+static const EVP_CIPHER pk11_aes_128_ecb =
+	{
+	NID_aes_128_ecb,
+	16, 16, 0,
+	EVP_CIPH_ECB_MODE,
+	pk11_cipher_init,
+	pk11_cipher_do_cipher,
+	pk11_cipher_cleanup,
+	sizeof (PK11_CIPHER_STATE),
+	NULL,
+	NULL,
+	NULL
+	};
+
+static const EVP_CIPHER pk11_aes_192_ecb =
+	{
+	NID_aes_192_ecb,
+	16, 24, 0,
+	EVP_CIPH_ECB_MODE,
+	pk11_cipher_init,
+	pk11_cipher_do_cipher,
+	pk11_cipher_cleanup,
+	sizeof (PK11_CIPHER_STATE),
+	NULL,
+	NULL,
+	NULL
+	};
+
+static const EVP_CIPHER pk11_aes_256_ecb =
+	{
+	NID_aes_256_ecb,
+	16, 32, 0,
+	EVP_CIPH_ECB_MODE,
+	pk11_cipher_init,
+	pk11_cipher_do_cipher,
+	pk11_cipher_cleanup,
+	sizeof (PK11_CIPHER_STATE),
+	NULL,
+	NULL,
+	NULL
+	};
+
+static EVP_CIPHER pk11_aes_128_ctr =
+	{
+	NID_aes_128_ctr,
+	16, 16, 16,
+	EVP_CIPH_CTR_MODE,
+	pk11_cipher_init,
+	pk11_cipher_do_cipher,
+	pk11_cipher_cleanup,
+	sizeof (PK11_CIPHER_STATE),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL
+	};
+
+static EVP_CIPHER pk11_aes_192_ctr =
+	{
+	NID_aes_192_ctr,
+	16, 24, 16,
+	EVP_CIPH_CTR_MODE,
+	pk11_cipher_init,
+	pk11_cipher_do_cipher,
+	pk11_cipher_cleanup,
+	sizeof (PK11_CIPHER_STATE),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL
+	};
+
+static EVP_CIPHER pk11_aes_256_ctr =
+	{
+	NID_aes_256_ctr,
+	16, 32, 16,
+	EVP_CIPH_CTR_MODE,
+	pk11_cipher_init,
+	pk11_cipher_do_cipher,
+	pk11_cipher_cleanup,
+	sizeof (PK11_CIPHER_STATE),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL
+	};
+
+static const EVP_CIPHER pk11_bf_cbc =
+	{
+	NID_bf_cbc,
+	8, 16, 8,
+	EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CBC_MODE,
+	pk11_cipher_init,
+	pk11_cipher_do_cipher,
+	pk11_cipher_cleanup,
+	sizeof (PK11_CIPHER_STATE),
+	EVP_CIPHER_set_asn1_iv,
+	EVP_CIPHER_get_asn1_iv,
+	NULL
+	};
+
+static const EVP_CIPHER pk11_rc4 =
+	{
+	NID_rc4,
+	1, 16, 0,
+	EVP_CIPH_VARIABLE_LENGTH,
+	pk11_cipher_init,
+	pk11_cipher_do_cipher,
+	pk11_cipher_cleanup,
+	sizeof (PK11_CIPHER_STATE),
+	NULL,
+	NULL,
+	NULL
+	};
+
+static const EVP_MD pk11_md5 =
+	{
+	NID_md5,
+	NID_md5WithRSAEncryption,
+	MD5_DIGEST_LENGTH,
+	0,
+	pk11_digest_init,
+	pk11_digest_update,
+	pk11_digest_final,
+	pk11_digest_copy,
+	pk11_digest_cleanup,
+	EVP_PKEY_RSA_method,
+	MD5_CBLOCK,
+	sizeof (PK11_CIPHER_STATE),
+	};
+
+static const EVP_MD pk11_sha1 =
+	{
+	NID_sha1,
+	NID_sha1WithRSAEncryption,
+	SHA_DIGEST_LENGTH,
+	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
+	pk11_digest_init,
+	pk11_digest_update,
+	pk11_digest_final,
+	pk11_digest_copy,
+	pk11_digest_cleanup,
+	EVP_PKEY_RSA_method,
+	SHA_CBLOCK,
+	sizeof (PK11_CIPHER_STATE),
+	};
+
+static const EVP_MD pk11_sha224 =
+	{
+	NID_sha224,
+	NID_sha224WithRSAEncryption,
+	SHA224_DIGEST_LENGTH,
+	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
+	pk11_digest_init,
+	pk11_digest_update,
+	pk11_digest_final,
+	pk11_digest_copy,
+	pk11_digest_cleanup,
+	EVP_PKEY_RSA_method,
+	/* SHA-224 uses the same cblock size as SHA-256 */
+	SHA256_CBLOCK,
+	sizeof (PK11_CIPHER_STATE),
+	};
+
+static const EVP_MD pk11_sha256 =
+	{
+	NID_sha256,
+	NID_sha256WithRSAEncryption,
+	SHA256_DIGEST_LENGTH,
+	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
+	pk11_digest_init,
+	pk11_digest_update,
+	pk11_digest_final,
+	pk11_digest_copy,
+	pk11_digest_cleanup,
+	EVP_PKEY_RSA_method,
+	SHA256_CBLOCK,
+	sizeof (PK11_CIPHER_STATE),
+	};
+
+static const EVP_MD pk11_sha384 =
+	{
+	NID_sha384,
+	NID_sha384WithRSAEncryption,
+	SHA384_DIGEST_LENGTH,
+	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
+	pk11_digest_init,
+	pk11_digest_update,
+	pk11_digest_final,
+	pk11_digest_copy,
+	pk11_digest_cleanup,
+	EVP_PKEY_RSA_method,
+	/* SHA-384 uses the same cblock size as SHA-512 */
+	SHA512_CBLOCK,
+	sizeof (PK11_CIPHER_STATE),
+	};
+
+static const EVP_MD pk11_sha512 =
+	{
+	NID_sha512,
+	NID_sha512WithRSAEncryption,
+	SHA512_DIGEST_LENGTH,
+	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
+	pk11_digest_init,
+	pk11_digest_update,
+	pk11_digest_final,
+	pk11_digest_copy,
+	pk11_digest_cleanup,
+	EVP_PKEY_RSA_method,
+	SHA512_CBLOCK,
+	sizeof (PK11_CIPHER_STATE),
+	};
+
+/*
+ * Initialization function. Sets up various PKCS#11 library components.
+ * The definitions for control commands specific to this engine
+ */
+#define	PK11_CMD_SO_PATH		ENGINE_CMD_BASE
+static const ENGINE_CMD_DEFN pk11_cmd_defns[] =
+	{
+		{
+		PK11_CMD_SO_PATH,
+		"SO_PATH",
+		"Specifies the path to the 'pkcs#11' shared library",
+		ENGINE_CMD_FLAG_STRING
+		},
+		{0, NULL, NULL, 0}
+	};
+
+
+static RAND_METHOD pk11_random =
+	{
+	pk11_rand_seed,
+	pk11_rand_bytes,
+	pk11_rand_cleanup,
+	pk11_rand_add,
+	pk11_rand_bytes,
+	pk11_rand_status
+	};
+
+
+/* Constants used when creating the ENGINE */
+static const char *engine_pk11_id = "pkcs11";
+static const char *engine_pk11_name = "PKCS #11 engine support";
+
+CK_FUNCTION_LIST_PTR pFuncList = NULL;
+static const char PK11_GET_FUNCTION_LIST[] = "C_GetFunctionList";
+
+/*
+ * This is a static string constant for the DSO file name and the function
+ * symbol names to bind to. We set it in the Configure script based on whether
+ * this is 32 or 64 bit build.
+ */
+static const char def_PK11_LIBNAME[] = PK11_LIB_LOCATION;
+
+/* Needed in e_pk11_pub.c as well so that's why it is not static. */
+CK_SLOT_ID pubkey_SLOTID = 0;
+static CK_SLOT_ID rand_SLOTID = 0;
+static CK_SLOT_ID SLOTID = 0;
+static CK_BBOOL pk11_library_initialized = CK_FALSE;
+static CK_BBOOL pk11_atfork_initialized = CK_FALSE;
+static int pk11_pid = 0;
+static ENGINE* pk11_engine = NULL;
+
+static DSO *pk11_dso = NULL;
+
+/* allocate and initialize all locks used by the engine itself */
+static int pk11_init_all_locks(void)
+	{
+	int type;
+
+#ifndef OPENSSL_NO_RSA
+	find_lock[OP_RSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
+	if (find_lock[OP_RSA] == NULL)
+		goto malloc_err;
+	(void) pthread_mutex_init(find_lock[OP_RSA], NULL);
+#endif /* OPENSSL_NO_RSA */
+
+	if ((uri_lock = OPENSSL_malloc(sizeof (pthread_mutex_t))) == NULL)
+		goto malloc_err;
+	(void) pthread_mutex_init(uri_lock, NULL);
+
+#ifndef OPENSSL_NO_DSA
+	find_lock[OP_DSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
+	if (find_lock[OP_DSA] == NULL)
+		goto malloc_err;
+	(void) pthread_mutex_init(find_lock[OP_DSA], NULL);
+#endif /* OPENSSL_NO_DSA */
+
+#ifndef OPENSSL_NO_DH
+	find_lock[OP_DH] = OPENSSL_malloc(sizeof (pthread_mutex_t));
+	if (find_lock[OP_DH] == NULL)
+		goto malloc_err;
+	(void) pthread_mutex_init(find_lock[OP_DH], NULL);
+#endif /* OPENSSL_NO_DH */
+
+	for (type = 0; type < OP_MAX; type++)
+		{
+		session_cache[type].lock =
+		    OPENSSL_malloc(sizeof (pthread_mutex_t));
+		if (session_cache[type].lock == NULL)
+			goto malloc_err;
+		(void) pthread_mutex_init(session_cache[type].lock, NULL);
+		}
+
+	return (1);
+
+malloc_err:
+	pk11_free_all_locks();
+	PK11err(PK11_F_INIT_ALL_LOCKS, PK11_R_MALLOC_FAILURE);
+	return (0);
+	}
+
+static void pk11_free_all_locks(void)
+	{
+	int type;
+
+#ifndef OPENSSL_NO_RSA
+	if (find_lock[OP_RSA] != NULL)
+		{
+		(void) pthread_mutex_destroy(find_lock[OP_RSA]);
+		OPENSSL_free(find_lock[OP_RSA]);
+		find_lock[OP_RSA] = NULL;
+		}
+#endif /* OPENSSL_NO_RSA */
+#ifndef OPENSSL_NO_DSA
+	if (find_lock[OP_DSA] != NULL)
+		{
+		(void) pthread_mutex_destroy(find_lock[OP_DSA]);
+		OPENSSL_free(find_lock[OP_DSA]);
+		find_lock[OP_DSA] = NULL;
+		}
+#endif /* OPENSSL_NO_DSA */
+#ifndef OPENSSL_NO_DH
+	if (find_lock[OP_DH] != NULL)
+		{
+		(void) pthread_mutex_destroy(find_lock[OP_DH]);
+		OPENSSL_free(find_lock[OP_DH]);
+		find_lock[OP_DH] = NULL;
+		}
+#endif /* OPENSSL_NO_DH */
+
+	for (type = 0; type < OP_MAX; type++)
+		{
+		if (session_cache[type].lock != NULL)
+			{
+			(void) pthread_mutex_destroy(session_cache[type].lock);
+			OPENSSL_free(session_cache[type].lock);
+			session_cache[type].lock = NULL;
+			}
+		}
+	/* Free uri_lock */
+	(void) pthread_mutex_destroy(uri_lock);
+	OPENSSL_free(uri_lock);
+	uri_lock = NULL;
+	}
+
+/*
+ * This internal function is used by ENGINE_pk11() and "dynamic" ENGINE support.
+ */
+static int bind_pk11(ENGINE *e)
+	{
+#ifndef OPENSSL_NO_RSA
+	const RSA_METHOD *rsa = NULL;
+	RSA_METHOD *pk11_rsa = PK11_RSA();
+#endif	/* OPENSSL_NO_RSA */
+	if (!pk11_library_initialized)
+		if (!pk11_library_init(e))
+			return (0);
+
+	if (!ENGINE_set_id(e, engine_pk11_id) ||
+	    !ENGINE_set_name(e, engine_pk11_name) ||
+	    !ENGINE_set_ciphers(e, pk11_engine_ciphers) ||
+	    !ENGINE_set_digests(e, pk11_engine_digests))
+		return (0);
+
+	if (!ENGINE_set_pkey_meths(e, pk11_engine_pkey_methods))
+		return (0);
+
+#ifndef OPENSSL_NO_RSA
+	if (pk11_have_rsa == CK_TRUE)
+		{
+		if (!ENGINE_set_RSA(e, PK11_RSA()) ||
+		    !ENGINE_set_load_privkey_function(e, pk11_load_privkey) ||
+		    !ENGINE_set_load_pubkey_function(e, pk11_load_pubkey))
+			return (0);
+		DEBUG_SLOT_SEL("%s: registered RSA\n", PK11_DBG);
+		}
+#endif	/* OPENSSL_NO_RSA */
+#ifndef OPENSSL_NO_DSA
+	if (pk11_have_dsa == CK_TRUE)
+		{
+		if (!ENGINE_set_DSA(e, PK11_DSA()))
+			return (0);
+		DEBUG_SLOT_SEL("%s: registered DSA\n", PK11_DBG);
+		}
+#endif	/* OPENSSL_NO_DSA */
+#ifndef OPENSSL_NO_DH
+	if (pk11_have_dh == CK_TRUE)
+		{
+		if (!ENGINE_set_DH(e, PK11_DH()))
+			return (0);
+		DEBUG_SLOT_SEL("%s: registered DH\n", PK11_DBG);
+		}
+#endif	/* OPENSSL_NO_DH */
+	if (pk11_have_random)
+		{
+		if (!ENGINE_set_RAND(e, &pk11_random))
+			return (0);
+		DEBUG_SLOT_SEL("%s: registered random\n", PK11_DBG);
+		}
+	if (!ENGINE_set_init_function(e, pk11_init) ||
+	    !ENGINE_set_destroy_function(e, pk11_destroy) ||
+	    !ENGINE_set_finish_function(e, pk11_finish) ||
+	    !ENGINE_set_ctrl_function(e, pk11_ctrl) ||
+	    !ENGINE_set_cmd_defns(e, pk11_cmd_defns))
+		return (0);
+
+/*
+ * Apache calls OpenSSL function RSA_blinding_on() once during startup
+ * which in turn calls bn_mod_exp. Since we do not implement bn_mod_exp
+ * here, we wire it back to the OpenSSL software implementation.
+ * Since it is used only once, performance is not a concern.
+ */
+#ifndef OPENSSL_NO_RSA
+	rsa = RSA_PKCS1_SSLeay();
+	pk11_rsa->rsa_mod_exp = rsa->rsa_mod_exp;
+	pk11_rsa->bn_mod_exp = rsa->bn_mod_exp;
+#endif	/* OPENSSL_NO_RSA */
+
+	/* Ensure the pk11 error handling is set up */
+	ERR_load_pk11_strings();
+
+	return (1);
+	}
+
+static int bind_helper(ENGINE *e, const char *id)
+	{
+	if (id && (strcmp(id, engine_pk11_id) != 0))
+		return (0);
+
+	if (!bind_pk11(e))
+		return (0);
+
+	return (1);
+	}
+
+IMPLEMENT_DYNAMIC_CHECK_FN()
+IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
+
+/*
+ * These are the static string constants for the DSO file name and
+ * the function symbol names to bind to.
+ */
+static const char *PK11_LIBNAME = NULL;
+
+static const char *get_PK11_LIBNAME(void)
+	{
+	if (PK11_LIBNAME)
+		return (PK11_LIBNAME);
+
+	return (def_PK11_LIBNAME);
+	}
+
+static void free_PK11_LIBNAME(void)
+	{
+	if (PK11_LIBNAME)
+		OPENSSL_free((void*)PK11_LIBNAME);
+
+	PK11_LIBNAME = NULL;
+	}
+
+static long set_PK11_LIBNAME(const char *name)
+	{
+	free_PK11_LIBNAME();
+
+	return ((PK11_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
+	}
+
+/* acquire all engine specific mutexes before fork */
+static void pk11_fork_prepare(void)
+	{
+	int i;
+
+	if (!pk11_library_initialized)
+		return;
+
+	LOCK_OBJSTORE(OP_RSA);
+	LOCK_OBJSTORE(OP_DSA);
+	LOCK_OBJSTORE(OP_DH);
+	(void) pthread_mutex_lock(uri_lock);
+	for (i = 0; i < OP_MAX; i++)
+		{
+		(void) pthread_mutex_lock(session_cache[i].lock);
+		}
+	}
+
+/* release all engine specific mutexes */
+static void pk11_fork_parent(void)
+	{
+	int i;
+
+	if (!pk11_library_initialized)
+		return;
+
+	for (i = OP_MAX - 1; i >= 0; i--)
+		{
+		(void) pthread_mutex_unlock(session_cache[i].lock);
+		}
+	UNLOCK_OBJSTORE(OP_DH);
+	UNLOCK_OBJSTORE(OP_DSA);
+	UNLOCK_OBJSTORE(OP_RSA);
+	(void) pthread_mutex_unlock(uri_lock);
+	}
+
+/*
+ * same situation as in parent - we need to unlock all locks to make them
+ * accessible to all threads.
+ */
+static void pk11_fork_child(void)
+	{
+	int i;
+
+	if (!pk11_library_initialized)
+		return;
+
+	/* invalidate the global session */
+	global_session = CK_INVALID_HANDLE;
+
+	for (i = OP_MAX - 1; i >= 0; i--)
+		{
+		(void) pthread_mutex_unlock(session_cache[i].lock);
+		}
+	UNLOCK_OBJSTORE(OP_DH);
+	UNLOCK_OBJSTORE(OP_DSA);
+	UNLOCK_OBJSTORE(OP_RSA);
+	(void) pthread_mutex_unlock(uri_lock);
+	}
+
+/* Initialization function for the pk11 engine */
+static int pk11_init(ENGINE *e)
+{
+	return (pk11_library_init(e));
+}
+
+/*
+ * Helper function that unsets reference to current engine (pk11_engine = NULL).
+ *
+ * Use of local variable only seems clumsy, it needs to be this way!
+ * This is to prevent double free in the unlucky scenario:
+ *     ENGINE_free calls pk11_destroy calls pk11_finish calls ENGINE_free
+ * Setting pk11_engine to NULL prior to ENGINE_free() avoids this.
+ */
+static void pk11_engine_free()
+	{
+	ENGINE* old_engine = pk11_engine;
+
+	if (old_engine) {
+		pk11_engine = NULL;
+	}
+	}
+
+/*
+ * Initialization function. Sets up various PKCS#11 library components.
+ * It selects a slot based on predefined critiera. In the process, it also
+ * count how many ciphers and digests to support. Since the cipher and
+ * digest information is needed when setting default engine, this function
+ * needs to be called before calling ENGINE_set_default.
+ */
+/* ARGSUSED */
+static int pk11_library_init(ENGINE *e)
+	{
+	CK_C_GetFunctionList p;
+	CK_RV rv = CKR_OK;
+	CK_INFO info;
+	CK_ULONG ul_state_len;
+	int any_slot_found;
+	int i;
+
+	if (e != pk11_engine)
+		{
+		pk11_engine_free();
+		pk11_engine = e;
+		}
+
+	/*
+	 * pk11_library_initialized is set to 0 in pk11_finish() which is called
+	 * from ENGINE_finish(). However, if there is still at least one
+	 * existing functional reference to the engine (see engine(3) for more
+	 * information), pk11_finish() is skipped. For example, this can happen
+	 * if an application forgets to clear one cipher context. In case of a
+	 * fork() when the application is finishing the engine so that it can be
+	 * reinitialized in the child, forgotten functional reference causes
+	 * pk11_library_initialized to stay 1. In that case we need the PID
+	 * check so that we properly initialize the engine again.
+	 */
+	if (pk11_library_initialized)
+		{
+		if (pk11_pid == getpid())
+			{
+			return (1);
+			}
+		else
+			{
+			global_session = CK_INVALID_HANDLE;
+			/*
+			 * free the locks first to prevent memory leak in case
+			 * the application calls fork() without finishing the
+			 * engine first.
+			 */
+			pk11_free_all_locks();
+			}
+		}
+
+	/*
+	 * If initialization of the locks fails pk11_init_all_locks()
+	 * will do the cleanup.
+	 */
+	if (!pk11_init_all_locks())
+		goto err;
+	for (i = 0; i < OP_MAX; i++)
+		session_cache[i].head = NULL;
+	/*
+	 * Initialize active lists. We only use active lists
+	 * for asymmetric ciphers.
+	 */
+	for (i = 0; i < OP_MAX; i++)
+		active_list[i] = NULL;
+
+	/* Attempt to load PKCS#11 library. */
+	if (!pk11_dso)
+		{
+		pk11_dso = DSO_load(NULL, get_PK11_LIBNAME(), NULL, 0);
+		if (pk11_dso == NULL)
+			{
+			PK11err(PK11_F_LOAD, PK11_R_DSO_FAILURE);
+			goto err;
+			}
+		}
+
+#ifdef	SOLARIS_HW_SLOT_SELECTION
+	if (check_hw_mechanisms() == 0)
+		goto err;
+#endif	/* SOLARIS_HW_SLOT_SELECTION */
+
+	/* get the C_GetFunctionList function from the loaded library */
+	p = (CK_C_GetFunctionList)DSO_bind_func(pk11_dso,
+		PK11_GET_FUNCTION_LIST);
+	if (!p)
+		{
+		PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
+		goto err;
+		}
+
+	/* get the full function list from the loaded library */
+	rv = p(&pFuncList);
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE, rv);
+		goto err;
+		}
+
+	rv = pFuncList->C_Initialize(NULL_PTR);
+	if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
+		{
+		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_INITIALIZE, rv);
+		goto err;
+		}
+
+	rv = pFuncList->C_GetInfo(&info);
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_GETINFO, rv);
+		goto err;
+		}
+
+	if (pk11_choose_slots(&any_slot_found) == 0)
+		goto err;
+
+	/*
+	 * The library we use, set in def_PK11_LIBNAME, may not offer any
+	 * slot(s). In that case, we must not proceed but we must not return an
+	 * error. The reason is that applications that try to set up the PKCS#11
+	 * engine don't exit on error during the engine initialization just
+	 * because no slot was present.
+	 */
+	if (any_slot_found == 0)
+		return (1);
+
+	if (global_session == CK_INVALID_HANDLE)
+		{
+		/* Open the global_session for the new process */
+		rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
+			NULL_PTR, NULL_PTR, &global_session);
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_LIBRARY_INIT,
+			    PK11_R_OPENSESSION, rv);
+			goto err;
+			}
+		}
+
+	/*
+	 * Disable digest if C_GetOperationState is not supported since
+	 * this function is required by OpenSSL digest copy function
+	 */
+	if (pFuncList->C_GetOperationState(global_session, NULL, &ul_state_len)
+			== CKR_FUNCTION_NOT_SUPPORTED) {
+		DEBUG_SLOT_SEL("%s: C_GetOperationState() not supported, "
+		    "setting digest_count to 0\n", PK11_DBG);
+		digest_count = 0;
+	}
+
+	pk11_library_initialized = CK_TRUE;
+	pk11_pid = getpid();
+
+	if (!pk11_atfork_initialized)
+		{
+		if (pthread_atfork(pk11_fork_prepare, pk11_fork_parent,
+		    pk11_fork_child) != 0)
+			{
+			PK11err(PK11_F_LIBRARY_INIT, PK11_R_ATFORK_FAILED);
+			goto err;
+			}
+		pk11_atfork_initialized = CK_TRUE;
+		}
+
+	return (1);
+
+err:
+	return (0);
+	}
+
+/* Destructor (complements the "ENGINE_pk11()" constructor) */
+/* ARGSUSED */
+static int pk11_destroy(ENGINE *e)
+	{
+	int rtn = 1;
+
+	free_PK11_LIBNAME();
+	ERR_unload_pk11_strings();
+	if (pk11_library_initialized == CK_TRUE)
+		rtn = pk11_finish(e);
+
+	return (rtn);
+	}
+
+/*
+ * Termination function to clean up the session, the token, and the pk11
+ * library.
+ */
+/* ARGSUSED */
+static int pk11_finish(ENGINE *e)
+	{
+	int i;
+
+	/*
+	 * Make sure, right engine instance is being destroyed.
+	 * Engine e may be the wrong instance if
+	 * 	1) either someone calls ENGINE_load_pk11 twice
+	 * 	2) or last ref. to an already finished engine is being destroyed
+	 */
+	if (e != pk11_engine)
+		goto err;
+
+	if (pk11_dso == NULL)
+		{
+		PK11err(PK11_F_FINISH, PK11_R_NOT_LOADED);
+		goto err;
+		}
+
+	OPENSSL_assert(pFuncList != NULL);
+
+	if (pk11_free_all_sessions() == 0)
+		goto err;
+
+	/* free all active lists */
+	for (i = 0; i < OP_MAX; i++)
+		pk11_free_active_list(i);
+
+	/* Global session is not present when there are no slots. */
+	if (global_session != CK_INVALID_HANDLE)
+		{
+		pFuncList->C_CloseSession(global_session);
+		global_session = CK_INVALID_HANDLE;
+		}
+
+	/*
+	 * Since we are part of a library (libcrypto.so), calling this function
+	 * may have side-effects.
+	 */
+#if 0
+	pFuncList->C_Finalize(NULL);
+#endif
+	if (!DSO_free(pk11_dso))
+		{
+		PK11err(PK11_F_FINISH, PK11_R_DSO_FAILURE);
+		goto err;
+		}
+	pk11_dso = NULL;
+	pFuncList = NULL;
+	pk11_library_initialized = CK_FALSE;
+	pk11_pid = 0;
+	pk11_engine_free();
+	/*
+	 * There is no way how to unregister atfork handlers (other than
+	 * unloading the library) so we just free the locks. For this reason
+	 * the atfork handlers check if the engine is initialized and bail out
+	 * immediately if not. This is necessary in case a process finishes
+	 * the engine before calling fork().
+	 */
+	pk11_free_all_locks();
+
+	return (1);
+
+err:
+	return (0);
+	}
+
+/* Standard engine interface function to set the dynamic library path */
+/* ARGSUSED */
+static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
+	{
+	int initialized = ((pk11_dso == NULL) ? 0 : 1);
+
+	switch (cmd)
+		{
+	case PK11_CMD_SO_PATH:
+		if (p == NULL)
+			{
+			PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
+			return (0);
+			}
+
+		if (initialized)
+			{
+			PK11err(PK11_F_CTRL, PK11_R_ALREADY_LOADED);
+			return (0);
+			}
+
+		return (set_PK11_LIBNAME((const char *)p));
+	default:
+		break;
+		}
+
+	PK11err(PK11_F_CTRL, PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED);
+
+	return (0);
+	}
+
+
+/* Required function by the engine random interface. It does nothing here */
+static void pk11_rand_cleanup(void)
+	{
+	return;
+	}
+
+/* ARGSUSED */
+static void pk11_rand_add(const void *buf, int num, double add)
+	{
+	PK11_SESSION *sp;
+
+	if ((sp = pk11_get_session(OP_RAND)) == NULL)
+		return;
+
+	/*
+	 * Ignore any errors (e.g. CKR_RANDOM_SEED_NOT_SUPPORTED) since
+	 * the calling functions do not care anyway
+	 */
+	pFuncList->C_SeedRandom(sp->session, (unsigned char *) buf, num);
+	pk11_return_session(sp, OP_RAND);
+
+	return;
+	}
+
+static void pk11_rand_seed(const void *buf, int num)
+	{
+	pk11_rand_add(buf, num, 0);
+	}
+
+static int pk11_rand_bytes(unsigned char *buf, int num)
+	{
+	CK_RV rv;
+	PK11_SESSION *sp;
+
+	if ((sp = pk11_get_session(OP_RAND)) == NULL)
+		return (0);
+
+	rv = pFuncList->C_GenerateRandom(sp->session, buf, num);
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_RAND_BYTES, PK11_R_GENERATERANDOM, rv);
+		pk11_return_session(sp, OP_RAND);
+		return (0);
+		}
+
+	pk11_return_session(sp, OP_RAND);
+	return (1);
+	}
+
+/* Required function by the engine random interface. It does nothing here */
+static int pk11_rand_status(void)
+	{
+	return (1);
+	}
+
+/* Free all BIGNUM structures from PK11_SESSION. */
+static void pk11_free_nums(PK11_SESSION *sp, PK11_OPTYPE optype)
+	{
+	switch (optype)
+		{
+#ifndef	OPENSSL_NO_RSA
+		case OP_RSA:
+			if (sp->opdata_rsa_n_num != NULL)
+				{
+				BN_free(sp->opdata_rsa_n_num);
+				sp->opdata_rsa_n_num = NULL;
+				}
+			if (sp->opdata_rsa_e_num != NULL)
+				{
+				BN_free(sp->opdata_rsa_e_num);
+				sp->opdata_rsa_e_num = NULL;
+				}
+			if (sp->opdata_rsa_d_num != NULL)
+				{
+				BN_free(sp->opdata_rsa_d_num);
+				sp->opdata_rsa_d_num = NULL;
+				}
+			break;
+#endif
+#ifndef	OPENSSL_NO_DSA
+		case OP_DSA:
+			if (sp->opdata_dsa_pub_num != NULL)
+				{
+				BN_free(sp->opdata_dsa_pub_num);
+				sp->opdata_dsa_pub_num = NULL;
+				}
+			if (sp->opdata_dsa_priv_num != NULL)
+				{
+				BN_free(sp->opdata_dsa_priv_num);
+				sp->opdata_dsa_priv_num = NULL;
+				}
+			break;
+#endif
+#ifndef	OPENSSL_NO_DH
+		case OP_DH:
+			if (sp->opdata_dh_priv_num != NULL)
+				{
+				BN_free(sp->opdata_dh_priv_num);
+				sp->opdata_dh_priv_num = NULL;
+				}
+			break;
+#endif
+		default:
+			break;
+		}
+	}
+
+/*
+ * Get new PK11_SESSION structure ready for use. Every process must have
+ * its own freelist of PK11_SESSION structures so handle fork() here
+ * by destroying the old and creating new freelist.
+ * The returned PK11_SESSION structure is disconnected from the freelist.
+ */
+PK11_SESSION *
+pk11_get_session(PK11_OPTYPE optype)
+	{
+	PK11_SESSION *sp = NULL, *sp1, *freelist;
+	pthread_mutex_t *freelist_lock;
+	static pid_t pid = 0;
+	pid_t new_pid;
+	CK_RV rv;
+
+	switch (optype)
+		{
+		case OP_RSA:
+		case OP_DSA:
+		case OP_DH:
+		case OP_RAND:
+		case OP_DIGEST:
+		case OP_CIPHER:
+			freelist_lock = session_cache[optype].lock;
+			break;
+		default:
+			PK11err(PK11_F_GET_SESSION,
+				PK11_R_INVALID_OPERATION_TYPE);
+			return (NULL);
+		}
+	(void) pthread_mutex_lock(freelist_lock);
+
+	/*
+	 * Will use it to find out if we forked. We cannot use the PID field in
+	 * the session structure because we could get a newly allocated session
+	 * here, with no PID information.
+	 */
+	if (pid == 0)
+		pid = getpid();
+
+	freelist = session_cache[optype].head;
+	sp = freelist;
+
+	/*
+	 * If the free list is empty, allocate new uninitialized (filled
+	 * with zeroes) PK11_SESSION structure otherwise return first
+	 * structure from the freelist.
+	 */
+	if (sp == NULL)
+		{
+		if ((sp = OPENSSL_malloc(sizeof (PK11_SESSION))) == NULL)
+			{
+			PK11err(PK11_F_GET_SESSION,
+				PK11_R_MALLOC_FAILURE);
+			goto err;
+			}
+		(void) memset(sp, 0, sizeof (PK11_SESSION));
+
+		/*
+		 * It is a new session so it will look like a cache miss to the
+		 * code below. So, we must not try to to destroy its members so
+		 * mark them as unused.
+		 */
+		sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
+		sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
+		}
+	else
+		freelist = sp->next;
+
+	/*
+	 * Check whether we have forked. In that case, we must get rid of all
+	 * inherited sessions and start allocating new ones.
+	 */
+	if (pid != (new_pid = getpid()))
+		{
+		pid = new_pid;
+
+		/*
+		 * We are a new process and thus need to free any inherited
+		 * PK11_SESSION objects aside from the first session (sp) which
+		 * is the only PK11_SESSION structure we will reuse (for the
+		 * head of the list).
+		 */
+		while ((sp1 = freelist) != NULL)
+			{
+			freelist = sp1->next;
+			/*
+			 * NOTE: we do not want to call pk11_free_all_sessions()
+			 * here because it would close underlying PKCS#11
+			 * sessions and destroy all objects.
+			 */
+			pk11_free_nums(sp1, optype);
+			OPENSSL_free(sp1);
+			}
+
+		/* we have to free the active list as well. */
+		pk11_free_active_list(optype);
+
+		/* Initialize the process */
+		rv = pFuncList->C_Initialize(NULL_PTR);
+		if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
+			{
+			PK11err_add_data(PK11_F_GET_SESSION, PK11_R_INITIALIZE,
+			    rv);
+			OPENSSL_free(sp);
+			sp = NULL;
+			goto err;
+			}
+
+		/*
+		 * Choose slot here since the slot table is different on this
+		 * process. If we are here then we must have found at least one
+		 * usable slot before so we don't need to check any_slot_found.
+		 * See pk11_library_init()'s usage of this function for more
+		 * information.
+		 */
+#ifdef	SOLARIS_HW_SLOT_SELECTION
+		if (check_hw_mechanisms() == 0)
+			goto err;
+#endif	/* SOLARIS_HW_SLOT_SELECTION */
+		if (pk11_choose_slots(NULL) == 0)
+			goto err;
+
+		/* Open the global_session for the new process */
+		rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
+			NULL_PTR, NULL_PTR, &global_session);
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_GET_SESSION, PK11_R_OPENSESSION,
+			    rv);
+			OPENSSL_free(sp);
+			sp = NULL;
+			goto err;
+			}
+
+		/*
+		 * It is an inherited session from our parent so it needs
+		 * re-initialization.
+		 */
+		if (pk11_setup_session(sp, optype) == 0)
+			{
+			OPENSSL_free(sp);
+			sp = NULL;
+			goto err;
+			}
+		if (pk11_token_relogin(sp->session) == 0)
+			{
+			/*
+			 * We will keep the session in the cache list and let
+			 * the caller cope with the situation.
+			 */
+			freelist = sp;
+			sp = NULL;
+			goto err;
+			}
+		}
+
+	if (sp->pid == 0)
+		{
+		/* It is a new session and needs initialization. */
+		if (pk11_setup_session(sp, optype) == 0)
+			{
+			OPENSSL_free(sp);
+			sp = NULL;
+			}
+		}
+
+	/* set new head for the list of PK11_SESSION objects */
+	session_cache[optype].head = freelist;
+
+err:
+	if (sp != NULL)
+		sp->next = NULL;
+
+	(void) pthread_mutex_unlock(freelist_lock);
+
+	return (sp);
+	}
+
+
+void
+pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype)
+	{
+	pthread_mutex_t *freelist_lock;
+	PK11_SESSION *freelist;
+
+	/*
+	 * If this is a session from the parent it will be taken care of and
+	 * freed in pk11_get_session() as part of the post-fork clean up the
+	 * next time we will ask for a new session.
+	 */
+	if (sp == NULL || sp->pid != getpid())
+		return;
+
+	switch (optype)
+		{
+		case OP_RSA:
+		case OP_DSA:
+		case OP_DH:
+		case OP_RAND:
+		case OP_DIGEST:
+		case OP_CIPHER:
+			freelist_lock = session_cache[optype].lock;
+			break;
+		default:
+			PK11err(PK11_F_RETURN_SESSION,
+				PK11_R_INVALID_OPERATION_TYPE);
+			return;
+		}
+
+	(void) pthread_mutex_lock(freelist_lock);
+	freelist = session_cache[optype].head;
+	sp->next = freelist;
+	session_cache[optype].head = sp;
+	(void) pthread_mutex_unlock(freelist_lock);
+	}
+
+
+/* Destroy all objects. This function is called when the engine is finished */
+static int pk11_free_all_sessions()
+	{
+	int ret = 1;
+	int type;
+
+#ifndef OPENSSL_NO_RSA
+	(void) pk11_destroy_rsa_key_objects(NULL);
+#endif	/* OPENSSL_NO_RSA */
+#ifndef OPENSSL_NO_DSA
+	(void) pk11_destroy_dsa_key_objects(NULL);
+#endif	/* OPENSSL_NO_DSA */
+#ifndef OPENSSL_NO_DH
+	(void) pk11_destroy_dh_key_objects(NULL);
+#endif	/* OPENSSL_NO_DH */
+	(void) pk11_destroy_cipher_key_objects(NULL);
+
+	/*
+	 * We try to release as much as we can but any error means that we will
+	 * return 0 on exit.
+	 */
+	for (type = 0; type < OP_MAX; type++)
+		{
+		if (pk11_free_session_list(type) == 0)
+			ret = 0;
+		}
+
+	return (ret);
+	}
+
+/*
+ * Destroy session structures from the linked list specified. Free as many
+ * sessions as possible but any failure in C_CloseSession() means that we
+ * return an error on return.
+ */
+static int pk11_free_session_list(PK11_OPTYPE optype)
+	{
+	CK_RV rv;
+	PK11_SESSION *sp = NULL;
+	PK11_SESSION *freelist = NULL;
+	pid_t mypid = getpid();
+	pthread_mutex_t *freelist_lock;
+	int ret = 1;
+
+	switch (optype)
+		{
+		case OP_RSA:
+		case OP_DSA:
+		case OP_DH:
+		case OP_RAND:
+		case OP_DIGEST:
+		case OP_CIPHER:
+			freelist_lock = session_cache[optype].lock;
+			break;
+		default:
+			PK11err(PK11_F_FREE_ALL_SESSIONS,
+				PK11_R_INVALID_OPERATION_TYPE);
+			return (0);
+		}
+
+	(void) pthread_mutex_lock(freelist_lock);
+	freelist = session_cache[optype].head;
+	while ((sp = freelist) != NULL)
+		{
+		if (sp->session != CK_INVALID_HANDLE && sp->pid == mypid)
+			{
+			rv = pFuncList->C_CloseSession(sp->session);
+			if (rv != CKR_OK)
+				{
+				PK11err_add_data(PK11_F_FREE_ALL_SESSIONS,
+					PK11_R_CLOSESESSION, rv);
+				ret = 0;
+				}
+			}
+		freelist = sp->next;
+		pk11_free_nums(sp, optype);
+		OPENSSL_free(sp);
+		}
+
+	(void) pthread_mutex_unlock(freelist_lock);
+	return (ret);
+	}
+
+
+static int
+pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype)
+	{
+	CK_RV rv;
+	CK_SLOT_ID myslot;
+
+	switch (optype)
+		{
+		case OP_RSA:
+		case OP_DSA:
+		case OP_DH:
+			myslot = pubkey_SLOTID;
+			break;
+		case OP_RAND:
+			myslot = rand_SLOTID;
+			break;
+		case OP_DIGEST:
+		case OP_CIPHER:
+			myslot = SLOTID;
+			break;
+		default:
+			PK11err(PK11_F_SETUP_SESSION,
+			    PK11_R_INVALID_OPERATION_TYPE);
+			return (0);
+		}
+
+	sp->session = CK_INVALID_HANDLE;
+	DEBUG_SLOT_SEL("%s: myslot=%d optype=%d\n", PK11_DBG, myslot, optype);
+	rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
+		NULL_PTR, NULL_PTR, &sp->session);
+	if (rv == CKR_CRYPTOKI_NOT_INITIALIZED)
+		{
+		/*
+		 * We are probably a child process so force the
+		 * reinitialize of the session
+		 */
+		pk11_library_initialized = CK_FALSE;
+		if (!pk11_library_init(NULL))
+			return (0);
+		rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
+			NULL_PTR, NULL_PTR, &sp->session);
+		}
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION, rv);
+		return (0);
+		}
+
+	sp->pid = getpid();
+
+	switch (optype)
+		{
+#ifndef OPENSSL_NO_RSA
+		case OP_RSA:
+			sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
+			sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
+			sp->opdata_rsa_pub = NULL;
+			sp->opdata_rsa_n_num = NULL;
+			sp->opdata_rsa_e_num = NULL;
+			sp->opdata_rsa_priv = NULL;
+			sp->opdata_rsa_d_num = NULL;
+			break;
+#endif	/* OPENSSL_NO_RSA */
+#ifndef OPENSSL_NO_DSA
+		case OP_DSA:
+			sp->opdata_dsa_pub_key = CK_INVALID_HANDLE;
+			sp->opdata_dsa_priv_key = CK_INVALID_HANDLE;
+			sp->opdata_dsa_pub = NULL;
+			sp->opdata_dsa_pub_num = NULL;
+			sp->opdata_dsa_priv = NULL;
+			sp->opdata_dsa_priv_num = NULL;
+			break;
+#endif	/* OPENSSL_NO_DSA */
+#ifndef OPENSSL_NO_DH
+		case OP_DH:
+			sp->opdata_dh_key = CK_INVALID_HANDLE;
+			sp->opdata_dh = NULL;
+			sp->opdata_dh_priv_num = NULL;
+			break;
+#endif	/* OPENSSL_NO_DH */
+		case OP_CIPHER:
+			sp->opdata_cipher_key = CK_INVALID_HANDLE;
+			sp->opdata_encrypt = -1;
+			break;
+		}
+
+	/*
+	 * We always initialize the session as containing a non-persistent
+	 * object. The key load functions set it to persistent if that is so.
+	 */
+	sp->persistent = CK_FALSE;
+	return (1);
+	}
+
+#ifndef OPENSSL_NO_RSA
+/*
+ * Destroy all non-NULL RSA parameters. For the RSA keys by reference code,
+ * public components 'n'/'e' are the key components we use to check for the
+ * cache hit even for the private keys. So, no matter whether we are destroying
+ * a public or a private key, we always free what we can.
+ */
+static void
+destroy_all_rsa_params(PK11_SESSION *sp)
+	{
+	if (sp->opdata_rsa_n_num != NULL)
+		{
+		BN_free(sp->opdata_rsa_n_num);
+		sp->opdata_rsa_n_num = NULL;
+		}
+	if (sp->opdata_rsa_e_num != NULL)
+		{
+		BN_free(sp->opdata_rsa_e_num);
+		sp->opdata_rsa_e_num = NULL;
+		}
+	if (sp->opdata_rsa_d_num != NULL)
+		{
+		BN_free(sp->opdata_rsa_d_num);
+		sp->opdata_rsa_d_num = NULL;
+		}
+	}
+
+/* Destroy RSA public key from single session. */
+int
+pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
+	{
+	int ret = 0;
+
+	if (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE)
+		{
+		TRY_OBJ_DESTROY(sp, sp->opdata_rsa_pub_key,
+		    ret, uselock, OP_RSA);
+		sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
+		sp->opdata_rsa_pub = NULL;
+		destroy_all_rsa_params(sp);
+		}
+
+	return (ret);
+	}
+
+/* Destroy RSA private key from single session. */
+int
+pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
+	{
+	int ret = 0;
+
+	if (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE)
+		{
+		TRY_OBJ_DESTROY(sp, sp->opdata_rsa_priv_key,
+		    ret, uselock, OP_RSA);
+		sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
+		sp->opdata_rsa_priv = NULL;
+		destroy_all_rsa_params(sp);
+		}
+
+	return (ret);
+	}
+
+/*
+ * Destroy RSA key object wrapper. If session is NULL, try to destroy all
+ * objects in the free list.
+ */
+int
+pk11_destroy_rsa_key_objects(PK11_SESSION *session)
+	{
+	int ret = 1;
+	PK11_SESSION *sp = NULL;
+	PK11_SESSION *local_free_session;
+	CK_BBOOL uselock = CK_TRUE;
+
+	if (session != NULL)
+		local_free_session = session;
+	else
+		{
+		(void) pthread_mutex_lock(session_cache[OP_RSA].lock);
+		local_free_session = session_cache[OP_RSA].head;
+		uselock = CK_FALSE;
+		}
+
+	/*
+	 * go through the list of sessions and delete key objects
+	 */
+	while ((sp = local_free_session) != NULL)
+		{
+		local_free_session = sp->next;
+
+		/*
+		 * Do not terminate list traversal if one of the
+		 * destroy operations fails.
+		 */
+		if (pk11_destroy_rsa_object_pub(sp, uselock) == 0)
+			{
+			ret = 0;
+			continue;
+			}
+		if (pk11_destroy_rsa_object_priv(sp, uselock) == 0)
+			{
+			ret = 0;
+			continue;
+			}
+		}
+
+	if (session == NULL)
+		(void) pthread_mutex_unlock(session_cache[OP_RSA].lock);
+
+	return (ret);
+	}
+#endif	/* OPENSSL_NO_RSA */
+
+#ifndef OPENSSL_NO_DSA
+/* Destroy DSA public key from single session. */
+int
+pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
+	{
+	int ret = 0;
+
+	if (sp->opdata_dsa_pub_key != CK_INVALID_HANDLE)
+		{
+		TRY_OBJ_DESTROY(sp, sp->opdata_dsa_pub_key,
+		    ret, uselock, OP_DSA);
+		sp->opdata_dsa_pub_key = CK_INVALID_HANDLE;
+		sp->opdata_dsa_pub = NULL;
+		if (sp->opdata_dsa_pub_num != NULL)
+			{
+			BN_free(sp->opdata_dsa_pub_num);
+			sp->opdata_dsa_pub_num = NULL;
+			}
+		}
+
+	return (ret);
+	}
+
+/* Destroy DSA private key from single session. */
+int
+pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
+	{
+	int ret = 0;
+
+	if (sp->opdata_dsa_priv_key != CK_INVALID_HANDLE)
+		{
+		TRY_OBJ_DESTROY(sp, sp->opdata_dsa_priv_key,
+		    ret, uselock, OP_DSA);
+		sp->opdata_dsa_priv_key = CK_INVALID_HANDLE;
+		sp->opdata_dsa_priv = NULL;
+		if (sp->opdata_dsa_priv_num != NULL)
+			{
+			BN_free(sp->opdata_dsa_priv_num);
+			sp->opdata_dsa_priv_num = NULL;
+			}
+		}
+
+	return (ret);
+	}
+
+/*
+ * Destroy DSA key object wrapper. If session is NULL, try to destroy all
+ * objects in the free list.
+ */
+int
+pk11_destroy_dsa_key_objects(PK11_SESSION *session)
+	{
+	int ret = 1;
+	PK11_SESSION *sp = NULL;
+	PK11_SESSION *local_free_session;
+	CK_BBOOL uselock = CK_TRUE;
+
+	if (session != NULL)
+		local_free_session = session;
+	else
+		{
+		(void) pthread_mutex_lock(session_cache[OP_DSA].lock);
+		local_free_session = session_cache[OP_DSA].head;
+		uselock = CK_FALSE;
+		}
+
+	/*
+	 * go through the list of sessions and delete key objects
+	 */
+	while ((sp = local_free_session) != NULL)
+		{
+		local_free_session = sp->next;
+
+		/*
+		 * Do not terminate list traversal if one of the
+		 * destroy operations fails.
+		 */
+		if (pk11_destroy_dsa_object_pub(sp, uselock) == 0)
+			{
+			ret = 0;
+			continue;
+			}
+		if (pk11_destroy_dsa_object_priv(sp, uselock) == 0)
+			{
+			ret = 0;
+			continue;
+			}
+		}
+
+	if (session == NULL)
+		(void) pthread_mutex_unlock(session_cache[OP_DSA].lock);
+
+	return (ret);
+	}
+#endif	/* OPENSSL_NO_DSA */
+
+#ifndef OPENSSL_NO_DH
+/* Destroy DH key from single session. */
+int
+pk11_destroy_dh_object(PK11_SESSION *sp, CK_BBOOL uselock)
+	{
+	int ret = 0;
+
+	if (sp->opdata_dh_key != CK_INVALID_HANDLE)
+		{
+		TRY_OBJ_DESTROY(sp, sp->opdata_dh_key,
+		    ret, uselock, OP_DH);
+		sp->opdata_dh_key = CK_INVALID_HANDLE;
+		sp->opdata_dh = NULL;
+		if (sp->opdata_dh_priv_num != NULL)
+			{
+			BN_free(sp->opdata_dh_priv_num);
+			sp->opdata_dh_priv_num = NULL;
+			}
+		}
+
+	return (ret);
+	}
+
+/*
+ * Destroy DH key object wrapper.
+ *
+ * arg0: pointer to PKCS#11 engine session structure
+ *       if session is NULL, try to destroy all objects in the free list
+ */
+int
+pk11_destroy_dh_key_objects(PK11_SESSION *session)
+	{
+	int ret = 1;
+	PK11_SESSION *sp = NULL;
+	PK11_SESSION *local_free_session;
+	CK_BBOOL uselock = CK_TRUE;
+
+	if (session != NULL)
+		local_free_session = session;
+	else
+		{
+		(void) pthread_mutex_lock(session_cache[OP_DH].lock);
+		local_free_session = session_cache[OP_DH].head;
+		uselock = CK_FALSE;
+		}
+
+	while ((sp = local_free_session) != NULL)
+		{
+		local_free_session = sp->next;
+
+		/*
+		 * Do not terminate list traversal if one of the
+		 * destroy operations fails.
+		 */
+		if (pk11_destroy_dh_object(sp, uselock) == 0)
+			{
+			ret = 0;
+			continue;
+			}
+		}
+	if (session == NULL)
+		(void) pthread_mutex_unlock(session_cache[OP_DH].lock);
+
+	return (ret);
+	}
+#endif	/* OPENSSL_NO_DH */
+
+static int
+pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
+    CK_BBOOL persistent)
+	{
+	CK_RV rv;
+
+	/*
+	 * We never try to destroy persistent objects which are the objects
+	 * stored in the keystore. Also, we always use read-only sessions so
+	 * C_DestroyObject() would be returning CKR_SESSION_READ_ONLY here.
+	 */
+	if (persistent == CK_TRUE)
+		return (1);
+
+	rv = pFuncList->C_DestroyObject(session, oh);
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_DESTROY_OBJECT, PK11_R_DESTROYOBJECT,
+		    rv);
+		return (0);
+		}
+
+	return (1);
+	}
+
+
+/* Symmetric ciphers and digests support functions */
+
+static int
+cipher_nid_to_pk11(int nid)
+	{
+	int i;
+
+	for (i = 0; i < PK11_CIPHER_MAX; i++)
+		if (ciphers[i].nid == nid)
+			return (ciphers[i].id);
+	return (-1);
+	}
+
+static int
+pk11_usable_ciphers(const int **nids)
+	{
+	if (cipher_count > 0)
+		*nids = cipher_nids;
+	else
+		*nids = NULL;
+	return (cipher_count);
+	}
+
+static int
+pk11_usable_digests(const int **nids)
+	{
+	if (digest_count > 0)
+		*nids = digest_nids;
+	else
+		*nids = NULL;
+	return (digest_count);
+	}
+
+/*
+ * Init context for encryption or decryption using a symmetric key.
+ */
+static int pk11_init_symmetric(EVP_CIPHER_CTX *ctx, PK11_CIPHER *pcipher,
+	PK11_SESSION *sp, CK_MECHANISM_PTR pmech)
+	{
+	CK_RV rv;
+	CK_AES_CTR_PARAMS ctr_params;
+
+	/*
+	 * We expect pmech->mechanism to be already set and
+	 * pParameter/ulParameterLen initialized to NULL/0 before
+	 * pk11_init_symmetric() is called.
+	 */
+	OPENSSL_assert(pmech->mechanism != NULL);
+	OPENSSL_assert(pmech->pParameter == NULL);
+	OPENSSL_assert(pmech->ulParameterLen == 0);
+
+	if (ctx->cipher->nid == NID_aes_128_ctr ||
+	    ctx->cipher->nid == NID_aes_192_ctr ||
+	    ctx->cipher->nid == NID_aes_256_ctr)
+		{
+		pmech->pParameter = (void *)(&ctr_params);
+		pmech->ulParameterLen = sizeof (ctr_params);
+		/*
+		 * For now, we are limited to the fixed length of the counter,
+		 * it covers the whole counter block. That's what RFC 4344
+		 * needs. For more information on internal structure of the
+		 * counter block, see RFC 3686. If needed in the future, we can
+		 * add code so that the counter length can be set via
+		 * ENGINE_ctrl() function.
+		 */
+		ctr_params.ulCounterBits = AES_BLOCK_SIZE * 8;
+		OPENSSL_assert(pcipher->iv_len == AES_BLOCK_SIZE);
+		(void) memcpy(ctr_params.cb, ctx->iv, AES_BLOCK_SIZE);
+		}
+	else
+		{
+		if (pcipher->iv_len > 0)
+			{
+			pmech->pParameter = (void *)ctx->iv;
+			pmech->ulParameterLen = pcipher->iv_len;
+			}
+		}
+
+	/* if we get here, the encryption needs to be reinitialized */
+	if (ctx->encrypt)
+		rv = pFuncList->C_EncryptInit(sp->session, pmech,
+			sp->opdata_cipher_key);
+	else
+		rv = pFuncList->C_DecryptInit(sp->session, pmech,
+			sp->opdata_cipher_key);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_CIPHER_INIT, ctx->encrypt ?
+		    PK11_R_ENCRYPTINIT : PK11_R_DECRYPTINIT, rv);
+		pk11_return_session(sp, OP_CIPHER);
+		return (0);
+		}
+
+	return (1);
+	}
+
+/* ARGSUSED */
+static int
+pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
+    const unsigned char *iv, int enc)
+	{
+	CK_MECHANISM mech;
+	int index;
+	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
+	PK11_SESSION *sp;
+	PK11_CIPHER *p_ciph_table_row;
+
+	state->sp = NULL;
+
+	index = cipher_nid_to_pk11(ctx->cipher->nid);
+	if (index < 0 || index >= PK11_CIPHER_MAX)
+		return (0);
+
+	p_ciph_table_row = &ciphers[index];
+	/*
+	 * iv_len in the ctx->cipher structure is the maximum IV length for the
+	 * current cipher and it must be less or equal to the IV length in our
+	 * ciphers table. The key length must be in the allowed interval. From
+	 * all cipher modes that the PKCS#11 engine supports only RC4 allows a
+	 * key length to be in some range, all other NIDs have a precise key
+	 * length. Every application can define its own EVP functions so this
+	 * code serves as a sanity check.
+	 *
+	 * Note that the reason why the IV length in ctx->cipher might be
+	 * greater than the actual length is that OpenSSL uses BLOCK_CIPHER_defs
+	 * macro to define functions that return EVP structures for all DES
+	 * modes. So, even ECB modes get 8 byte IV.
+	 */
+	if (ctx->cipher->iv_len < p_ciph_table_row->iv_len ||
+	    ctx->key_len < p_ciph_table_row->min_key_len ||
+	    ctx->key_len > p_ciph_table_row->max_key_len) {
+		PK11err(PK11_F_CIPHER_INIT, PK11_R_KEY_OR_IV_LEN_PROBLEM);
+		return (0);
+	}
+
+	if ((sp = pk11_get_session(OP_CIPHER)) == NULL)
+		return (0);
+
+	/* if applicable, the mechanism parameter is used for IV */
+	mech.mechanism = p_ciph_table_row->mech_type;
+	mech.pParameter = NULL;
+	mech.ulParameterLen = 0;
+
+	/* The key object is destroyed here if it is not the current key. */
+	(void) check_new_cipher_key(sp, key, ctx->key_len);
+
+	/*
+	 * If the key is the same and the encryption is also the same, then
+	 * just reuse it. However, we must not forget to reinitialize the
+	 * context that was finalized in pk11_cipher_cleanup().
+	 */
+	if (sp->opdata_cipher_key != CK_INVALID_HANDLE &&
+	    sp->opdata_encrypt == ctx->encrypt)
+		{
+		state->sp = sp;
+		if (pk11_init_symmetric(ctx, p_ciph_table_row, sp, &mech) == 0)
+			return (0);
+
+		return (1);
+		}
+
+	/*
+	 * Check if the key has been invalidated. If so, a new key object
+	 * needs to be created.
+	 */
+	if (sp->opdata_cipher_key == CK_INVALID_HANDLE)
+		{
+		sp->opdata_cipher_key = pk11_get_cipher_key(
+			ctx, key, p_ciph_table_row->key_type, sp);
+		}
+
+	if (sp->opdata_encrypt != ctx->encrypt && sp->opdata_encrypt != -1)
+		{
+		/*
+		 * The previous encryption/decryption is different. Need to
+		 * terminate the previous * active encryption/decryption here.
+		 */
+		if (!pk11_cipher_final(sp))
+			{
+			pk11_return_session(sp, OP_CIPHER);
+			return (0);
+			}
+		}
+
+	if (sp->opdata_cipher_key == CK_INVALID_HANDLE)
+		{
+		pk11_return_session(sp, OP_CIPHER);
+		return (0);
+		}
+
+	/* now initialize the context with a new key */
+	if (pk11_init_symmetric(ctx, p_ciph_table_row, sp, &mech) == 0)
+		return (0);
+
+	sp->opdata_encrypt = ctx->encrypt;
+	state->sp = sp;
+
+	return (1);
+	}
+
+/*
+ * When reusing the same key in an encryption/decryption session for a
+ * decryption/encryption session, we need to close the active session
+ * and recreate a new one. Note that the key is in the global session so
+ * that it needs not be recreated.
+ *
+ * It is more appropriate to use C_En/DecryptFinish here. At the time of this
+ * development, these two functions in the PKCS#11 libraries used return
+ * unexpected errors when passing in 0 length output. It may be a good
+ * idea to try them again if performance is a problem here and fix
+ * C_En/DecryptFinial if there are bugs there causing the problem.
+ */
+static int
+pk11_cipher_final(PK11_SESSION *sp)
+	{
+	CK_RV rv;
+
+	rv = pFuncList->C_CloseSession(sp->session);
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_CIPHER_FINAL, PK11_R_CLOSESESSION, rv);
+		return (0);
+		}
+
+	rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
+		NULL_PTR, NULL_PTR, &sp->session);
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_CIPHER_FINAL, PK11_R_OPENSESSION, rv);
+		return (0);
+		}
+
+	return (1);
+	}
+
+/*
+ * An engine interface function. The calling function allocates sufficient
+ * memory for the output buffer "out" to hold the results.
+ */
+static int
+pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+	const unsigned char *in, size_t inl)
+	{
+	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
+	PK11_SESSION *sp;
+	CK_RV rv;
+	unsigned long outl = inl;
+
+	if (state == NULL || state->sp == NULL)
+		return (0);
+
+	sp = (PK11_SESSION *) state->sp;
+
+	if (!inl)
+		return (1);
+
+	/* RC4 is the only stream cipher we support */
+	if (ctx->cipher->nid != NID_rc4 && (inl % ctx->cipher->block_size) != 0)
+		return (0);
+
+	if (ctx->encrypt)
+		{
+		rv = pFuncList->C_EncryptUpdate(sp->session,
+			(unsigned char *)in, inl, out, &outl);
+
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_CIPHER_DO_CIPHER,
+			    PK11_R_ENCRYPTUPDATE, rv);
+			return (0);
+			}
+		}
+	else
+		{
+		rv = pFuncList->C_DecryptUpdate(sp->session,
+			(unsigned char *)in, inl, out, &outl);
+
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_CIPHER_DO_CIPHER,
+			    PK11_R_DECRYPTUPDATE, rv);
+			return (0);
+			}
+		}
+
+	/*
+	 * For DES_CBC, DES3_CBC, AES_CBC, and RC4, the output size is always
+	 * the same size of input.
+	 * The application has guaranteed to call the block ciphers with
+	 * correctly aligned buffers.
+	 */
+	if (inl != outl)
+		return (0);
+
+	return (1);
+	}
+
+/*
+ * Return the session to the pool. Calling C_EncryptFinal() and C_DecryptFinal()
+ * here is the right thing because in EVP_DecryptFinal_ex(), engine's
+ * do_cipher() is not even called, and in EVP_EncryptFinal_ex() it is called but
+ * the engine can't find out that it's the finalizing call. We wouldn't
+ * necessarily have to finalize the context here since reinitializing it with
+ * C_(Encrypt|Decrypt)Init() should be fine but for the sake of correctness,
+ * let's do it. Some implementations might leak memory if the previously used
+ * context is initialized without finalizing it first.
+ */
+static int
+pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx)
+	{
+	CK_RV rv;
+	CK_ULONG len = EVP_MAX_BLOCK_LENGTH;
+	CK_BYTE buf[EVP_MAX_BLOCK_LENGTH];
+	PK11_CIPHER_STATE *state = ctx->cipher_data;
+
+	if (state != NULL && state->sp != NULL)
+		{
+		/*
+		 * We are not interested in the data here, we just need to get
+		 * rid of the context.
+		 */
+		if (ctx->encrypt)
+			rv = pFuncList->C_EncryptFinal(
+			    state->sp->session, buf, &len);
+		else
+			rv = pFuncList->C_DecryptFinal(
+			    state->sp->session, buf, &len);
+
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_CIPHER_CLEANUP, ctx->encrypt ?
+			    PK11_R_ENCRYPTFINAL : PK11_R_DECRYPTFINAL, rv);
+			pk11_return_session(state->sp, OP_CIPHER);
+			return (0);
+			}
+
+		pk11_return_session(state->sp, OP_CIPHER);
+		state->sp = NULL;
+		}
+
+	return (1);
+	}
+
+/*
+ * Registered by the ENGINE when used to find out how to deal with
+ * a particular NID in the ENGINE. This says what we'll do at the
+ * top level - note, that list is restricted by what we answer with
+ */
+/* ARGSUSED */
+static int
+pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
+	const int **nids, int nid)
+	{
+	if (!cipher)
+		return (pk11_usable_ciphers(nids));
+
+	switch (nid)
+		{
+		case NID_des_ede3_cbc:
+			*cipher = &pk11_3des_cbc;
+			break;
+		case NID_des_cbc:
+			*cipher = &pk11_des_cbc;
+			break;
+		case NID_des_ede3_ecb:
+			*cipher = &pk11_3des_ecb;
+			break;
+		case NID_des_ecb:
+			*cipher = &pk11_des_ecb;
+			break;
+		case NID_aes_128_cbc:
+			*cipher = &pk11_aes_128_cbc;
+			break;
+		case NID_aes_192_cbc:
+			*cipher = &pk11_aes_192_cbc;
+			break;
+		case NID_aes_256_cbc:
+			*cipher = &pk11_aes_256_cbc;
+			break;
+		case NID_aes_128_ecb:
+			*cipher = &pk11_aes_128_ecb;
+			break;
+		case NID_aes_192_ecb:
+			*cipher = &pk11_aes_192_ecb;
+			break;
+		case NID_aes_256_ecb:
+			*cipher = &pk11_aes_256_ecb;
+			break;
+		case NID_aes_128_ctr:
+			*cipher = &pk11_aes_128_ctr;
+			break;
+		case NID_aes_192_ctr:
+			*cipher = &pk11_aes_192_ctr;
+			break;
+		case NID_aes_256_ctr:
+			*cipher = &pk11_aes_256_ctr;
+			break;
+		case NID_bf_cbc:
+			*cipher = &pk11_bf_cbc;
+			break;
+		case NID_rc4:
+			*cipher = &pk11_rc4;
+			break;
+		default:
+			*cipher = NULL;
+			break;
+		}
+	return (*cipher != NULL);
+	}
+
+/* ARGSUSED */
+static int
+pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
+	const int **nids, int nid)
+	{
+	if (!digest)
+		return (pk11_usable_digests(nids));
+
+	switch (nid)
+		{
+		case NID_md5:
+			*digest = &pk11_md5;
+			break;
+		/*
+		 * A special case. For "openssl dgst -dss1 -engine pkcs11 ...",
+		 * OpenSSL calls EVP_get_digestbyname() on "dss1" which ends up
+		 * calling pk11_engine_digests() for NID_dsa. Internally, if an
+		 * engine is not used, OpenSSL uses SHA1_Init() as expected for
+		 * DSA. So, we must return pk11_sha1() for NID_dsa as well. Note
+		 * that this must have changed between 0.9.8 and 1.0.0 since we
+		 * did not have the problem with the 0.9.8 version.
+		 */
+		case NID_sha1:
+		case NID_dsa:
+			*digest = &pk11_sha1;
+			break;
+		case NID_sha224:
+			*digest = &pk11_sha224;
+			break;
+		case NID_sha256:
+			*digest = &pk11_sha256;
+			break;
+		case NID_sha384:
+			*digest = &pk11_sha384;
+			break;
+		case NID_sha512:
+			*digest = &pk11_sha512;
+			break;
+		default:
+			*digest = NULL;
+			break;
+		}
+	return (*digest != NULL);
+	}
+
+
+/* Create a secret key object in a PKCS#11 session */
+static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
+	const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp)
+	{
+	CK_RV rv;
+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
+	CK_OBJECT_CLASS obj_key = CKO_SECRET_KEY;
+	CK_ULONG ul_key_attr_count = 6;
+
+	CK_ATTRIBUTE  a_key_template[] =
+		{
+		{CKA_CLASS, (void*) NULL, sizeof (CK_OBJECT_CLASS)},
+		{CKA_KEY_TYPE, (void*) NULL, sizeof (CK_KEY_TYPE)},
+		{CKA_TOKEN, &pk11_false, sizeof (pk11_false)},
+		{CKA_ENCRYPT, &pk11_true, sizeof (pk11_true)},
+		{CKA_DECRYPT, &pk11_true, sizeof (pk11_true)},
+		{CKA_VALUE, (void*) NULL, 0},
+		};
+
+	/*
+	 * Create secret key object in global_session. All other sessions
+	 * can use the key handles. Here is why:
+	 * OpenSSL will call EncryptInit and EncryptUpdate using a secret key.
+	 * It may then call DecryptInit and DecryptUpdate using the same key.
+	 * To use the same key object, we need to call EncryptFinal with
+	 * a 0 length message. Currently, this does not work for 3DES
+	 * mechanism. To get around this problem, we close the session and
+	 * then create a new session to use the same key object. When a session
+	 * is closed, all the object handles will be invalid. Thus, create key
+	 * objects in a global session, an individual session may be closed to
+	 * terminate the active operation.
+	 */
+	CK_SESSION_HANDLE session = global_session;
+	a_key_template[0].pValue = &obj_key;
+	a_key_template[1].pValue = &key_type;
+	a_key_template[5].pValue = (void *) key;
+	a_key_template[5].ulValueLen = (unsigned long) ctx->key_len;
+
+	rv = pFuncList->C_CreateObject(session,
+		a_key_template, ul_key_attr_count, &h_key);
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_GET_CIPHER_KEY, PK11_R_CREATEOBJECT,
+		    rv);
+		goto err;
+		}
+
+	/*
+	 * Save the key information used in this session.
+	 * The max can be saved is PK11_KEY_LEN_MAX.
+	 */
+	sp->opdata_key_len = ctx->key_len > PK11_KEY_LEN_MAX ?
+		PK11_KEY_LEN_MAX : ctx->key_len;
+	(void) memcpy(sp->opdata_key, key, sp->opdata_key_len);
+err:
+
+	return (h_key);
+	}
+
+static int
+md_nid_to_pk11(int nid)
+	{
+	int i;
+
+	for (i = 0; i < PK11_DIGEST_MAX; i++)
+		if (digests[i].nid == nid)
+			return (digests[i].id);
+	return (-1);
+	}
+
+static int
+pk11_digest_init(EVP_MD_CTX *ctx)
+	{
+	CK_RV rv;
+	CK_MECHANISM mech;
+	int index;
+	PK11_SESSION *sp;
+	PK11_DIGEST *pdp;
+	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
+
+	state->sp = NULL;
+
+	index = md_nid_to_pk11(ctx->digest->type);
+	if (index < 0 || index >= PK11_DIGEST_MAX)
+		return (0);
+
+	pdp = &digests[index];
+	if ((sp = pk11_get_session(OP_DIGEST)) == NULL)
+		return (0);
+
+	/* at present, no parameter is needed for supported digests */
+	mech.mechanism = pdp->mech_type;
+	mech.pParameter = NULL;
+	mech.ulParameterLen = 0;
+
+	rv = pFuncList->C_DigestInit(sp->session, &mech);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_DIGEST_INIT, PK11_R_DIGESTINIT, rv);
+		pk11_return_session(sp, OP_DIGEST);
+		return (0);
+		}
+
+	state->sp = sp;
+
+	return (1);
+	}
+
+static int
+pk11_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
+	{
+	CK_RV rv;
+	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
+
+	/* 0 length message will cause a failure in C_DigestFinal */
+	if (count == 0)
+		return (1);
+
+	if (state == NULL || state->sp == NULL)
+		return (0);
+
+	rv = pFuncList->C_DigestUpdate(state->sp->session, (CK_BYTE *) data,
+		count);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_DIGEST_UPDATE, PK11_R_DIGESTUPDATE, rv);
+		pk11_return_session(state->sp, OP_DIGEST);
+		state->sp = NULL;
+		return (0);
+		}
+
+	return (1);
+	}
+
+static int
+pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
+	{
+	CK_RV rv;
+	unsigned long len;
+	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
+	len = ctx->digest->md_size;
+
+	if (state == NULL || state->sp == NULL)
+		return (0);
+
+	rv = pFuncList->C_DigestFinal(state->sp->session, md, &len);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_DIGEST_FINAL, PK11_R_DIGESTFINAL, rv);
+		pk11_return_session(state->sp, OP_DIGEST);
+		state->sp = NULL;
+		return (0);
+		}
+
+	if (ctx->digest->md_size != len)
+		return (0);
+
+	/*
+	 * Final is called and digest is returned, so return the session
+	 * to the pool
+	 */
+	pk11_return_session(state->sp, OP_DIGEST);
+	state->sp = NULL;
+
+	return (1);
+	}
+
+static int
+pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
+	{
+	CK_RV rv;
+	int ret = 0;
+	PK11_CIPHER_STATE *state, *state_to;
+	CK_BYTE_PTR pstate = NULL;
+	CK_ULONG ul_state_len;
+
+	if (from->md_data == NULL || to->digest->ctx_size == 0)
+		return (1);
+
+	/* The copy-from state */
+	state = (PK11_CIPHER_STATE *) from->md_data;
+	if (state->sp == NULL)
+		goto err;
+
+	/* Initialize the copy-to state */
+	if (!pk11_digest_init(to))
+		goto err;
+	state_to = (PK11_CIPHER_STATE *) to->md_data;
+
+	/* Get the size of the operation state of the copy-from session */
+	rv = pFuncList->C_GetOperationState(state->sp->session, NULL,
+		&ul_state_len);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE,
+		    rv);
+		goto err;
+		}
+	if (ul_state_len == 0)
+		{
+		goto err;
+		}
+
+	pstate = OPENSSL_malloc(ul_state_len);
+	if (pstate == NULL)
+		{
+		PK11err(PK11_F_DIGEST_COPY, PK11_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	/* Get the operation state of the copy-from session */
+	rv = pFuncList->C_GetOperationState(state->sp->session, pstate,
+		&ul_state_len);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE,
+		    rv);
+		goto err;
+		}
+
+	/* Set the operation state of the copy-to session */
+	rv = pFuncList->C_SetOperationState(state_to->sp->session, pstate,
+		ul_state_len, 0, 0);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_DIGEST_COPY,
+		    PK11_R_SET_OPERATION_STATE, rv);
+		goto err;
+		}
+
+	ret = 1;
+err:
+	if (pstate != NULL)
+		OPENSSL_free(pstate);
+
+	return (ret);
+	}
+
+/* Return any pending session state to the pool */
+static int
+pk11_digest_cleanup(EVP_MD_CTX *ctx)
+	{
+	PK11_CIPHER_STATE *state = ctx->md_data;
+	unsigned char buf[EVP_MAX_MD_SIZE];
+
+	if (state != NULL && state->sp != NULL)
+		{
+		/*
+		 * If state->sp is not NULL then pk11_digest_final() has not
+		 * been called yet. We must call it now to free any memory
+		 * that might have been allocated in the token when
+		 * pk11_digest_init() was called. pk11_digest_final()
+		 * will return the session to the cache.
+		 */
+		if (!pk11_digest_final(ctx, buf))
+			return (0);
+		}
+
+	return (1);
+	}
+
+/*
+ * Check if the new key is the same as the key object in the session. If the key
+ * is the same, no need to create a new key object. Otherwise, the old key
+ * object needs to be destroyed and a new one will be created. Return 1 for
+ * cache hit, 0 for cache miss. Note that we must check the key length first
+ * otherwise we could end up reusing a different, longer key with the same
+ * prefix.
+ */
+static int check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key,
+	int key_len)
+	{
+	if (sp->opdata_key_len != key_len ||
+	    memcmp(sp->opdata_key, key, key_len) != 0)
+		{
+		(void) pk11_destroy_cipher_key_objects(sp);
+		return (0);
+		}
+	return (1);
+	}
+
+/* Destroy one or more secret key objects. */
+static int pk11_destroy_cipher_key_objects(PK11_SESSION *session)
+	{
+	int ret = 0;
+	PK11_SESSION *sp = NULL;
+	PK11_SESSION *local_free_session;
+
+	if (session != NULL)
+		local_free_session = session;
+	else
+		{
+		(void) pthread_mutex_lock(session_cache[OP_CIPHER].lock);
+		local_free_session = session_cache[OP_CIPHER].head;
+		}
+
+	while ((sp = local_free_session) != NULL)
+		{
+		local_free_session = sp->next;
+
+		if (sp->opdata_cipher_key != CK_INVALID_HANDLE)
+			{
+			/*
+			 * The secret key object is created in the
+			 * global_session. See pk11_get_cipher_key().
+			 */
+			if (pk11_destroy_object(global_session,
+				sp->opdata_cipher_key, CK_FALSE) == 0)
+				goto err;
+			sp->opdata_cipher_key = CK_INVALID_HANDLE;
+			}
+		}
+	ret = 1;
+err:
+
+	if (session == NULL)
+		(void) pthread_mutex_unlock(session_cache[OP_CIPHER].lock);
+
+	return (ret);
+	}
+
+
+/*
+ * Public key mechanisms optionally supported
+ *
+ * CKM_RSA_X_509
+ * CKM_RSA_PKCS
+ * CKM_DSA
+ *
+ * The first slot that supports at least one of those mechanisms is chosen as a
+ * public key slot.
+ *
+ * Symmetric ciphers optionally supported
+ *
+ * CKM_DES3_CBC
+ * CKM_DES_CBC
+ * CKM_AES_CBC
+ * CKM_DES3_ECB
+ * CKM_DES_ECB
+ * CKM_AES_ECB
+ * CKM_AES_CTR
+ * CKM_RC4
+ * CKM_BLOWFISH_CBC
+ *
+ * Digests optionally supported
+ *
+ * CKM_MD5
+ * CKM_SHA_1
+ * CKM_SHA224
+ * CKM_SHA256
+ * CKM_SHA384
+ * CKM_SHA512
+ *
+ * The output of this function is a set of global variables indicating which
+ * mechanisms from RSA, DSA, DH and RAND are present, and also two arrays of
+ * mechanisms, one for symmetric ciphers and one for digests. Also, 3 global
+ * variables carry information about which slot was chosen for (a) public key
+ * mechanisms, (b) random operations, and (c) symmetric ciphers and digests.
+ */
+static int
+pk11_choose_slots(int *any_slot_found)
+	{
+	CK_SLOT_ID_PTR pSlotList = NULL_PTR;
+	CK_ULONG ulSlotCount = 0;
+	CK_MECHANISM_INFO mech_info;
+	CK_TOKEN_INFO token_info;
+	int i;
+	CK_RV rv;
+	CK_SLOT_ID best_slot_sofar;
+	CK_BBOOL found_candidate_slot = CK_FALSE;
+	int slot_n_cipher = 0;
+	int slot_n_digest = 0;
+	CK_SLOT_ID current_slot = 0;
+	int current_slot_n_cipher = 0;
+	int current_slot_n_digest = 0;
+
+	int local_cipher_nids[PK11_CIPHER_MAX];
+	int local_digest_nids[PK11_DIGEST_MAX];
+
+	/* let's initialize the output parameter */
+	if (any_slot_found != NULL)
+		*any_slot_found = 0;
+
+	/* Get slot list for memory allocation */
+	rv = pFuncList->C_GetSlotList(CK_FALSE, NULL_PTR, &ulSlotCount);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
+		return (0);
+		}
+
+	/* it's not an error if we didn't find any providers */
+	if (ulSlotCount == 0)
+		{
+		DEBUG_SLOT_SEL("%s: no crypto providers found\n", PK11_DBG);
+		return (1);
+		}
+
+	pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
+
+	if (pSlotList == NULL)
+		{
+		PK11err(PK11_F_CHOOSE_SLOT, PK11_R_MALLOC_FAILURE);
+		return (0);
+		}
+
+	/* Get the slot list for processing */
+	rv = pFuncList->C_GetSlotList(CK_FALSE, pSlotList, &ulSlotCount);
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
+		OPENSSL_free(pSlotList);
+		return (0);
+		}
+
+	DEBUG_SLOT_SEL("%s: provider: %s\n", PK11_DBG, def_PK11_LIBNAME);
+	DEBUG_SLOT_SEL("%s: number of slots: %d\n", PK11_DBG, ulSlotCount);
+
+	DEBUG_SLOT_SEL("%s: == checking rand slots ==\n", PK11_DBG);
+	for (i = 0; i < ulSlotCount; i++)
+		{
+		current_slot = pSlotList[i];
+
+		DEBUG_SLOT_SEL("%s: checking slot: %d\n", PK11_DBG, i);
+		/* Check if slot has random support. */
+		rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
+		if (rv != CKR_OK)
+			continue;
+
+		DEBUG_SLOT_SEL("%s: token label: %.32s\n", PK11_DBG,
+		    token_info.label);
+
+		if (token_info.flags & CKF_RNG)
+			{
+			DEBUG_SLOT_SEL(
+			    "%s: this token has CKF_RNG flag\n", PK11_DBG);
+			pk11_have_random = CK_TRUE;
+			rand_SLOTID = current_slot;
+			break;
+			}
+		}
+
+	DEBUG_SLOT_SEL("%s: == checking pubkey slots ==\n", PK11_DBG);
+
+	pubkey_SLOTID = pSlotList[0];
+	for (i = 0; i < ulSlotCount; i++)
+		{
+		CK_BBOOL slot_has_rsa = CK_FALSE;
+		CK_BBOOL slot_has_dsa = CK_FALSE;
+		CK_BBOOL slot_has_dh = CK_FALSE;
+		current_slot = pSlotList[i];
+
+		DEBUG_SLOT_SEL("%s: checking slot: %d\n", PK11_DBG, i);
+		rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
+		if (rv != CKR_OK)
+			continue;
+
+		DEBUG_SLOT_SEL("%s: token label: %.32s\n", PK11_DBG,
+		    token_info.label);
+
+#ifndef OPENSSL_NO_RSA
+		/*
+		 * Check if this slot is capable of signing and
+		 * verifying with CKM_RSA_PKCS.
+		 */
+		rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS,
+			&mech_info);
+
+		if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
+				(mech_info.flags & CKF_VERIFY)))
+			{
+			/*
+			 * Check if this slot is capable of encryption,
+			 * decryption, sign, and verify with CKM_RSA_X_509.
+			 */
+			rv = pFuncList->C_GetMechanismInfo(current_slot,
+			    CKM_RSA_X_509, &mech_info);
+
+			if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
+			    (mech_info.flags & CKF_VERIFY) &&
+			    (mech_info.flags & CKF_ENCRYPT) &&
+			    (mech_info.flags & CKF_VERIFY_RECOVER) &&
+			    (mech_info.flags & CKF_DECRYPT)))
+				{
+				slot_has_rsa = CK_TRUE;
+				}
+			}
+#endif	/* OPENSSL_NO_RSA */
+
+#ifndef OPENSSL_NO_DSA
+		/*
+		 * Check if this slot is capable of signing and
+		 * verifying with CKM_DSA.
+		 */
+		rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_DSA,
+			&mech_info);
+		if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
+		    (mech_info.flags & CKF_VERIFY)))
+			{
+			slot_has_dsa = CK_TRUE;
+			}
+
+#endif	/* OPENSSL_NO_DSA */
+
+#ifndef OPENSSL_NO_DH
+		/*
+		 * Check if this slot is capable of DH key generataion and
+		 * derivation.
+		 */
+		rv = pFuncList->C_GetMechanismInfo(current_slot,
+		    CKM_DH_PKCS_KEY_PAIR_GEN, &mech_info);
+
+		if (rv == CKR_OK && (mech_info.flags & CKF_GENERATE_KEY_PAIR))
+			{
+			rv = pFuncList->C_GetMechanismInfo(current_slot,
+				CKM_DH_PKCS_DERIVE, &mech_info);
+			if (rv == CKR_OK && (mech_info.flags & CKF_DERIVE))
+				{
+				slot_has_dh = CK_TRUE;
+				}
+			}
+#endif	/* OPENSSL_NO_DH */
+
+		if (!found_candidate_slot &&
+		    (slot_has_rsa || slot_has_dsa || slot_has_dh))
+			{
+			DEBUG_SLOT_SEL(
+			    "%s: potential slot: %d\n", PK11_DBG, current_slot);
+			best_slot_sofar = current_slot;
+			pk11_have_rsa = slot_has_rsa;
+			pk11_have_dsa = slot_has_dsa;
+			pk11_have_dh = slot_has_dh;
+			found_candidate_slot = CK_TRUE;
+			/*
+			 * Cache the flags for later use. We might need those if
+			 * RSA keys by reference feature is used.
+			 */
+			pubkey_token_flags = token_info.flags;
+			DEBUG_SLOT_SEL(
+			    "%s: setting found_candidate_slot to CK_TRUE\n",
+			    PK11_DBG);
+			DEBUG_SLOT_SEL("%s: best slot so far: %d\n", PK11_DBG,
+			    best_slot_sofar);
+			DEBUG_SLOT_SEL("%s: pubkey flags changed to "
+			    "%lu.\n", PK11_DBG, pubkey_token_flags);
+			}
+		else
+			{
+			DEBUG_SLOT_SEL("%s: no rsa/dsa/dh\n", PK11_DBG);
+			}
+		} /* for */
+
+	if (found_candidate_slot == CK_TRUE)
+		{
+		pubkey_SLOTID = best_slot_sofar;
+		}
+
+	found_candidate_slot = CK_FALSE;
+	best_slot_sofar = 0;
+
+	DEBUG_SLOT_SEL("%s: == checking cipher/digest ==\n", PK11_DBG);
+
+	SLOTID = pSlotList[0];
+	for (i = 0; i < ulSlotCount; i++)
+		{
+		DEBUG_SLOT_SEL("%s: checking slot: %d\n", PK11_DBG, i);
+
+		current_slot = pSlotList[i];
+		current_slot_n_cipher = 0;
+		current_slot_n_digest = 0;
+		(void) memset(local_cipher_nids, 0, sizeof (local_cipher_nids));
+		(void) memset(local_digest_nids, 0, sizeof (local_digest_nids));
+
+		pk11_find_symmetric_ciphers(pFuncList, current_slot,
+		    &current_slot_n_cipher, local_cipher_nids);
+
+		pk11_find_digests(pFuncList, current_slot,
+		    &current_slot_n_digest, local_digest_nids);
+
+		DEBUG_SLOT_SEL("%s: current_slot_n_cipher %d\n", PK11_DBG,
+			current_slot_n_cipher);
+		DEBUG_SLOT_SEL("%s: current_slot_n_digest %d\n", PK11_DBG,
+			current_slot_n_digest);
+		DEBUG_SLOT_SEL("%s: best cipher/digest slot so far: %d\n",
+			PK11_DBG, best_slot_sofar);
+
+		/*
+		 * If the current slot supports more ciphers/digests than
+		 * the previous best one we change the current best to this one,
+		 * otherwise leave it where it is.
+		 */
+		if ((current_slot_n_cipher + current_slot_n_digest) >
+		    (slot_n_cipher + slot_n_digest))
+			{
+			DEBUG_SLOT_SEL("%s: changing best slot to %d\n",
+				PK11_DBG, current_slot);
+			best_slot_sofar = SLOTID = current_slot;
+			cipher_count = slot_n_cipher = current_slot_n_cipher;
+			digest_count = slot_n_digest = current_slot_n_digest;
+			(void) memcpy(cipher_nids, local_cipher_nids,
+			    sizeof (local_cipher_nids));
+			(void) memcpy(digest_nids, local_digest_nids,
+			    sizeof (local_digest_nids));
+			}
+		}
+
+	DEBUG_SLOT_SEL("%s: chosen pubkey slot: %d\n", PK11_DBG, pubkey_SLOTID);
+	DEBUG_SLOT_SEL("%s: chosen rand slot: %d\n", PK11_DBG, rand_SLOTID);
+	DEBUG_SLOT_SEL("%s: chosen cipher/digest slot: %d\n", PK11_DBG, SLOTID);
+	DEBUG_SLOT_SEL("%s: pk11_have_rsa %d\n", PK11_DBG, pk11_have_rsa);
+	DEBUG_SLOT_SEL("%s: pk11_have_dsa %d\n", PK11_DBG, pk11_have_dsa);
+	DEBUG_SLOT_SEL("%s: pk11_have_dh %d\n", PK11_DBG, pk11_have_dh);
+	DEBUG_SLOT_SEL("%s: pk11_have_random %d\n", PK11_DBG, pk11_have_random);
+	DEBUG_SLOT_SEL("%s: cipher_count %d\n", PK11_DBG, cipher_count);
+	DEBUG_SLOT_SEL("%s: digest_count %d\n", PK11_DBG, digest_count);
+
+	if (pSlotList != NULL)
+		OPENSSL_free(pSlotList);
+
+#ifdef	SOLARIS_HW_SLOT_SELECTION
+	OPENSSL_free(hw_cnids);
+	OPENSSL_free(hw_dnids);
+#endif	/* SOLARIS_HW_SLOT_SELECTION */
+
+	if (any_slot_found != NULL)
+		*any_slot_found = 1;
+	return (1);
+	}
+
+static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR pflist,
+    int slot_id, int *current_slot_n_cipher, int *local_cipher_nids,
+    PK11_CIPHER *cipher)
+	{
+	CK_MECHANISM_INFO mech_info;
+	CK_RV rv;
+
+	DEBUG_SLOT_SEL("%s: checking mech: %x", PK11_DBG, cipher->mech_type);
+	rv = pflist->C_GetMechanismInfo(slot_id, cipher->mech_type, &mech_info);
+
+	if (rv != CKR_OK)
+		{
+		DEBUG_SLOT_SEL(" not found\n");
+		return;
+		}
+
+	if ((mech_info.flags & CKF_ENCRYPT) &&
+	    (mech_info.flags & CKF_DECRYPT))
+		{
+		if (mech_info.ulMinKeySize > cipher->min_key_len ||
+		    mech_info.ulMaxKeySize < cipher->max_key_len)
+			{
+			DEBUG_SLOT_SEL(" engine key size range <%i-%i> does not"
+			    " match mech range <%lu-%lu>\n",
+			    cipher->min_key_len, cipher->max_key_len,
+			    mech_info.ulMinKeySize, mech_info.ulMaxKeySize);
+			return;
+			}
+#ifdef	SOLARIS_HW_SLOT_SELECTION
+		if (nid_in_table(cipher->nid, hw_cnids))
+#endif	/* SOLARIS_HW_SLOT_SELECTION */
+			{
+			DEBUG_SLOT_SEL(" usable\n");
+			local_cipher_nids[(*current_slot_n_cipher)++] =
+			    cipher->nid;
+			}
+#ifdef	SOLARIS_HW_SLOT_SELECTION
+		else
+			{
+			DEBUG_SLOT_SEL(
+			    " rejected, software implementation only\n");
+			}
+#endif	/* SOLARIS_HW_SLOT_SELECTION */
+		}
+	else
+		{
+		DEBUG_SLOT_SEL(" unusable\n");
+		}
+
+	return;
+	}
+
+static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
+    int *current_slot_n_digest, int *local_digest_nids, PK11_DIGEST *digest)
+	{
+	CK_MECHANISM_INFO mech_info;
+	CK_RV rv;
+
+	DEBUG_SLOT_SEL("%s: checking mech: %x", PK11_DBG, digest->mech_type);
+	rv = pflist->C_GetMechanismInfo(slot_id, digest->mech_type, &mech_info);
+
+	if (rv != CKR_OK)
+		{
+		DEBUG_SLOT_SEL(" not found\n");
+		return;
+		}
+
+	if (mech_info.flags & CKF_DIGEST)
+		{
+#ifdef	SOLARIS_HW_SLOT_SELECTION
+		if (nid_in_table(digest->nid, hw_dnids))
+#endif	/* SOLARIS_HW_SLOT_SELECTION */
+			{
+			DEBUG_SLOT_SEL(" usable\n");
+			local_digest_nids[(*current_slot_n_digest)++] =
+			    digest->nid;
+			}
+#ifdef	SOLARIS_HW_SLOT_SELECTION
+		else
+			{
+			DEBUG_SLOT_SEL(
+			    " rejected, software implementation only\n");
+			}
+#endif	/* SOLARIS_HW_SLOT_SELECTION */
+		}
+	else
+		{
+		DEBUG_SLOT_SEL(" unusable\n");
+		}
+
+	return;
+	}
+
+/* Find what symmetric ciphers this slot supports. */
+static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
+    CK_SLOT_ID current_slot, int *current_slot_n_cipher, int *local_cipher_nids)
+	{
+	int i;
+
+	for (i = 0; i < PK11_CIPHER_MAX; ++i)
+		{
+		pk11_get_symmetric_cipher(pflist, current_slot,
+		    current_slot_n_cipher, local_cipher_nids, &ciphers[i]);
+		}
+	}
+
+/* Find what digest algorithms this slot supports. */
+static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
+    CK_SLOT_ID current_slot, int *current_slot_n_digest, int *local_digest_nids)
+	{
+	int i;
+
+	for (i = 0; i < PK11_DIGEST_MAX; ++i)
+		{
+		pk11_get_digest(pflist, current_slot, current_slot_n_digest,
+		    local_digest_nids, &digests[i]);
+		}
+	}
+
+#ifdef	SOLARIS_HW_SLOT_SELECTION
+/*
+ * It would be great if we could use pkcs11_kernel directly since this library
+ * offers hardware slots only. That's the easiest way to achieve the situation
+ * where we use the hardware accelerators when present and OpenSSL native code
+ * otherwise. That presumes the fact that OpenSSL native code is faster than the
+ * code in the soft token. It's a logical assumption - Crypto Framework has some
+ * inherent overhead so going there for the software implementation of a
+ * mechanism should be logically slower in contrast to the OpenSSL native code,
+ * presuming that both implementations are of similar speed. For example, the
+ * soft token for AES is roughly three times slower than OpenSSL for 64 byte
+ * blocks and still 20% slower for 8KB blocks. So, if we want to ship products
+ * that use the PKCS#11 engine by default, we must somehow avoid that regression
+ * on machines without hardware acceleration. That's why switching to the
+ * pkcs11_kernel library seems like a very good idea.
+ *
+ * The problem is that OpenSSL built with SunStudio is roughly 2x slower for
+ * asymmetric operations (RSA/DSA/DH) than the soft token built with the same
+ * compiler. That means that if we switched to pkcs11_kernel from the libpkcs11
+ * library, we would have had a performance regression on machines without
+ * hardware acceleration for asymmetric operations for all applications that use
+ * the PKCS#11 engine. There is one such application - Apache web server since
+ * it's shipped configured to use the PKCS#11 engine by default. Having said
+ * that, we can't switch to the pkcs11_kernel library now and have to come with
+ * a solution that, on non-accelerated machines, uses the OpenSSL native code
+ * for all symmetric ciphers and digests while it uses the soft token for
+ * asymmetric operations.
+ *
+ * This is the idea: dlopen() pkcs11_kernel directly and find out what
+ * mechanisms are there. We don't care about duplications (more slots can
+ * support the same mechanism), we just want to know what mechanisms can be
+ * possibly supported in hardware on that particular machine. As said before,
+ * pkcs11_kernel will show you hardware providers only.
+ *
+ * Then, we rely on the fact that since we use libpkcs11 library we will find
+ * the metaslot. When we go through the metaslot's mechanisms for symmetric
+ * ciphers and digests, we check that any found mechanism is in the table
+ * created using the pkcs11_kernel library. So, as a result we have two arrays
+ * of mechanisms that were advertised as supported in hardware which was the
+ * goal of that whole exercise. Thus, we can use libpkcs11 but avoid soft token
+ * code for symmetric ciphers and digests. See pk11_choose_slots() for more
+ * information.
+ *
+ * This is Solaris specific code, if SOLARIS_HW_SLOT_SELECTION is not defined
+ * the code won't be used.
+ */
+#if defined(__sparcv9) || defined(__x86_64) || defined(__amd64)
+static const char pkcs11_kernel[] = "/usr/lib/security/64/pkcs11_kernel.so.1";
+#else
+static const char pkcs11_kernel[] = "/usr/lib/security/pkcs11_kernel.so.1";
+#endif
+
+/*
+ * Check hardware capabilities of the machines. The output are two lists,
+ * hw_cnids and hw_dnids, that contain hardware mechanisms found in all hardware
+ * providers together. They are not sorted and may contain duplicate mechanisms.
+ */
+static int check_hw_mechanisms(void)
+	{
+	int i;
+	CK_RV rv;
+	void *handle;
+	CK_C_GetFunctionList p;
+	CK_TOKEN_INFO token_info;
+	CK_ULONG ulSlotCount = 0;
+	int n_cipher = 0, n_digest = 0;
+	CK_FUNCTION_LIST_PTR pflist = NULL;
+	CK_SLOT_ID_PTR pSlotList = NULL_PTR;
+	int *tmp_hw_cnids = NULL, *tmp_hw_dnids = NULL;
+	int hw_ctable_size, hw_dtable_size;
+
+	DEBUG_SLOT_SEL("%s: SOLARIS_HW_SLOT_SELECTION code running\n",
+	    PK11_DBG);
+	/*
+	 * Use RTLD_GROUP to limit the pkcs11_kernel provider to its own
+	 * symbols, which prevents it from mistakenly accessing C_* functions
+	 * from the top-level PKCS#11 library.
+	 */
+	if ((handle = dlopen(pkcs11_kernel, RTLD_LAZY | RTLD_GROUP)) == NULL)
+		{
+		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
+		goto err;
+		}
+
+	if ((p = (CK_C_GetFunctionList)dlsym(handle,
+	    PK11_GET_FUNCTION_LIST)) == NULL)
+		{
+		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
+		goto err;
+		}
+
+	/* get the full function list from the loaded library */
+	if (p(&pflist) != CKR_OK)
+		{
+		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
+		goto err;
+		}
+
+	rv = pflist->C_Initialize(NULL_PTR);
+	if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
+		{
+		PK11err_add_data(PK11_F_CHECK_HW_MECHANISMS,
+		    PK11_R_INITIALIZE, rv);
+		goto err;
+		}
+
+	if (pflist->C_GetSlotList(0, NULL_PTR, &ulSlotCount) != CKR_OK)
+		{
+		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_GETSLOTLIST);
+		goto err;
+		}
+
+	/* no slots, set the hw mechanism tables as empty */
+	if (ulSlotCount == 0)
+		{
+		DEBUG_SLOT_SEL("%s: no hardware mechanisms found\n", PK11_DBG);
+		hw_cnids = OPENSSL_malloc(sizeof (int));
+		hw_dnids = OPENSSL_malloc(sizeof (int));
+		if (hw_cnids == NULL || hw_dnids == NULL)
+			{
+			PK11err(PK11_F_CHECK_HW_MECHANISMS,
+			    PK11_R_MALLOC_FAILURE);
+			return (0);
+			}
+		/* this means empty tables */
+		hw_cnids[0] = NID_undef;
+		hw_dnids[0] = NID_undef;
+		return (1);
+		}
+
+	pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
+	if (pSlotList == NULL)
+		{
+		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	/* Get the slot list for processing */
+	if (pflist->C_GetSlotList(0, pSlotList, &ulSlotCount) != CKR_OK)
+		{
+		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_GETSLOTLIST);
+		goto err;
+		}
+
+	/*
+	 * We don't care about duplicate mechanisms in multiple slots and also
+	 * reserve one slot for the terminal NID_undef which we use to stop the
+	 * search.
+	 */
+	hw_ctable_size = ulSlotCount * PK11_CIPHER_MAX + 1;
+	hw_dtable_size = ulSlotCount * PK11_DIGEST_MAX + 1;
+	tmp_hw_cnids = OPENSSL_malloc(hw_ctable_size * sizeof (int));
+	tmp_hw_dnids = OPENSSL_malloc(hw_dtable_size * sizeof (int));
+	if (tmp_hw_cnids == NULL || tmp_hw_dnids == NULL)
+		{
+		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	/*
+	 * Do not use memset since we should not rely on the fact that NID_undef
+	 * is zero now.
+	 */
+	for (i = 0; i < hw_ctable_size; ++i)
+		tmp_hw_cnids[i] = NID_undef;
+	for (i = 0; i < hw_dtable_size; ++i)
+		tmp_hw_dnids[i] = NID_undef;
+
+	DEBUG_SLOT_SEL("%s: provider: %s\n", PK11_DBG, pkcs11_kernel);
+	DEBUG_SLOT_SEL("%s: found %d hardware slots\n", PK11_DBG, ulSlotCount);
+	DEBUG_SLOT_SEL("%s: now looking for mechs supported in hw\n",
+	    PK11_DBG);
+
+	for (i = 0; i < ulSlotCount; i++)
+		{
+		if (pflist->C_GetTokenInfo(pSlotList[i], &token_info) != CKR_OK)
+			continue;
+
+		DEBUG_SLOT_SEL("%s: token label: %.32s\n", PK11_DBG,
+		    token_info.label);
+
+		/*
+		 * We are filling the hw mech tables here. Global tables are
+		 * still NULL so all mechanisms are put into tmp tables.
+		 */
+		pk11_find_symmetric_ciphers(pflist, pSlotList[i],
+		    &n_cipher, tmp_hw_cnids);
+		pk11_find_digests(pflist, pSlotList[i],
+		    &n_digest, tmp_hw_dnids);
+		}
+
+	/*
+	 * Since we are part of a library (libcrypto.so), calling this function
+	 * may have side-effects. Also, C_Finalize() is triggered by
+	 * dlclose(3C).
+	 */
+#if 0
+	pflist->C_Finalize(NULL);
+#endif
+	OPENSSL_free(pSlotList);
+	(void) dlclose(handle);
+	hw_cnids = tmp_hw_cnids;
+	hw_dnids = tmp_hw_dnids;
+
+	DEBUG_SLOT_SEL("%s: hw mechs check complete\n", PK11_DBG);
+	return (1);
+
+err:
+	if (pSlotList != NULL)
+		OPENSSL_free(pSlotList);
+	if (tmp_hw_cnids != NULL)
+		OPENSSL_free(tmp_hw_cnids);
+	if (tmp_hw_dnids != NULL)
+		OPENSSL_free(tmp_hw_dnids);
+
+	return (0);
+	}
+
+/*
+ * Check presence of a NID in the table of NIDs unless the mechanism is
+ * supported directly in a CPU instruction set. The table may be NULL (i.e.,
+ * non-existent).
+ */
+static int nid_in_table(int nid, int *nid_table)
+	{
+	int i = 0;
+
+	/*
+	 * Special case first. NULL means that we are initializing a new table.
+	 */
+	if (nid_table == NULL)
+		return (1);
+
+#if defined(__x86)
+	/*
+	 * On Intel, if we have AES-NI instruction set we route AES to the
+	 * Crypto Framework. Intel CPUs do not have other instruction sets for
+	 * HW crypto acceleration so we check the HW NID table for any other
+	 * mechanism.
+	 */
+	if (hw_aes_instruction_set_present() == 1)
+		{
+		switch (nid)
+			{
+			case NID_aes_128_ecb:
+			case NID_aes_192_ecb:
+			case NID_aes_256_ecb:
+			case NID_aes_128_cbc:
+			case NID_aes_192_cbc:
+			case NID_aes_256_cbc:
+			case NID_aes_128_ctr:
+			case NID_aes_192_ctr:
+			case NID_aes_256_ctr:
+				return (1);
+			}
+		}
+#elif defined(__sparc)
+	if (hw_aes_instruction_set_present() == 1)
+		return (1);
+#endif
+
+	/* The table is never full, there is always at least one NID_undef. */
+	while (nid_table[i] != NID_undef)
+		{
+		if (nid_table[i++] == nid)
+			{
+			DEBUG_SLOT_SEL(" (NID %d in hw table, idx %d)", nid, i);
+			return (1);
+			}
+		}
+
+	return (0);
+	}
+
+/* Do we have an AES instruction set? */
+static int
+hw_aes_instruction_set_present(void)
+	{
+	static int present = -1;
+
+	if (present == -1)
+		{
+		uint_t ui = 0;
+
+		(void) getisax(&ui, 1);
+
+#if defined(__amd64) || defined(__i386)
+		present = (ui & (AV_386_AES)) > 0;
+#elif defined(__sparc)
+		present = (ui & (AV_SPARC_AES|AV_SPARC_FJAES)) > 0;
+#endif
+		}
+
+	return (present);
+	}
+
+#endif	/* SOLARIS_HW_SLOT_SELECTION */
+
+#endif	/* OPENSSL_NO_HW_PK11 */
+#endif	/* OPENSSL_NO_HW */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/engines/pkcs11/e_pk11.h	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* crypto/engine/e_pk11.h */
+/*
+ * This product includes software developed by the OpenSSL Project for
+ * use in the OpenSSL Toolkit (http://www.openssl.org/).
+ *
+ * This project also referenced hw_pkcs11-0.9.7b.patch written by
+ * Afchine Madjlessi.
+ */
+/*
+ * ====================================================================
+ * 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
+ *    [email protected].
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+#ifndef	E_PK11_H
+#define	E_PK11_H
+
+#include "e_pk11_err.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* max byte length of a symmetric key we support */
+#define	PK11_KEY_LEN_MAX			32
+
+/*
+ * This structure encapsulates all reusable information for a PKCS#11
+ * session. A list of these objects is created on behalf of the
+ * calling application using an on-demand method. Each operation
+ * type (see PK11_OPTYPE below) has its own per-process list.
+ * Each of the lists is basically a cache for faster PKCS#11 object
+ * access to avoid expensive C_Find{,Init,Final}Object() calls.
+ *
+ * When a new request comes in, an object will be taken from the list
+ * (if there is one) or a new one is created to handle the request
+ * (if the list is empty). See pk11_get_session() on how it is done.
+ */
+typedef struct PK11_st_SESSION
+	{
+	struct PK11_st_SESSION	*next;
+	CK_SESSION_HANDLE	session;	/* PK11 session handle */
+	pid_t			pid;		/* Current process ID */
+	CK_BBOOL		persistent;	/* is that a keystore object? */
+	union
+		{
+#ifndef OPENSSL_NO_RSA
+		struct
+			{
+			CK_OBJECT_HANDLE	rsa_pub_key; /* pub handle */
+			CK_OBJECT_HANDLE	rsa_priv_key; /* priv handle */
+			RSA			*rsa_pub; /* pub key addr */
+			BIGNUM			*rsa_n_num; /* pub modulus */
+			BIGNUM			*rsa_e_num; /* pub exponent */
+			RSA			*rsa_priv; /* priv key addr */
+			BIGNUM			*rsa_d_num; /* priv exponent */
+			} u_RSA;
+#endif /* OPENSSL_NO_RSA */
+#ifndef OPENSSL_NO_DSA
+		struct
+			{
+			CK_OBJECT_HANDLE	dsa_pub_key; /* pub handle */
+			CK_OBJECT_HANDLE	dsa_priv_key; /* priv handle */
+			DSA			*dsa_pub; /* pub key addr */
+			BIGNUM			*dsa_pub_num; /* pub key */
+			DSA			*dsa_priv; /* priv key addr */
+			BIGNUM			*dsa_priv_num; /* priv key */
+			} u_DSA;
+#endif /* OPENSSL_NO_DSA */
+#ifndef OPENSSL_NO_DH
+		struct
+			{
+			CK_OBJECT_HANDLE	dh_key; /* key handle */
+			DH			*dh; /* dh key addr */
+			BIGNUM			*dh_priv_num; /* priv dh key */
+			} u_DH;
+#endif /* OPENSSL_NO_DH */
+		struct
+			{
+			CK_OBJECT_HANDLE	cipher_key; /* key handle */
+			unsigned char		key[PK11_KEY_LEN_MAX];
+			int			key_len; /* priv key len */
+			int			encrypt; /* 1/0 enc/decr */
+			} u_cipher;
+		} opdata_u;
+	} PK11_SESSION;
+
+#define	opdata_rsa_pub_key	opdata_u.u_RSA.rsa_pub_key
+#define	opdata_rsa_priv_key	opdata_u.u_RSA.rsa_priv_key
+#define	opdata_rsa_pub		opdata_u.u_RSA.rsa_pub
+#define	opdata_rsa_priv		opdata_u.u_RSA.rsa_priv
+#define	opdata_rsa_n_num	opdata_u.u_RSA.rsa_n_num
+#define	opdata_rsa_e_num	opdata_u.u_RSA.rsa_e_num
+#define	opdata_rsa_d_num	opdata_u.u_RSA.rsa_d_num
+#define	opdata_dsa_pub_key	opdata_u.u_DSA.dsa_pub_key
+#define	opdata_dsa_priv_key	opdata_u.u_DSA.dsa_priv_key
+#define	opdata_dsa_pub		opdata_u.u_DSA.dsa_pub
+#define	opdata_dsa_pub_num	opdata_u.u_DSA.dsa_pub_num
+#define	opdata_dsa_priv		opdata_u.u_DSA.dsa_priv
+#define	opdata_dsa_priv_num	opdata_u.u_DSA.dsa_priv_num
+#define	opdata_dh_key		opdata_u.u_DH.dh_key
+#define	opdata_dh		opdata_u.u_DH.dh
+#define	opdata_dh_priv_num	opdata_u.u_DH.dh_priv_num
+#define	opdata_cipher_key	opdata_u.u_cipher.cipher_key
+#define	opdata_key		opdata_u.u_cipher.key
+#define	opdata_key_len		opdata_u.u_cipher.key_len
+#define	opdata_encrypt		opdata_u.u_cipher.encrypt
+
+/*
+ * We have 3 different groups of operation types:
+ *   1) asymmetric operations
+ *   2) random operations
+ *   3) symmetric and digest operations
+ *
+ * This division into groups stems from the fact that it's common that hardware
+ * providers may support operations from one group only. For example, hardware
+ * providers on UltraSPARC T2, n2rng(7d), ncp(7d), and n2cp(7d), each support
+ * only a single group of operations.
+ *
+ * For every group a different slot can be chosen. That means that we must have
+ * at least 3 different lists of cached PKCS#11 sessions since sessions from
+ * different groups may be initialized in different slots.
+ *
+ * To provide locking granularity in multithreaded environment, the groups are
+ * further split into types with each type having a separate session cache.
+ */
+typedef enum PK11_OPTYPE_ENUM
+	{
+	OP_RAND,
+	OP_RSA,
+	OP_DSA,
+	OP_DH,
+	OP_CIPHER,
+	OP_DIGEST,
+	OP_MAX
+	} PK11_OPTYPE;
+
+/*
+ * This structure contains the heads of the lists forming the object caches
+ * and locks associated with the lists.
+ */
+typedef struct PK11_st_CACHE
+	{
+	PK11_SESSION *head;
+	pthread_mutex_t *lock;
+	} PK11_CACHE;
+
+/* structure for tracking handles of asymmetric key objects */
+typedef struct PK11_active_st
+	{
+	CK_OBJECT_HANDLE h;
+	unsigned int refcnt;
+	struct PK11_active_st *prev;
+	struct PK11_active_st *next;
+	} PK11_active;
+
+extern pthread_mutex_t *find_lock[];
+extern PK11_active *active_list[];
+/*
+ * These variables are specific for the RSA keys by reference code. See
+ * e_pk11_pub.c for explanation.
+ */
+extern char *passphrasedialog;
+extern CK_FLAGS pubkey_token_flags;
+
+#define	LOCK_OBJSTORE(alg_type)	\
+	(void) pthread_mutex_lock(find_lock[alg_type])
+#define	UNLOCK_OBJSTORE(alg_type)	\
+	(void) pthread_mutex_unlock(find_lock[alg_type])
+
+extern PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
+extern void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
+
+#ifndef OPENSSL_NO_RSA
+extern int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
+extern int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
+extern int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
+extern EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *pubkey_file,
+	UI_METHOD *ui_method, void *callback_data);
+extern EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
+	UI_METHOD *ui_method, void *callback_data);
+extern RSA_METHOD *PK11_RSA(void);
+#endif /* OPENSSL_NO_RSA */
+#ifndef OPENSSL_NO_DSA
+extern int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
+extern int pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
+extern int pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
+extern DSA_METHOD *PK11_DSA(void);
+#endif /* OPENSSL_NO_DSA */
+#ifndef OPENSSL_NO_DH
+extern int pk11_destroy_dh_key_objects(PK11_SESSION *session);
+extern int pk11_destroy_dh_object(PK11_SESSION *sp, CK_BBOOL uselock);
+extern DH_METHOD *PK11_DH(void);
+#endif /* OPENSSL_NO_DH */
+
+extern int pk11_engine_pkey_methods(ENGINE *e, EVP_PKEY_METHOD **pmeth,
+    const int **nids, int nid);
+
+extern CK_FUNCTION_LIST_PTR pFuncList;
+
+#ifdef	__cplusplus
+}
+#endif
+#endif /* E_PK11_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/engines/pkcs11/e_pk11_err.c	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* crypto/engine/e_pk11_err.c */
+/*
+ * This product includes software developed by the OpenSSL Project for
+ * use in the OpenSSL Toolkit (http://www.openssl.org/).
+ *
+ * This project also referenced hw_pkcs11-0.9.7b.patch written by
+ * Afchine Madjlessi.
+ */
+/*
+ * ====================================================================
+ * 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
+ *    [email protected].
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+#include <stdio.h>
+#include <openssl/err.h>
+#include "e_pk11_err.h"
+
+/* BEGIN ERROR CODES */
+#ifndef OPENSSL_NO_ERR
+static ERR_STRING_DATA pk11_str_functs[]=
+{
+{ ERR_PACK(0, PK11_F_INIT, 0),			"PK11_INIT"},
+{ ERR_PACK(0, PK11_F_FINISH, 0),		"PK11_FINISH"},
+{ ERR_PACK(0, PK11_F_DESTROY, 0),		"PK11_DESTROY"},
+{ ERR_PACK(0, PK11_F_CTRL, 0),			"PK11_CTRL"},
+{ ERR_PACK(0, PK11_F_RSA_INIT, 0),		"PK11_RSA_INIT"},
+{ ERR_PACK(0, PK11_F_RSA_FINISH, 0),		"PK11_RSA_FINISH"},
+{ ERR_PACK(0, PK11_F_GET_PUB_RSA_KEY, 0),	"PK11_GET_PUB_RSA_KEY"},
+{ ERR_PACK(0, PK11_F_GET_PRIV_RSA_KEY, 0),	"PK11_GET_PRIV_RSA_KEY"},
+{ ERR_PACK(0, PK11_F_RSA_GEN_KEY, 0),		"PK11_RSA_GEN_KEY"},
+{ ERR_PACK(0, PK11_F_RSA_PUB_ENC, 0),		"PK11_RSA_PUB_ENC"},
+{ ERR_PACK(0, PK11_F_RSA_PRIV_ENC, 0),		"PK11_RSA_PRIV_ENC"},
+{ ERR_PACK(0, PK11_F_RSA_PUB_DEC, 0),		"PK11_RSA_PUB_DEC"},
+{ ERR_PACK(0, PK11_F_RSA_PRIV_DEC, 0),		"PK11_RSA_PRIV_DEC"},
+{ ERR_PACK(0, PK11_F_RSA_SIGN, 0),		"PK11_RSA_SIGN"},
+{ ERR_PACK(0, PK11_F_RSA_VERIFY, 0),		"PK11_RSA_VERIFY"},
+{ ERR_PACK(0, PK11_F_RAND_ADD, 0),		"PK11_RAND_ADD"},
+{ ERR_PACK(0, PK11_F_RAND_BYTES, 0),		"PK11_RAND_BYTES"},
+{ ERR_PACK(0, PK11_F_GET_SESSION, 0),		"PK11_GET_SESSION"},
+{ ERR_PACK(0, PK11_F_FREE_SESSION, 0),		"PK11_FREE_SESSION"},
+{ ERR_PACK(0, PK11_F_LOAD_PUBKEY, 0),		"PK11_LOAD_PUBKEY"},
+{ ERR_PACK(0, PK11_F_LOAD_PRIVKEY, 0),		"PK11_LOAD_PRIV_KEY"},
+{ ERR_PACK(0, PK11_F_RSA_PUB_ENC_LOW, 0),	"PK11_RSA_PUB_ENC_LOW"},
+{ ERR_PACK(0, PK11_F_RSA_PRIV_ENC_LOW, 0),	"PK11_RSA_PRIV_ENC_LOW"},
+{ ERR_PACK(0, PK11_F_RSA_PUB_DEC_LOW, 0),	"PK11_RSA_PUB_DEC_LOW"},
+{ ERR_PACK(0, PK11_F_RSA_PRIV_DEC_LOW, 0),	"PK11_RSA_PRIV_DEC_LOW"},
+{ ERR_PACK(0, PK11_F_DSA_SIGN, 0),		"PK11_DSA_SIGN"},
+{ ERR_PACK(0, PK11_F_DSA_VERIFY, 0),		"PK11_DSA_VERIFY"},
+{ ERR_PACK(0, PK11_F_DSA_INIT, 0),		"PK11_DSA_INIT"},
+{ ERR_PACK(0, PK11_F_DSA_FINISH, 0),		"PK11_DSA_FINISH"},
+{ ERR_PACK(0, PK11_F_GET_PUB_DSA_KEY, 0),	"PK11_GET_PUB_DSA_KEY"},
+{ ERR_PACK(0, PK11_F_GET_PRIV_DSA_KEY, 0),	"PK11_GET_PRIV_DSA_KEY"},
+{ ERR_PACK(0, PK11_F_DH_INIT, 0),		"PK11_DH_INIT"},
+{ ERR_PACK(0, PK11_F_DH_FINISH, 0),		"PK11_DH_FINISH"},
+{ ERR_PACK(0, PK11_F_MOD_EXP_DH, 0),		"PK11_MOD_EXP_DH"},
+{ ERR_PACK(0, PK11_F_GET_DH_KEY, 0),		"PK11_GET_DH_KEY"},
+{ ERR_PACK(0, PK11_F_FREE_ALL_SESSIONS, 0),	"PK11_FREE_ALL_SESSIONS"},
+{ ERR_PACK(0, PK11_F_SETUP_SESSION, 0),		"PK11_SETUP_SESSION"},
+{ ERR_PACK(0, PK11_F_DESTROY_OBJECT, 0),	"PK11_DESTROY_OBJECT"},
+{ ERR_PACK(0, PK11_F_CIPHER_INIT, 0),		"PK11_CIPHER_INIT"},
+{ ERR_PACK(0, PK11_F_CIPHER_DO_CIPHER, 0),	"PK11_CIPHER_DO_CIPHER"},
+{ ERR_PACK(0, PK11_F_GET_CIPHER_KEY, 0),	"PK11_GET_CIPHER_KEY"},
+{ ERR_PACK(0, PK11_F_DIGEST_INIT, 0),		"PK11_DIGEST_INIT"},
+{ ERR_PACK(0, PK11_F_DIGEST_UPDATE, 0),		"PK11_DIGEST_UPDATE"},
+{ ERR_PACK(0, PK11_F_DIGEST_FINAL, 0),		"PK11_DIGEST_FINAL"},
+{ ERR_PACK(0, PK11_F_CHOOSE_SLOT, 0),		"PK11_CHOOSE_SLOT"},
+{ ERR_PACK(0, PK11_F_CIPHER_FINAL, 0),		"PK11_CIPHER_FINAL"},
+{ ERR_PACK(0, PK11_F_LIBRARY_INIT, 0),		"PK11_LIBRARY_INIT"},
+{ ERR_PACK(0, PK11_F_LOAD, 0),			"ENGINE_LOAD_PK11"},
+{ ERR_PACK(0, PK11_F_DH_GEN_KEY, 0),		"PK11_DH_GEN_KEY"},
+{ ERR_PACK(0, PK11_F_DH_COMP_KEY, 0),		"PK11_DH_COMP_KEY"},
+{ ERR_PACK(0, PK11_F_DIGEST_COPY, 0),		"PK11_DIGEST_COPY"},
+{ ERR_PACK(0, PK11_F_CIPHER_CLEANUP, 0),	"PK11_CIPHER_CLEANUP"},
+{ ERR_PACK(0, PK11_F_ACTIVE_ADD, 0),		"PK11_ACTIVE_ADD"},
+{ ERR_PACK(0, PK11_F_ACTIVE_DELETE, 0),		"PK11_ACTIVE_DELETE"},
+{ ERR_PACK(0, PK11_F_CHECK_HW_MECHANISMS, 0),	"PK11_CHECK_HW_MECHANISMS"},
+{ ERR_PACK(0, PK11_F_INIT_SYMMETRIC, 0),	"PK11_INIT_SYMMETRIC"},
+{ ERR_PACK(0, PK11_F_ADD_AES_CTR_NIDS, 0),	"PK11_ADD_AES_CTR_NIDS"},
+{ ERR_PACK(0, PK11_F_INIT_ALL_LOCKS, 0),	"PK11_INIT_ALL_LOCKS"},
+{ ERR_PACK(0, PK11_F_RETURN_SESSION, 0),	"PK11_RETURN_SESSION"},
+{ ERR_PACK(0, PK11_F_GET_PIN, 0),		"PK11_GET_PIN"},
+{ ERR_PACK(0, PK11_F_FIND_ONE_OBJECT, 0),	"PK11_FIND_ONE_OBJECT"},
+{ ERR_PACK(0, PK11_F_CHECK_TOKEN_ATTRS, 0),	"PK11_CHECK_TOKEN_ATTRS"},
+{ ERR_PACK(0, PK11_F_CACHE_PIN, 0),		"PK11_CACHE_PIN"},
+{ ERR_PACK(0, PK11_F_MLOCK_PIN_IN_MEMORY, 0),	"PK11_MLOCK_PIN_IN_MEMORY"},
+{ ERR_PACK(0, PK11_F_TOKEN_LOGIN, 0),		"PK11_TOKEN_LOGIN"},
+{ ERR_PACK(0, PK11_F_TOKEN_RELOGIN, 0),		"PK11_TOKEN_RELOGIN"},
+{ ERR_PACK(0, PK11_F_RUN_ASKPASS, 0),		"PK11_F_RUN_ASKPASS"},
+{ 0, NULL}
+};
+
+static ERR_STRING_DATA pk11_str_reasons[]=
+{
+{ PK11_R_ALREADY_LOADED,		"PKCS#11 DSO already loaded"},
+{ PK11_R_DSO_FAILURE,			"unable to load PKCS#11 DSO"},
+{ PK11_R_NOT_LOADED,			"PKCS#11 DSO not loaded"},
+{ PK11_R_PASSED_NULL_PARAMETER,		"null parameter passed"},
+{ PK11_R_COMMAND_NOT_IMPLEMENTED,	"command not implemented"},
+{ PK11_R_INITIALIZE,			"C_Initialize failed"},
+{ PK11_R_FINALIZE,			"C_Finalize failed"},
+{ PK11_R_GETINFO,			"C_GetInfo faile"},
+{ PK11_R_GETSLOTLIST,			"C_GetSlotList failed"},
+{ PK11_R_NO_MODULUS_OR_NO_EXPONENT,	"no modulus or no exponent"},
+{ PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID,	"attr sensitive or invalid"},
+{ PK11_R_GETATTRIBUTVALUE,		"C_GetAttributeValue failed"},
+{ PK11_R_NO_MODULUS,			"no modulus"},
+{ PK11_R_NO_EXPONENT,			"no exponent"},
+{ PK11_R_FINDOBJECTSINIT,		"C_FindObjectsInit failed"},
+{ PK11_R_FINDOBJECTS,			"C_FindObjects failed"},
+{ PK11_R_FINDOBJECTSFINAL,		"C_FindObjectsFinal failed"},
+{ PK11_R_CREATEOBJECT,			"C_CreateObject failed"},
+{ PK11_R_DESTROYOBJECT,			"C_DestroyObject failed"},
+{ PK11_R_OPENSESSION,			"C_OpenSession failed"},
+{ PK11_R_CLOSESESSION,			"C_CloseSession failed"},
+{ PK11_R_ENCRYPTINIT,			"C_EncryptInit failed"},
+{ PK11_R_ENCRYPT,			"C_Encrypt failed"},
+{ PK11_R_SIGNINIT,			"C_SignInit failed"},
+{ PK11_R_SIGN,				"C_Sign failed"},
+{ PK11_R_DECRYPTINIT,			"C_DecryptInit failed"},
+{ PK11_R_DECRYPT,			"C_Decrypt failed"},
+{ PK11_R_VERIFYINIT,			"C_VerifyRecover failed"},
+{ PK11_R_VERIFY,			"C_Verify failed"},
+{ PK11_R_VERIFYRECOVERINIT,		"C_VerifyRecoverInit failed"},
+{ PK11_R_VERIFYRECOVER,			"C_VerifyRecover failed"},
+{ PK11_R_GEN_KEY,			"C_GenerateKeyPair failed"},
+{ PK11_R_SEEDRANDOM,			"C_SeedRandom failed"},
+{ PK11_R_GENERATERANDOM,		"C_GenerateRandom failed"},
+{ PK11_R_INVALID_MESSAGE_LENGTH,	"invalid message length"},
+{ PK11_R_UNKNOWN_ALGORITHM_TYPE,	"unknown algorithm type"},
+{ PK11_R_UNKNOWN_ASN1_OBJECT_ID,	"unknown asn1 onject id"},
+{ PK11_R_UNKNOWN_PADDING_TYPE,		"unknown padding type"},
+{ PK11_R_PADDING_CHECK_FAILED,		"padding check failed"},
+{ PK11_R_DIGEST_TOO_BIG,		"digest too big"},
+{ PK11_R_MALLOC_FAILURE,		"malloc failure"},
+{ PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED,	"ctl command not implemented"},
+{ PK11_R_DATA_GREATER_THAN_MOD_LEN,	"data is bigger than mod"},
+{ PK11_R_DATA_TOO_LARGE_FOR_MODULUS,	"data is too larger for mod"},
+{ PK11_R_MISSING_KEY_COMPONENT,		"a dsa component is missing"},
+{ PK11_R_INVALID_SIGNATURE_LENGTH,	"invalid signature length"},
+{ PK11_R_INVALID_DSA_SIGNATURE_R,	"missing r in dsa verify"},
+{ PK11_R_INVALID_DSA_SIGNATURE_S,	"missing s in dsa verify"},
+{ PK11_R_INCONSISTENT_KEY,		"inconsistent key type"},
+{ PK11_R_ENCRYPTUPDATE,			"C_EncryptUpdate failed"},
+{ PK11_R_DECRYPTUPDATE,			"C_DecryptUpdate failed"},
+{ PK11_R_DIGESTINIT,			"C_DigestInit failed"},
+{ PK11_R_DIGESTUPDATE,			"C_DigestUpdate failed"},
+{ PK11_R_DIGESTFINAL,			"C_DigestFinal failed"},
+{ PK11_R_ENCRYPTFINAL,			"C_EncryptFinal failed"},
+{ PK11_R_DECRYPTFINAL,			"C_DecryptFinal failed"},
+{ PK11_R_NO_PRNG_SUPPORT,		"Slot does not support PRNG"},
+{ PK11_R_GETTOKENINFO,			"C_GetTokenInfo failed"},
+{ PK11_R_DERIVEKEY,			"C_DeriveKey failed"},
+{ PK11_R_GET_OPERATION_STATE,		"C_GetOperationState failed"},
+{ PK11_R_SET_OPERATION_STATE,		"C_SetOperationState failed"},
+{ PK11_R_INVALID_HANDLE,		"invalid PKCS#11 object handle"},
+{ PK11_R_KEY_OR_IV_LEN_PROBLEM,		"IV or key length incorrect"},
+{ PK11_R_INVALID_OPERATION_TYPE,	"invalid operation type"},
+{ PK11_R_ADD_NID_FAILED,		"failed to add NID" },
+{ PK11_R_ATFORK_FAILED,			"atfork failed" },
+{ PK11_R_TOKEN_LOGIN_FAILED,		"C_Login failed on token" },
+{ PK11_R_MORE_THAN_ONE_OBJECT_FOUND,	"more than one object found" },
+{ PK11_R_INVALID_PKCS11_URI,		"pkcs11 URI provided is invalid" },
+{ PK11_R_COULD_NOT_READ_PIN,		"could not read PIN from terminal" },
+{ PK11_R_PIN_NOT_READ_FROM_COMMAND,	"PIN not read from external command" },
+{ PK11_R_COULD_NOT_OPEN_COMMAND,	"could not popen dialog command" },
+{ PK11_R_PIPE_FAILED,			"pipe failed" },
+{ PK11_R_BAD_PASSPHRASE_SPEC,		"bad passphrasedialog specification" },
+{ PK11_R_TOKEN_NOT_INITIALIZED,		"token not initialized" },
+{ PK11_R_TOKEN_PIN_NOT_SET,		"token PIN required but not set" },
+{ PK11_R_TOKEN_PIN_NOT_PROVIDED,	"token PIN required but not provided" },
+{ PK11_R_MISSING_OBJECT_LABEL,		"missing mandatory 'object' keyword" },
+{ PK11_R_TOKEN_ATTRS_DO_NOT_MATCH,	"token attrs provided do not match" },
+{ PK11_R_PRIV_KEY_NOT_FOUND,		"private key not found in keystore" },
+{ PK11_R_NO_OBJECT_FOUND,		"specified object not found" },
+{ PK11_R_PIN_CACHING_POLICY_INVALID,	"PIN set but caching policy invalid" },
+{ PK11_R_SYSCONF_FAILED,		"sysconf failed" },
+{ PK11_R_MMAP_FAILED,			"mmap failed" },
+{ PK11_R_PRIV_PROC_LOCK_MEMORY_MISSING,	"PROC_LOCK_MEMORY privilege missing" },
+{ PK11_R_MLOCK_FAILED,			"mlock failed" },
+{ PK11_R_FORK_FAILED,			"fork failed" },
+{ 0,	NULL}
+};
+#endif	/* OPENSSL_NO_ERR */
+
+static int pk11_lib_error_code = 0;
+static int pk11_error_init = 1;
+
+#ifdef PK11_ENGINE_LIB_NAME
+static ERR_STRING_DATA pk11_engine_lib_name[] =
+{
+{0, PK11_ENGINE_LIB_NAME},
+{0, NULL}
+};
+#endif
+
+static void
+ERR_load_pk11_strings(void)
+	{
+	if (pk11_lib_error_code == 0)
+		pk11_lib_error_code = ERR_get_next_error_library();
+
+	if (pk11_error_init)
+		{
+		pk11_error_init = 0;
+#ifndef OPENSSL_NO_ERR
+		ERR_load_strings(pk11_lib_error_code, pk11_str_functs);
+		ERR_load_strings(pk11_lib_error_code, pk11_str_reasons);
+#endif
+
+#ifdef PK11_ENGINE_LIB_NAME
+		pk11_engine_lib_name->error =
+		    ERR_PACK(pk11_lib_error_code, 0, 0);
+		ERR_load_strings(0, pk11_engine_lib_name);
+#endif
+		}
+}
+
+static void
+ERR_unload_pk11_strings(void)
+	{
+	if (pk11_error_init == 0)
+		{
+#ifndef OPENSSL_NO_ERR
+		ERR_unload_strings(pk11_lib_error_code, pk11_str_functs);
+		ERR_unload_strings(pk11_lib_error_code, pk11_str_reasons);
+#endif
+
+#ifdef PK11_ENGINE_LIB_NAME
+		ERR_unload_strings(0, pk11_engine_lib_name);
+#endif
+
+		pk11_error_init = 1;
+		}
+}
+
+void
+ERR_pk11_error(int function, int reason, char *file, int line)
+{
+	if (pk11_lib_error_code == 0)
+		pk11_lib_error_code = ERR_get_next_error_library();
+	ERR_PUT_error(pk11_lib_error_code, function, reason, file, line);
+}
+
+void
+PK11err_add_data(int function, int reason, CK_RV rv)
+{
+	char tmp_buf[20];
+
+	PK11err(function, reason);
+	(void) snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
+	ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/engines/pkcs11/e_pk11_err.h	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * This product includes software developed by the OpenSSL Project for
+ * use in the OpenSSL Toolkit (http://www.openssl.org/).
+ *
+ * This project also referenced hw_pkcs11-0.9.7b.patch written by
+ * Afchine Madjlessi.
+ */
+/*
+ * ====================================================================
+ * 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
+ *    [email protected].
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+#ifndef	E_PK11_ERR_H
+#define	E_PK11_ERR_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+void ERR_pk11_error(int function, int reason, char *file, int line);
+void PK11err_add_data(int function, int reason, CK_RV rv);
+#define	PK11err(f, r)	ERR_pk11_error((f), (r), __FILE__, __LINE__)
+
+/* Error codes for the PK11 functions. */
+
+/* Function codes. */
+
+#define	PK11_F_INIT 				100
+#define	PK11_F_FINISH				101
+#define	PK11_F_DESTROY 				102
+#define	PK11_F_CTRL 				103
+#define	PK11_F_RSA_INIT 			104
+#define	PK11_F_RSA_FINISH 			105
+#define	PK11_F_GET_PUB_RSA_KEY 			106
+#define	PK11_F_GET_PRIV_RSA_KEY 		107
+#define	PK11_F_RSA_GEN_KEY 			108
+#define	PK11_F_RSA_PUB_ENC 			109
+#define	PK11_F_RSA_PRIV_ENC 			110
+#define	PK11_F_RSA_PUB_DEC 			111
+#define	PK11_F_RSA_PRIV_DEC 			112
+#define	PK11_F_RSA_SIGN 			113
+#define	PK11_F_RSA_VERIFY 			114
+#define	PK11_F_RAND_ADD 			115
+#define	PK11_F_RAND_BYTES 			116
+#define	PK11_F_GET_SESSION 			117
+#define	PK11_F_FREE_SESSION 			118
+#define	PK11_F_LOAD_PUBKEY 			119
+#define	PK11_F_LOAD_PRIVKEY 			120
+#define	PK11_F_RSA_PUB_ENC_LOW 			121
+#define	PK11_F_RSA_PRIV_ENC_LOW 		122
+#define	PK11_F_RSA_PUB_DEC_LOW 			123
+#define	PK11_F_RSA_PRIV_DEC_LOW 		124
+#define	PK11_F_DSA_SIGN				125
+#define	PK11_F_DSA_VERIFY			126
+#define	PK11_F_DSA_INIT				127
+#define	PK11_F_DSA_FINISH			128
+#define	PK11_F_GET_PUB_DSA_KEY			129
+#define	PK11_F_GET_PRIV_DSA_KEY 		130
+#define	PK11_F_DH_INIT 				131
+#define	PK11_F_DH_FINISH 			132
+#define	PK11_F_MOD_EXP_DH 			133
+#define	PK11_F_GET_DH_KEY 			134
+#define	PK11_F_FREE_ALL_SESSIONS		135
+#define	PK11_F_SETUP_SESSION			136
+#define	PK11_F_DESTROY_OBJECT			137
+#define	PK11_F_CIPHER_INIT			138
+#define	PK11_F_CIPHER_DO_CIPHER			139
+#define	PK11_F_GET_CIPHER_KEY			140
+#define	PK11_F_DIGEST_INIT			141
+#define	PK11_F_DIGEST_UPDATE			142
+#define	PK11_F_DIGEST_FINAL			143
+#define	PK11_F_CHOOSE_SLOT			144
+#define	PK11_F_CIPHER_FINAL			145
+#define	PK11_F_LIBRARY_INIT 			146
+#define	PK11_F_LOAD 				147
+#define	PK11_F_DH_GEN_KEY			148
+#define	PK11_F_DH_COMP_KEY 			149
+#define	PK11_F_DIGEST_COPY 			150
+#define	PK11_F_CIPHER_CLEANUP			151
+#define	PK11_F_ACTIVE_ADD			152
+#define	PK11_F_ACTIVE_DELETE			153
+#define	PK11_F_CHECK_HW_MECHANISMS		154
+#define	PK11_F_INIT_SYMMETRIC			155
+#define	PK11_F_ADD_AES_CTR_NIDS			156
+#define	PK11_F_INIT_ALL_LOCKS			157
+#define	PK11_F_RETURN_SESSION			158
+#define	PK11_F_GET_PIN				159
+#define	PK11_F_FIND_ONE_OBJECT 			160
+#define	PK11_F_CHECK_TOKEN_ATTRS 		161
+#define	PK11_F_CACHE_PIN			162
+#define	PK11_F_MLOCK_PIN_IN_MEMORY		163
+#define	PK11_F_TOKEN_LOGIN 			164
+#define	PK11_F_TOKEN_RELOGIN 			165
+#define	PK11_F_RUN_ASKPASS 			166
+
+/* Reason codes. */
+#define	PK11_R_ALREADY_LOADED 			100
+#define	PK11_R_DSO_FAILURE 			101
+#define	PK11_R_NOT_LOADED 			102
+#define	PK11_R_PASSED_NULL_PARAMETER 		103
+#define	PK11_R_COMMAND_NOT_IMPLEMENTED 		104
+#define	PK11_R_INITIALIZE 			105
+#define	PK11_R_FINALIZE 			106
+#define	PK11_R_GETINFO 				107
+#define	PK11_R_GETSLOTLIST 			108
+#define	PK11_R_NO_MODULUS_OR_NO_EXPONENT 	109
+#define	PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID 	110
+#define	PK11_R_GETATTRIBUTVALUE 		111
+#define	PK11_R_NO_MODULUS 			112
+#define	PK11_R_NO_EXPONENT 			113
+#define	PK11_R_FINDOBJECTSINIT 			114
+#define	PK11_R_FINDOBJECTS 			115
+#define	PK11_R_FINDOBJECTSFINAL 		116
+#define	PK11_R_CREATEOBJECT 			118
+#define	PK11_R_DESTROYOBJECT 			119
+#define	PK11_R_OPENSESSION 			120
+#define	PK11_R_CLOSESESSION 			121
+#define	PK11_R_ENCRYPTINIT 			122
+#define	PK11_R_ENCRYPT 				123
+#define	PK11_R_SIGNINIT 			124
+#define	PK11_R_SIGN 				125
+#define	PK11_R_DECRYPTINIT 			126
+#define	PK11_R_DECRYPT 				127
+#define	PK11_R_VERIFYINIT 			128
+#define	PK11_R_VERIFY 				129
+#define	PK11_R_VERIFYRECOVERINIT 		130
+#define	PK11_R_VERIFYRECOVER 			131
+#define	PK11_R_GEN_KEY 				132
+#define	PK11_R_SEEDRANDOM 			133
+#define	PK11_R_GENERATERANDOM 			134
+#define	PK11_R_INVALID_MESSAGE_LENGTH 		135
+#define	PK11_R_UNKNOWN_ALGORITHM_TYPE 		136
+#define	PK11_R_UNKNOWN_ASN1_OBJECT_ID 		137
+#define	PK11_R_UNKNOWN_PADDING_TYPE 		138
+#define	PK11_R_PADDING_CHECK_FAILED 		139
+#define	PK11_R_DIGEST_TOO_BIG 			140
+#define	PK11_R_MALLOC_FAILURE 			141
+#define	PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED 	142
+#define	PK11_R_DATA_GREATER_THAN_MOD_LEN 	143
+#define	PK11_R_DATA_TOO_LARGE_FOR_MODULUS 	144
+#define	PK11_R_MISSING_KEY_COMPONENT		145
+#define	PK11_R_INVALID_SIGNATURE_LENGTH		146
+#define	PK11_R_INVALID_DSA_SIGNATURE_R		147
+#define	PK11_R_INVALID_DSA_SIGNATURE_S		148
+#define	PK11_R_INCONSISTENT_KEY			149
+#define	PK11_R_ENCRYPTUPDATE			150
+#define	PK11_R_DECRYPTUPDATE			151
+#define	PK11_R_DIGESTINIT			152
+#define	PK11_R_DIGESTUPDATE			153
+#define	PK11_R_DIGESTFINAL			154
+#define	PK11_R_ENCRYPTFINAL			155
+#define	PK11_R_DECRYPTFINAL			156
+#define	PK11_R_NO_PRNG_SUPPORT			157
+#define	PK11_R_GETTOKENINFO			158
+#define	PK11_R_DERIVEKEY			159
+#define	PK11_R_GET_OPERATION_STATE		160
+#define	PK11_R_SET_OPERATION_STATE		161
+#define	PK11_R_INVALID_HANDLE			162
+#define	PK11_R_KEY_OR_IV_LEN_PROBLEM		163
+#define	PK11_R_INVALID_OPERATION_TYPE		164
+#define	PK11_R_ADD_NID_FAILED			165
+#define	PK11_R_ATFORK_FAILED			166
+#define	PK11_R_TOKEN_LOGIN_FAILED		167
+#define	PK11_R_MORE_THAN_ONE_OBJECT_FOUND	168
+#define	PK11_R_INVALID_PKCS11_URI		169
+#define	PK11_R_COULD_NOT_READ_PIN		170
+#define	PK11_R_COULD_NOT_OPEN_COMMAND		171
+#define	PK11_R_PIPE_FAILED			172
+#define	PK11_R_PIN_NOT_READ_FROM_COMMAND	173
+#define	PK11_R_BAD_PASSPHRASE_SPEC		174
+#define	PK11_R_TOKEN_NOT_INITIALIZED		175
+#define	PK11_R_TOKEN_PIN_NOT_SET		176
+#define	PK11_R_TOKEN_PIN_NOT_PROVIDED		177
+#define	PK11_R_MISSING_OBJECT_LABEL		178
+#define	PK11_R_TOKEN_ATTRS_DO_NOT_MATCH		179
+#define	PK11_R_PRIV_KEY_NOT_FOUND		180
+#define	PK11_R_NO_OBJECT_FOUND			181
+#define	PK11_R_PIN_CACHING_POLICY_INVALID	182
+#define	PK11_R_SYSCONF_FAILED			183
+#define	PK11_R_MMAP_FAILED			183
+#define	PK11_R_PRIV_PROC_LOCK_MEMORY_MISSING	184
+#define	PK11_R_MLOCK_FAILED			185
+#define	PK11_R_FORK_FAILED			186
+
+#ifdef	__cplusplus
+}
+#endif
+#endif /* E_PK11_ERR_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/engines/pkcs11/e_pk11_pub.c	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,3273 @@
+/*
+ * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* crypto/engine/e_pk11_pub.c */
+/*
+ * This product includes software developed by the OpenSSL Project for
+ * use in the OpenSSL Toolkit (http://www.openssl.org/).
+ *
+ * This project also referenced hw_pkcs11-0.9.7b.patch written by
+ * Afchine Madjlessi.
+ */
+/*
+ * ====================================================================
+ * 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
+ *    [email protected].
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <strings.h>
+
+#include <openssl/e_os2.h>
+#include <openssl/crypto.h>
+#include <openssl/engine.h>
+#include <openssl/dso.h>
+#include <openssl/err.h>
+#include <openssl/bn.h>
+#include <openssl/pem.h>
+#ifndef OPENSSL_NO_RSA
+#include <openssl/rsa.h>
+#endif /* OPENSSL_NO_RSA */
+#ifndef OPENSSL_NO_DSA
+#include <openssl/dsa.h>
+#endif /* OPENSSL_NO_DSA */
+#ifndef OPENSSL_NO_DH
+#include <openssl/dh.h>
+#endif /* OPENSSL_NO_DH */
+#include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <pthread.h>
+#include <libgen.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_PK11
+
+#include <security/cryptoki.h>
+#include <security/pkcs11.h>
+#include "e_pk11.h"
+#include "e_pk11_uri.h"
+
+static CK_BBOOL pk11_login_done = CK_FALSE;
+extern CK_SLOT_ID pubkey_SLOTID;
+
+/*
+ * During the reinitialization after a detected fork we will try to login to the
+ * token using the passphrasedialog keyword that we inherit from the parent.
+ */
+char *passphrasedialog;
+
+#ifndef OPENSSL_NO_RSA
+/* RSA stuff */
+static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
+	unsigned char *to, RSA *rsa, int padding);
+static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
+	unsigned char *to, RSA *rsa, int padding);
+static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
+	unsigned char *to, RSA *rsa, int padding);
+static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
+	unsigned char *to, RSA *rsa, int padding);
+static int pk11_RSA_init(RSA *rsa);
+static int pk11_RSA_finish(RSA *rsa);
+static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
+	unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
+static int pk11_RSA_verify(int dtype, const unsigned char *m,
+	unsigned int m_len, const unsigned char *sigbuf, unsigned int siglen,
+	const RSA *rsa);
+EVP_PKEY *pk11_load_privkey(ENGINE*, const char *privkey_id,
+	UI_METHOD *ui_method, void *callback_data);
+EVP_PKEY *pk11_load_pubkey(ENGINE*, const char *pubkey_id,
+	UI_METHOD *ui_method, void *callback_data);
+
+static int pk11_RSA_public_encrypt_low(int flen, const unsigned char *from,
+	unsigned char *to, RSA *rsa);
+static int pk11_RSA_private_encrypt_low(int flen, const unsigned char *from,
+	unsigned char *to, RSA *rsa);
+static int pk11_RSA_public_decrypt_low(int flen, const unsigned char *from,
+	unsigned char *to, RSA *rsa);
+static int pk11_RSA_private_decrypt_low(int flen, const unsigned char *from,
+	unsigned char *to, RSA *rsa);
+
+static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA* rsa, PK11_SESSION *sp);
+static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa, PK11_SESSION *sp);
+
+static int pk11_check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa);
+static int pk11_check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa);
+#endif
+
+/* DSA stuff */
+#ifndef OPENSSL_NO_DSA
+static int pk11_DSA_init(DSA *dsa);
+static int pk11_DSA_finish(DSA *dsa);
+static DSA_SIG *pk11_dsa_do_sign(const unsigned char *dgst, int dlen,
+	DSA *dsa);
+static int pk11_dsa_do_verify(const unsigned char *dgst, int dgst_len,
+	DSA_SIG *sig, DSA *dsa);
+
+static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa, DSA **key_ptr,
+	BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session);
+static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa, DSA **key_ptr,
+	BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session);
+
+static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa);
+static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa);
+#endif
+
+/* DH stuff */
+#ifndef OPENSSL_NO_DH
+static int pk11_DH_init(DH *dh);
+static int pk11_DH_finish(DH *dh);
+static int pk11_DH_generate_key(DH *dh);
+static int pk11_DH_compute_key(unsigned char *key,
+	const BIGNUM *pub_key, DH *dh);
+
+static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh, DH **key_ptr,
+	BIGNUM **priv_key, CK_SESSION_HANDLE session);
+
+static int check_new_dh_key(PK11_SESSION *sp, DH *dh);
+#endif
+
+static int find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
+	CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey);
+static int init_template_value(BIGNUM *bn, CK_VOID_PTR *pValue,
+	CK_ULONG *ulValueLen);
+static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn);
+
+static int pk11_pkey_meth_nids[] = {NID_dsa};
+
+/* Read mode string to be used for fopen() */
+#if SOLARIS_OPENSSL
+static char *read_mode_flags = "rF";
+#else
+static char *read_mode_flags = "r";
+#endif
+
+/*
+ * Increment existing or create a new reference for an asymmetric key PKCS#11
+ * object handle in the active object list. If the operation fails, unlock (if
+ * locked), set error variable and jump to the specified label. We use this list
+ * so that we can track how many references to the PKCS#11 objects are used from
+ * all our sessions structures. If we are replacing an object reference in the
+ * session structure and the ref count for the reference being replaced gets to
+ * 0 we know that we can safely free the object itself via C_ObjectDestroy().
+ * See also TRY_OBJ_DESTROY.
+ */
+#define	KEY_HANDLE_REFHOLD(key_handle, alg_type, unlock, var, label)	\
+	{								\
+	if (pk11_active_add(key_handle, alg_type) < 0)			\
+		{							\
+		var = CK_TRUE;						\
+		if (unlock)						\
+			UNLOCK_OBJSTORE(alg_type);			\
+		goto label;						\
+		}							\
+	}
+
+/*
+ * Find active list entry according to object handle and return pointer to the
+ * entry otherwise return NULL.
+ *
+ * This function presumes it is called with lock protecting the active list
+ * held.
+ */
+static PK11_active *pk11_active_find(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
+	{
+	PK11_active *entry;
+
+	for (entry = active_list[type]; entry != NULL; entry = entry->next)
+		if (entry->h == h)
+			return (entry);
+
+	return (NULL);
+	}
+
+/*
+ * Search for an entry in the active list using PKCS#11 object handle as a
+ * search key and return refcnt of the found/created entry or -1 in case of
+ * failure.
+ *
+ * This function presumes it is called with lock protecting the active list
+ * held.
+ */
+int
+pk11_active_add(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
+	{
+	PK11_active *entry = NULL;
+
+	if (h == CK_INVALID_HANDLE)
+		{
+		PK11err(PK11_F_ACTIVE_ADD, PK11_R_INVALID_HANDLE);
+		return (-1);
+		}
+
+	/* search for entry in the active list */
+	if ((entry = pk11_active_find(h, type)) != NULL)
+		entry->refcnt++;
+	else
+		{
+		/* not found, create new entry and add it to the list */
+		entry = OPENSSL_malloc(sizeof (PK11_active));
+		if (entry == NULL)
+			{
+			PK11err(PK11_F_ACTIVE_ADD, PK11_R_MALLOC_FAILURE);
+			return (-1);
+			}
+		entry->h = h;
+		entry->refcnt = 1;
+		entry->prev = NULL;
+		entry->next = NULL;
+		/* connect the newly created entry to the list */
+		if (active_list[type] == NULL)
+			active_list[type] = entry;
+		else /* make the entry first in the list */
+			{
+			entry->next = active_list[type];
+			active_list[type]->prev = entry;
+			active_list[type] = entry;
+			}
+		}
+
+	return (entry->refcnt);
+	}
+
+/*
+ * Remove active list entry from the list and free it.
+ *
+ * This function presumes it is called with lock protecting the active list
+ * held.
+ */
+void
+pk11_active_remove(PK11_active *entry, PK11_OPTYPE type)
+	{
+	PK11_active *prev_entry;
+
+	/* remove the entry from the list and free it */
+	if ((prev_entry = entry->prev) != NULL)
+		{
+		prev_entry->next = entry->next;
+		if (entry->next != NULL)
+			entry->next->prev = prev_entry;
+		}
+	else
+		{
+		active_list[type] = entry->next;
+		/* we were the first but not the only one */
+		if (entry->next != NULL)
+			entry->next->prev = NULL;
+		}
+
+	/* sanitization */
+	entry->h = CK_INVALID_HANDLE;
+	entry->prev = NULL;
+	entry->next = NULL;
+	OPENSSL_free(entry);
+	}
+
+/* Free all entries from the active list. */
+void
+pk11_free_active_list(PK11_OPTYPE type)
+	{
+	PK11_active *entry;
+
+	/* only for asymmetric types since only they have C_Find* locks. */
+	switch (type)
+		{
+		case OP_RSA:
+		case OP_DSA:
+		case OP_DH:
+			break;
+		default:
+			return;
+		}
+
+	/* see find_lock array definition for more info on object locking */
+	LOCK_OBJSTORE(type);
+	while ((entry = active_list[type]) != NULL)
+		pk11_active_remove(entry, type);
+	UNLOCK_OBJSTORE(type);
+	}
+
+/*
+ * Search for active list entry associated with given PKCS#11 object handle,
+ * decrement its refcnt and if it drops to 0, disconnect the entry and free it.
+ *
+ * Return 1 if the PKCS#11 object associated with the entry has no references,
+ * return 0 if there is at least one reference, -1 on error.
+ *
+ * This function presumes it is called with lock protecting the active list
+ * held.
+ */
+int
+pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
+	{
+	PK11_active *entry = NULL;
+
+	if ((entry = pk11_active_find(h, type)) == NULL)
+		{
+		PK11err(PK11_F_ACTIVE_DELETE, PK11_R_INVALID_HANDLE);
+		return (-1);
+		}
+
+	OPENSSL_assert(entry->refcnt > 0);
+	entry->refcnt--;
+	if (entry->refcnt == 0)
+		{
+		pk11_active_remove(entry, type);
+		return (1);
+		}
+
+	return (0);
+	}
+
+#ifndef OPENSSL_NO_RSA
+/* Our internal RSA_METHOD that we provide pointers to */
+static RSA_METHOD pk11_rsa =
+	{
+	"PKCS#11 RSA method",
+	pk11_RSA_public_encrypt,		/* rsa_pub_encrypt */
+	pk11_RSA_public_decrypt,		/* rsa_pub_decrypt */
+	pk11_RSA_private_encrypt,		/* rsa_priv_encrypt */
+	pk11_RSA_private_decrypt,		/* rsa_priv_decrypt */
+	NULL,					/* rsa_mod_exp */
+	NULL,					/* bn_mod_exp */
+	pk11_RSA_init,				/* init */
+	pk11_RSA_finish,			/* finish */
+	RSA_FLAG_SIGN_VER,			/* flags */
+	NULL,					/* app_data */
+	pk11_RSA_sign,				/* rsa_sign */
+	pk11_RSA_verify,			/* rsa_verify */
+	/* Internal rsa_keygen will be used if this is NULL. */
+	NULL					/* rsa_keygen */
+	};
+
+RSA_METHOD *
+PK11_RSA(void)
+	{
+	return (&pk11_rsa);
+	}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+/* Our internal DSA_METHOD that we provide pointers to */
+static DSA_METHOD pk11_dsa =
+	{
+	"PKCS#11 DSA method",
+	pk11_dsa_do_sign, 	/* dsa_do_sign */
+	NULL, 			/* dsa_sign_setup */
+	pk11_dsa_do_verify, 	/* dsa_do_verify */
+	NULL,			/* dsa_mod_exp */
+	NULL, 			/* bn_mod_exp */
+	pk11_DSA_init, 		/* init */
+	pk11_DSA_finish, 	/* finish */
+	0, 			/* flags */
+	NULL 			/* app_data */
+	};
+
+DSA_METHOD *
+PK11_DSA(void)
+	{
+	return (&pk11_dsa);
+	}
+#endif
+
+#ifndef OPENSSL_NO_DH
+/*
+ * PKCS #11 V2.20, section 11.2 specifies that the number of bytes needed for
+ * output buffer may somewhat exceed the precise number of bytes needed, but
+ * should not exceed it by a large amount. That may be caused, for example, by
+ * rounding it up to multiple of X in the underlying bignum library. 8 should be
+ * enough.
+ */
+#define	DH_BUF_RESERVE	8
+
+/* Our internal DH_METHOD that we provide pointers to */
+static DH_METHOD pk11_dh =
+	{
+	"PKCS#11 DH method",
+	pk11_DH_generate_key,	/* generate_key */
+	pk11_DH_compute_key,	/* compute_key */
+	NULL,			/* bn_mod_exp */
+	pk11_DH_init,		/* init */
+	pk11_DH_finish,		/* finish */
+	0,			/* flags */
+	NULL,			/* app_data */
+	NULL			/* generate_params */
+	};
+
+DH_METHOD *
+PK11_DH(void)
+	{
+	return (&pk11_dh);
+	}
+#endif
+
+/* Size of an SSL signature: MD5+SHA1 */
+#define	SSL_SIG_LENGTH		36
+
+/* Lengths of DSA data and signature */
+#define	DSA_DATA_LEN		20
+#define	DSA_SIGNATURE_LEN	40
+
+#ifndef OPENSSL_NO_RSA
+/*
+ * Similar to OpenSSL to take advantage of the paddings. The goal is to
+ * support all paddings in this engine although PK11 library does not
+ * support all the paddings used in OpenSSL.
+ * The input errors should have been checked in the padding functions.
+ */
+static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
+		unsigned char *to, RSA *rsa, int padding)
+	{
+	int i, num = 0, r = -1;
+	unsigned char *buf = NULL;
+
+	num = BN_num_bytes(rsa->n);
+	if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
+		{
+		PK11err(PK11_F_RSA_PUB_ENC, PK11_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:
+		PK11err(PK11_F_RSA_PUB_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
+		goto err;
+		}
+	if (i <= 0) goto err;
+
+	/* PK11 functions are called here */
+	r = pk11_RSA_public_encrypt_low(num, buf, to, rsa);
+err:
+	if (buf != NULL)
+		{
+		OPENSSL_cleanse(buf, num);
+		OPENSSL_free(buf);
+		}
+	return (r);
+	}
+
+
+/*
+ * Similar to Openssl to take advantage of the paddings. The input errors
+ * should be caught in the padding functions
+ */
+static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
+	unsigned char *to, RSA *rsa, int padding)
+	{
+	int i, num = 0, r = -1;
+	unsigned char *buf = NULL;
+
+	num = BN_num_bytes(rsa->n);
+	if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
+		{
+		PK11err(PK11_F_RSA_PRIV_ENC, PK11_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_NO_PADDING:
+		i = RSA_padding_add_none(buf, num, from, flen);
+		break;
+	case RSA_SSLV23_PADDING:
+	default:
+		PK11err(PK11_F_RSA_PRIV_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
+		goto err;
+		}
+	if (i <= 0) goto err;
+
+	/* PK11 functions are called here */
+	r = pk11_RSA_private_encrypt_low(num, buf, to, rsa);
+err:
+	if (buf != NULL)
+		{
+		OPENSSL_cleanse(buf, num);
+		OPENSSL_free(buf);
+		}
+	return (r);
+	}
+
+/* Similar to OpenSSL code. Input errors are also checked here */
+static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
+	unsigned char *to, RSA *rsa, int padding)
+	{
+	BIGNUM f;
+	int j, num = 0, r = -1;
+	unsigned char *p;
+	unsigned char *buf = NULL;
+
+	BN_init(&f);
+
+	num = BN_num_bytes(rsa->n);
+
+	if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
+		{
+		PK11err(PK11_F_RSA_PRIV_DEC, PK11_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)
+		{
+		PK11err(PK11_F_RSA_PRIV_DEC,
+			PK11_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)
+		{
+		PK11err(PK11_F_RSA_PRIV_DEC,
+			PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
+		goto err;
+		}
+
+	/* PK11 functions are called here */
+	r = pk11_RSA_private_decrypt_low(flen, from, buf, rsa);
+
+	/*
+	 * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
+	 * Needs to skip these 0's paddings here.
+	 */
+	for (j = 0; j < r; j++)
+		if (buf[j] != 0)
+			break;
+
+	p = buf + j;
+	j = r - j;  /* j is only used with no-padding mode */
+
+	switch (padding)
+		{
+	case RSA_PKCS1_PADDING:
+		r = RSA_padding_check_PKCS1_type_2(to, num, p, j, num);
+		break;
+#ifndef OPENSSL_NO_SHA
+	case RSA_PKCS1_OAEP_PADDING:
+		r = RSA_padding_check_PKCS1_OAEP(to, num, p, j, num, NULL, 0);
+		break;
+#endif
+	case RSA_SSLV23_PADDING:
+		r = RSA_padding_check_SSLv23(to, num, p, j, num);
+		break;
+	case RSA_NO_PADDING:
+		r = RSA_padding_check_none(to, num, p, j, num);
+		break;
+	default:
+		PK11err(PK11_F_RSA_PRIV_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
+		goto err;
+		}
+	if (r < 0)
+		PK11err(PK11_F_RSA_PRIV_DEC, PK11_R_PADDING_CHECK_FAILED);
+
+err:
+	BN_clear_free(&f);
+	if (buf != NULL)
+		{
+		OPENSSL_cleanse(buf, num);
+		OPENSSL_free(buf);
+		}
+	return (r);
+	}
+
+/* Similar to OpenSSL code. Input errors are also checked here */
+static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
+	unsigned char *to, RSA *rsa, int padding)
+	{
+	BIGNUM f;
+	int i, num = 0, r = -1;
+	unsigned char *p;
+	unsigned char *buf = NULL;
+
+	BN_init(&f);
+	num = BN_num_bytes(rsa->n);
+	buf = (unsigned char *)OPENSSL_malloc(num);
+	if (buf == NULL)
+		{
+		PK11err(PK11_F_RSA_PUB_DEC, PK11_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)
+		{
+		PK11err(PK11_F_RSA_PUB_DEC, PK11_R_DATA_GREATER_THAN_MOD_LEN);
+		goto err;
+		}
+
+	if (BN_bin2bn(from, flen, &f) == NULL)
+		goto err;
+
+	if (BN_ucmp(&f, rsa->n) >= 0)
+		{
+		PK11err(PK11_F_RSA_PUB_DEC,
+			PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
+		goto err;
+		}
+
+	/* PK11 functions are called here */
+	r = pk11_RSA_public_decrypt_low(flen, from, buf, rsa);
+
+	/*
+	 * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
+	 * Needs to skip these 0's here
+	 */
+	for (i = 0; i < r; i++)
+		if (buf[i] != 0)
+			break;
+
+	p = buf + i;
+	i = r - i;  /* i is only used with no-padding mode */
+
+	switch (padding)
+		{
+	case RSA_PKCS1_PADDING:
+		r = RSA_padding_check_PKCS1_type_1(to, num, p, i, num);
+		break;
+	case RSA_NO_PADDING:
+		r = RSA_padding_check_none(to, num, p, i, num);
+		break;
+	default:
+		PK11err(PK11_F_RSA_PUB_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
+		goto err;
+		}
+	if (r < 0)
+		PK11err(PK11_F_RSA_PUB_DEC, PK11_R_PADDING_CHECK_FAILED);
+
+err:
+	BN_clear_free(&f);
+	if (buf != NULL)
+		{
+		OPENSSL_cleanse(buf, num);
+		OPENSSL_free(buf);
+		}
+	return (r);
+	}
+
+/*
+ * This function implements RSA public encryption using C_EncryptInit and
+ * C_Encrypt pk11 interfaces. Note that the CKM_RSA_X_509 is used here.
+ * The calling function allocated sufficient memory in "to" to store results.
+ */
+static int pk11_RSA_public_encrypt_low(int flen,
+	const unsigned char *from, unsigned char *to, RSA *rsa)
+	{
+	CK_ULONG bytes_encrypted = flen;
+	int retval = -1;
+	CK_RV rv;
+	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
+	CK_MECHANISM *p_mech = &mech_rsa;
+	CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
+	PK11_SESSION *sp;
+
+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
+		return (-1);
+
+	(void) pk11_check_new_rsa_key_pub(sp, rsa);
+
+	h_pub_key = sp->opdata_rsa_pub_key;
+	if (h_pub_key == CK_INVALID_HANDLE)
+		h_pub_key = sp->opdata_rsa_pub_key =
+			pk11_get_public_rsa_key(rsa, sp);
+
+	if (h_pub_key != CK_INVALID_HANDLE)
+		{
+		rv = pFuncList->C_EncryptInit(sp->session, p_mech,
+			h_pub_key);
+
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
+			    PK11_R_ENCRYPTINIT, rv);
+			pk11_return_session(sp, OP_RSA);
+			return (-1);
+			}
+
+		rv = pFuncList->C_Encrypt(sp->session,
+			(unsigned char *)from, flen, to, &bytes_encrypted);
+
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
+			    PK11_R_ENCRYPT, rv);
+			pk11_return_session(sp, OP_RSA);
+			return (-1);
+			}
+		retval = bytes_encrypted;
+		}
+
+	pk11_return_session(sp, OP_RSA);
+	return (retval);
+	}
+
+
+/*
+ * This function implements RSA private encryption using C_SignInit and
+ * C_Sign pk11 APIs. Note that CKM_RSA_X_509 is used here.
+ * The calling function allocated sufficient memory in "to" to store results.
+ */
+static int pk11_RSA_private_encrypt_low(int flen,
+	const unsigned char *from, unsigned char *to, RSA *rsa)
+	{
+	CK_ULONG ul_sig_len = flen;
+	int retval = -1;
+	CK_RV rv;
+	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
+	CK_MECHANISM *p_mech = &mech_rsa;
+	CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
+	PK11_SESSION *sp;
+
+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
+		return (-1);
+
+	(void) pk11_check_new_rsa_key_priv(sp, rsa);
+
+	h_priv_key = sp->opdata_rsa_priv_key;
+	if (h_priv_key == CK_INVALID_HANDLE)
+		h_priv_key = sp->opdata_rsa_priv_key =
+			pk11_get_private_rsa_key(rsa, sp);
+
+	if (h_priv_key != CK_INVALID_HANDLE)
+		{
+		rv = pFuncList->C_SignInit(sp->session, p_mech,
+			h_priv_key);
+
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW,
+			    PK11_R_SIGNINIT, rv);
+			pk11_return_session(sp, OP_RSA);
+			return (-1);
+			}
+
+		rv = pFuncList->C_Sign(sp->session,
+			(unsigned char *)from, flen, to, &ul_sig_len);
+
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW, PK11_R_SIGN,
+			    rv);
+			pk11_return_session(sp, OP_RSA);
+			return (-1);
+			}
+
+		retval = ul_sig_len;
+		}
+
+	pk11_return_session(sp, OP_RSA);
+	return (retval);
+	}
+
+
+/*
+ * This function implements RSA private decryption using C_DecryptInit and
+ * C_Decrypt pk11 APIs. Note that CKM_RSA_X_509 mechanism is used here.
+ * The calling function allocated sufficient memory in "to" to store results.
+ */
+static int pk11_RSA_private_decrypt_low(int flen,
+	const unsigned char *from, unsigned char *to, RSA *rsa)
+	{
+	CK_ULONG bytes_decrypted = flen;
+	int retval = -1;
+	CK_RV rv;
+	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
+	CK_MECHANISM *p_mech = &mech_rsa;
+	CK_OBJECT_HANDLE h_priv_key;
+	PK11_SESSION *sp;
+
+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
+		return (-1);
+
+	(void) pk11_check_new_rsa_key_priv(sp, rsa);
+
+	h_priv_key = sp->opdata_rsa_priv_key;
+	if (h_priv_key == CK_INVALID_HANDLE)
+		h_priv_key = sp->opdata_rsa_priv_key =
+			pk11_get_private_rsa_key(rsa, sp);
+
+	if (h_priv_key != CK_INVALID_HANDLE)
+		{
+		rv = pFuncList->C_DecryptInit(sp->session, p_mech,
+			h_priv_key);
+
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
+				PK11_R_DECRYPTINIT, rv);
+			pk11_return_session(sp, OP_RSA);
+			return (-1);
+			}
+
+		rv = pFuncList->C_Decrypt(sp->session,
+			(unsigned char *)from, flen, to, &bytes_decrypted);
+
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
+			    PK11_R_DECRYPT, rv);
+			pk11_return_session(sp, OP_RSA);
+			return (-1);
+			}
+		retval = bytes_decrypted;
+		}
+
+	pk11_return_session(sp, OP_RSA);
+	return (retval);
+	}
+
+
+/*
+ * This function implements RSA public decryption using C_VerifyRecoverInit
+ * and C_VerifyRecover pk11 APIs. Note that CKM_RSA_X_509 is used here.
+ * The calling function allocated sufficient memory in "to" to store results.
+ */
+static int pk11_RSA_public_decrypt_low(int flen,
+	const unsigned char *from, unsigned char *to, RSA *rsa)
+	{
+	CK_ULONG bytes_decrypted = flen;
+	int retval = -1;
+	CK_RV rv;
+	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
+	CK_MECHANISM *p_mech = &mech_rsa;
+	CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
+	PK11_SESSION *sp;
+
+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
+		return (-1);
+
+	(void) pk11_check_new_rsa_key_pub(sp, rsa);
+
+	h_pub_key = sp->opdata_rsa_pub_key;
+	if (h_pub_key == CK_INVALID_HANDLE)
+		h_pub_key = sp->opdata_rsa_pub_key =
+			pk11_get_public_rsa_key(rsa, sp);
+
+	if (h_pub_key != CK_INVALID_HANDLE)
+		{
+		rv = pFuncList->C_VerifyRecoverInit(sp->session,
+			p_mech, h_pub_key);
+
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
+				PK11_R_VERIFYRECOVERINIT, rv);
+			pk11_return_session(sp, OP_RSA);
+			return (-1);
+			}
+
+		rv = pFuncList->C_VerifyRecover(sp->session,
+			(unsigned char *)from, flen, to, &bytes_decrypted);
+
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
+			    PK11_R_VERIFYRECOVER, rv);
+			pk11_return_session(sp, OP_RSA);
+			return (-1);
+			}
+		retval = bytes_decrypted;
+		}
+
+	pk11_return_session(sp, OP_RSA);
+	return (retval);
+	}
+
+static int pk11_RSA_init(RSA *rsa)
+	{
+	/*
+	 * This flag in the RSA_METHOD enables the new rsa_sign,
+	 * rsa_verify functions. See rsa.h for details.
+	 */
+	rsa->flags |= RSA_FLAG_SIGN_VER;
+
+	return (1);
+	}
+
+static int pk11_RSA_finish(RSA *rsa)
+	{
+	/*
+	 * Since we are overloading OpenSSL's native RSA_eay_finish() we need
+	 * to do the same as in the original function, i.e. to free bignum
+	 * structures.
+	 */
+	if (rsa->_method_mod_n != NULL)
+		BN_MONT_CTX_free(rsa->_method_mod_n);
+	if (rsa->_method_mod_p != NULL)
+		BN_MONT_CTX_free(rsa->_method_mod_p);
+	if (rsa->_method_mod_q != NULL)
+		BN_MONT_CTX_free(rsa->_method_mod_q);
+
+	return (1);
+	}
+
+/*
+ * Standard engine interface function. Majority codes here are from
+ * rsa/rsa_sign.c. We replaced the decrypt function call by C_Sign of PKCS#11.
+ * See more details in rsa/rsa_sign.c
+ */
+static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
+	unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
+	{
+	X509_SIG sig;
+	ASN1_TYPE parameter;
+	int i, j;
+	unsigned char *p, *s = NULL;
+	X509_ALGOR algor;
+	ASN1_OCTET_STRING digest;
+	CK_RV rv;
+	CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
+	CK_MECHANISM *p_mech = &mech_rsa;
+	CK_OBJECT_HANDLE h_priv_key;
+	PK11_SESSION *sp = NULL;
+	int ret = 0;
+	unsigned long ulsiglen;
+
+	/* Encode the digest */
+	/* Special case: SSL signature, just check the length */
+	if (type == NID_md5_sha1)
+		{
+		if (m_len != SSL_SIG_LENGTH)
+			{
+			PK11err(PK11_F_RSA_SIGN,
+				PK11_R_INVALID_MESSAGE_LENGTH);
+			goto err;
+			}
+		i = SSL_SIG_LENGTH;
+		s = (unsigned char *)m;
+		}
+	else
+		{
+		sig.algor = &algor;
+		sig.algor->algorithm = OBJ_nid2obj(type);
+		if (sig.algor->algorithm == NULL)
+			{
+			PK11err(PK11_F_RSA_SIGN,
+				PK11_R_UNKNOWN_ALGORITHM_TYPE);
+			goto err;
+			}
+		if (sig.algor->algorithm->length == 0)
+			{
+			PK11err(PK11_F_RSA_SIGN,
+				PK11_R_UNKNOWN_ASN1_OBJECT_ID);
+			goto err;
+			}
+		parameter.type = V_ASN1_NULL;
+		parameter.value.ptr = NULL;
+		sig.algor->parameter = &parameter;
+
+		sig.digest = &digest;
+		sig.digest->data = (unsigned char *)m;
+		sig.digest->length = m_len;
+
+		i = i2d_X509_SIG(&sig, NULL);
+		}
+
+	j = RSA_size(rsa);
+	if ((i - RSA_PKCS1_PADDING) > j)
+		{
+		PK11err(PK11_F_RSA_SIGN, PK11_R_DIGEST_TOO_BIG);
+		goto err;
+		}
+
+	if (type != NID_md5_sha1)
+		{
+		s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
+		if (s == NULL)
+			{
+			PK11err(PK11_F_RSA_SIGN, PK11_R_MALLOC_FAILURE);
+			goto err;
+			}
+		p = s;
+		(void) i2d_X509_SIG(&sig, &p);
+		}
+
+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
+		goto err;
+
+	(void) pk11_check_new_rsa_key_priv(sp, rsa);
+
+	h_priv_key = sp->opdata_rsa_priv_key;
+	if (h_priv_key == CK_INVALID_HANDLE)
+		h_priv_key = sp->opdata_rsa_priv_key =
+			pk11_get_private_rsa_key((RSA *)rsa, sp);
+
+	if (h_priv_key != CK_INVALID_HANDLE)
+		{
+		rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
+
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGNINIT, rv);
+			goto err;
+			}
+
+		ulsiglen = j;
+		rv = pFuncList->C_Sign(sp->session, s, i, sigret,
+			(CK_ULONG_PTR) &ulsiglen);
+		*siglen = ulsiglen;
+
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGN, rv);
+			goto err;
+			}
+		ret = 1;
+		}
+
+err:
+	if (type != NID_md5_sha1)
+		{
+		(void) memset(s, 0, (unsigned int)(j + 1));
+		OPENSSL_free(s);
+		}
+
+	pk11_return_session(sp, OP_RSA);
+	return (ret);
+	}
+
+static int pk11_RSA_verify(int type, const unsigned char *m,
+	unsigned int m_len, const unsigned char *sigbuf, unsigned int siglen,
+	const RSA *rsa)
+	{
+	X509_SIG sig;
+	ASN1_TYPE parameter;
+	int i, j;
+	unsigned char *p, *s = NULL;
+	X509_ALGOR algor;
+	ASN1_OCTET_STRING digest;
+	CK_RV rv;
+	CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
+	CK_MECHANISM *p_mech = &mech_rsa;
+	CK_OBJECT_HANDLE h_pub_key;
+	PK11_SESSION *sp = NULL;
+	int ret = 0;
+
+	/* Encode the digest	*/
+	/* Special case: SSL signature, just check the length */
+	if (type == NID_md5_sha1)
+		{
+		if (m_len != SSL_SIG_LENGTH)
+			{
+			PK11err(PK11_F_RSA_VERIFY,
+				PK11_R_INVALID_MESSAGE_LENGTH);
+			goto err;
+			}
+		i = SSL_SIG_LENGTH;
+		s = (unsigned char *)m;
+		}
+	else
+		{
+		sig.algor = &algor;
+		sig.algor->algorithm = OBJ_nid2obj(type);
+		if (sig.algor->algorithm == NULL)
+			{
+			PK11err(PK11_F_RSA_VERIFY,
+				PK11_R_UNKNOWN_ALGORITHM_TYPE);
+			goto err;
+			}
+		if (sig.algor->algorithm->length == 0)
+			{
+			PK11err(PK11_F_RSA_VERIFY,
+				PK11_R_UNKNOWN_ASN1_OBJECT_ID);
+			goto err;
+			}
+		parameter.type = V_ASN1_NULL;
+		parameter.value.ptr = NULL;
+		sig.algor->parameter = &parameter;
+		sig.digest = &digest;
+		sig.digest->data = (unsigned char *)m;
+		sig.digest->length = m_len;
+		i = i2d_X509_SIG(&sig, NULL);
+		}
+
+	j = RSA_size(rsa);
+	if ((i - RSA_PKCS1_PADDING) > j)
+		{
+		PK11err(PK11_F_RSA_VERIFY, PK11_R_DIGEST_TOO_BIG);
+		goto err;
+		}
+
+	if (type != NID_md5_sha1)
+		{
+		s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
+		if (s == NULL)
+			{
+			PK11err(PK11_F_RSA_VERIFY, PK11_R_MALLOC_FAILURE);
+			goto err;
+			}
+		p = s;
+		(void) i2d_X509_SIG(&sig, &p);
+		}
+
+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
+		goto err;
+
+	(void) pk11_check_new_rsa_key_pub(sp, rsa);
+
+	h_pub_key = sp->opdata_rsa_pub_key;
+	if (h_pub_key == CK_INVALID_HANDLE)
+		h_pub_key = sp->opdata_rsa_pub_key =
+			pk11_get_public_rsa_key((RSA *)rsa, sp);
+
+	if (h_pub_key != CK_INVALID_HANDLE)
+		{
+		rv = pFuncList->C_VerifyInit(sp->session, p_mech,
+			h_pub_key);
+
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFYINIT,
+			    rv);
+			goto err;
+			}
+		rv = pFuncList->C_Verify(sp->session, s, i,
+			(CK_BYTE_PTR)sigbuf, (CK_ULONG)siglen);
+
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFY, rv);
+			goto err;
+			}
+		ret = 1;
+		}
+
+err:
+	if (type != NID_md5_sha1)
+		{
+		(void) memset(s, 0, (unsigned int)siglen);
+		OPENSSL_free(s);
+		}
+
+	pk11_return_session(sp, OP_RSA);
+	return (ret);
+	}
+
+#define	MAXATTR	1024
+/*
+ * Load RSA private key from a file or get its PKCS#11 handle if stored in the
+ * PKCS#11 token.
+ */
+/* ARGSUSED */
+EVP_PKEY *pk11_load_privkey(ENGINE* e, const char *privkey_id,
+	UI_METHOD *ui_method, void *callback_data)
+	{
+	EVP_PKEY *pkey = NULL;
+	FILE *privkey;
+	CK_OBJECT_HANDLE  h_priv_key = CK_INVALID_HANDLE;
+	RSA *rsa = NULL;
+	PK11_SESSION *sp;
+	/* Anything else below is needed for the key by reference extension. */
+	const char *file;
+	int ret;
+	pkcs11_uri uri_struct;
+	CK_RV rv;
+	CK_BBOOL is_token = CK_TRUE;
+	CK_BBOOL rollback = CK_FALSE;
+	CK_BYTE attr_data[8][MAXATTR];
+	CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
+	CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;	/* key in keystore */
+
+	/* We look for private keys only. */
+	CK_ATTRIBUTE search_templ[] =
+		{
+		{CKA_TOKEN, &is_token, sizeof (is_token)},
+		{CKA_CLASS, &key_class, sizeof (key_class)},
+		{CKA_LABEL, NULL, 0}
+		};
+
+	/*
+	 * These public attributes are needed to initialize the OpenSSL RSA
+	 * structure with something we can use to look up the key. Note that we
+	 * never ask for private components.
+	 */
+	CK_ATTRIBUTE get_templ[] =
+		{
+		{CKA_MODULUS, (void *)attr_data[0], MAXATTR},		/* n */
+		{CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},	/* e */
+		};
+
+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
+		return (NULL);
+
+	/*
+	 * The next function will decide whether we are going to access keys in
+	 * the token or read them from plain files. It all depends on what is in
+	 * the 'privkey_id' parameter.
+	 */
+	ret = pk11_process_pkcs11_uri(privkey_id, &uri_struct, &file);
+
+	if (ret == 0)
+		goto err;
+
+	/* We will try to access a key from a PKCS#11 token. */
+	if (ret == 1)
+		{
+		if (pk11_check_token_attrs(&uri_struct) == 0)
+			goto err;
+
+		search_templ[2].pValue = uri_struct.object;
+		search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
+
+		if (pk11_token_login(sp->session, &pk11_login_done,
+		    &uri_struct, CK_TRUE) == 0)
+			goto err;
+
+		/*
+		 * Now let's try to find the key in the token. It is a failure
+		 * if we can't find it.
+		 */
+		if (find_one_object(OP_RSA, sp->session, search_templ, 3,
+		    &ks_key) == 0)
+			goto err;
+
+		/*
+		 * Free the structure now. Note that we use uri_struct's field
+		 * directly in the template so we cannot free it until the find
+		 * is done.
+		 */
+		pk11_free_pkcs11_uri(&uri_struct, 0);
+
+		/*
+		 * We might have a cache hit which we could confirm according to
+		 * the 'n'/'e' params, RSA public pointer as NULL, and non-NULL
+		 * RSA private pointer. However, it is easier just to recreate
+		 * everything. We expect the keys to be loaded once and used
+		 * many times. We do not check the return value because even in
+		 * case of failure the sp structure will have both key pointer
+		 * and object handle cleaned and pk11_destroy_object() reports
+		 * the failure to the OpenSSL error message buffer.
+		 */
+		(void) pk11_destroy_rsa_object_priv(sp, CK_TRUE);
+
+		sp->opdata_rsa_priv_key = ks_key;
+		/* This object shall not be deleted on a cache miss. */
+		sp->persistent = CK_TRUE;
+
+		if ((rsa = sp->opdata_rsa_priv = RSA_new_method(e)) == NULL)
+			goto err;
+
+		if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
+		    get_templ, 2)) != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_LOAD_PRIVKEY,
+			    PK11_R_GETATTRIBUTVALUE, rv);
+			goto err;
+			}
+
+		/*
+		 * Cache the RSA private structure pointer. We do not use it now
+		 * for key-by-ref keys but let's do it for consistency reasons.
+		 */
+		sp->opdata_rsa_priv = rsa;
+
+		/*
+		 * We do not use pk11_get_private_rsa_key() here so we must take
+		 * care of handle management ourselves.
+		 */
+		KEY_HANDLE_REFHOLD(ks_key, OP_RSA, CK_FALSE, rollback, err);
+
+		/*
+		 * Those are the sensitive components we do not want to export
+		 * from the token at all: rsa->(d|p|q|dmp1|dmq1|iqmp).
+		 */
+		attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
+		attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
+		/*
+		 * Must have 'n'/'e' components in the session structure as
+		 * well. They serve as a public look-up key for the private key
+		 * in the keystore.
+		 */
+		attr_to_BN(&get_templ[0], attr_data[0], &sp->opdata_rsa_n_num);
+		attr_to_BN(&get_templ[1], attr_data[1], &sp->opdata_rsa_e_num);
+
+		if ((pkey = EVP_PKEY_new()) == NULL)
+			goto err;
+
+		if (EVP_PKEY_set1_RSA(pkey, rsa) == 0)
+			goto err;
+		}
+	else
+		if ((privkey = fopen(file, read_mode_flags)) != NULL)
+			{
+			pkey = PEM_read_PrivateKey(privkey, NULL, NULL, NULL);
+			(void) fclose(privkey);
+			if (pkey != NULL)
+				{
+				rsa = EVP_PKEY_get1_RSA(pkey);
+				if (rsa != NULL)
+					{
+					(void) pk11_check_new_rsa_key_priv(sp,
+					    rsa);
+
+					h_priv_key = sp->opdata_rsa_priv_key =
+					    pk11_get_private_rsa_key(rsa, sp);
+					if (h_priv_key == CK_INVALID_HANDLE)
+						goto err;
+					}
+				else
+					goto err;
+				}
+			}
+
+	pk11_return_session(sp, OP_RSA);
+	return (pkey);
+err:
+	if (rsa != NULL)
+		RSA_free(rsa);
+	if (pkey != NULL)
+		{
+		EVP_PKEY_free(pkey);
+		pkey = NULL;
+		}
+	return (pkey);
+	}
+
+/* Load RSA public key from a file or load it from the PKCS#11 token. */
+/* ARGSUSED */
+EVP_PKEY *pk11_load_pubkey(ENGINE* e, const char *pubkey_id,
+	UI_METHOD *ui_method, void *callback_data)
+	{
+	EVP_PKEY *pkey = NULL;
+	FILE *pubkey;
+	CK_OBJECT_HANDLE  h_pub_key = CK_INVALID_HANDLE;
+	RSA *rsa = NULL;
+	PK11_SESSION *sp;
+	/* everything else below needed for key by reference extension */
+	int ret;
+	const char *file;
+	pkcs11_uri uri_struct;
+	CK_RV rv;
+	CK_BBOOL is_token = CK_TRUE;
+	CK_BYTE attr_data[2][MAXATTR];
+	CK_OBJECT_CLASS key_class = CKO_PUBLIC_KEY;
+	CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;	/* key in keystore */
+
+	CK_ATTRIBUTE search_templ[] =
+		{
+		{CKA_TOKEN, &is_token, sizeof (is_token)},
+		{CKA_CLASS, &key_class, sizeof (key_class)},
+		{CKA_LABEL, NULL, 0}
+		};
+
+	/*
+	 * These public attributes are needed to initialize OpenSSL RSA
+	 * structure with something we can use to look up the key.
+	 */
+	CK_ATTRIBUTE get_templ[] =
+		{
+		{CKA_MODULUS, (void *)attr_data[0], MAXATTR},		/* n */
+		{CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},	/* e */
+		};
+
+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
+		return (NULL);
+
+	ret = pk11_process_pkcs11_uri(pubkey_id, &uri_struct, &file);
+
+	if (ret == 0)
+		goto err;
+
+	if (ret == 1)
+		{
+		if (pk11_check_token_attrs(&uri_struct) == 0)
+			goto err;
+
+		search_templ[2].pValue = uri_struct.object;
+		search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
+
+		if (pk11_token_login(sp->session, &pk11_login_done,
+		    &uri_struct, CK_FALSE) == 0)
+			goto err;
+
+		if (find_one_object(OP_RSA, sp->session, search_templ, 3,
+		    &ks_key) == 0)
+			{
+			goto err;
+			}
+
+		/*
+		 * Free the structure now. Note that we use uri_struct's field
+		 * directly in the template so we can't free until find is done.
+		 */
+		pk11_free_pkcs11_uri(&uri_struct, 0);
+		/*
+		 * We load a new public key so we will create a new RSA
+		 * structure. No cache hit is possible.
+		 */
+		(void) pk11_destroy_rsa_object_pub(sp, CK_TRUE);
+		sp->opdata_rsa_pub_key = ks_key;
+
+		if ((rsa = sp->opdata_rsa_pub = RSA_new_method(e)) == NULL)
+			goto err;
+
+		if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
+		    get_templ, 2)) != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_LOAD_PUBKEY,
+			    PK11_R_GETATTRIBUTVALUE, rv);
+			goto err;
+			}
+
+		/*
+		 * Cache the RSA public structure pointer.
+		 */
+		sp->opdata_rsa_pub = rsa;
+
+		/*
+		 * These are the sensitive components we do not want to export
+		 * from the token at all: rsa->(d|p|q|dmp1|dmq1|iqmp).
+		 */
+		attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
+		attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
+
+		if ((pkey = EVP_PKEY_new()) == NULL)
+			goto err;
+
+		if (EVP_PKEY_set1_RSA(pkey, rsa) == 0)
+			goto err;
+
+		/*
+		 * Create a session object from it so that when calling
+		 * pk11_get_public_rsa_key() the next time, we can find it. The
+		 * reason why we do that is that we cannot tell from the RSA
+		 * structure (OpenSSL RSA structure does not have any room for
+		 * additional data used by the engine, for example) if it bears
+		 * a public key stored in the keystore or not so it's better if
+		 * we always have a session key. Note that this is different
+		 * from what we do for the private keystore objects but in that
+		 * case, we can tell from the RSA structure that the keystore
+		 * object is in play - the 'd' component is NULL in that case.
+		 */
+		h_pub_key = sp->opdata_rsa_pub_key =
+		    pk11_get_public_rsa_key(rsa, sp);
+		if (h_pub_key == CK_INVALID_HANDLE)
+			goto err;
+		}
+	else
+		if ((pubkey = fopen(file, read_mode_flags)) != NULL)
+			{
+			pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL);
+			(void) fclose(pubkey);
+			if (pkey != NULL)
+				{
+				rsa = EVP_PKEY_get1_RSA(pkey);
+				if (rsa != NULL)
+					{
+					/*
+					 * This will always destroy the RSA
+					 * object since we have a new RSA
+					 * structure here.
+					 */
+					(void) pk11_check_new_rsa_key_pub(sp,
+					    rsa);
+
+					h_pub_key = sp->opdata_rsa_pub_key =
+					    pk11_get_public_rsa_key(rsa, sp);
+					if (h_pub_key == CK_INVALID_HANDLE)
+						{
+						EVP_PKEY_free(pkey);
+						pkey = NULL;
+						}
+					}
+				else
+					{
+					EVP_PKEY_free(pkey);
+					pkey = NULL;
+					}
+				}
+			}
+
+	pk11_return_session(sp, OP_RSA);
+	return (pkey);
+err:
+	if (rsa != NULL)
+		RSA_free(rsa);
+	if (pkey != NULL)
+		{
+		EVP_PKEY_free(pkey);
+		pkey = NULL;
+		}
+	return (pkey);
+	}
+
+/*
+ * Get a public key object in a session from a given rsa structure. If the
+ * PKCS#11 session object already exists it is found, reused, and
+ * the counter in the active object list incremented. If not found, a new
+ * session object is created and put also onto the active object list.
+ *
+ * We use the session field from sp, and we cache rsa->(n|e) in
+ * opdata_rsa_(n|e|d)_num, respectively.
+ */
+static CK_OBJECT_HANDLE
+pk11_get_public_rsa_key(RSA* rsa, PK11_SESSION *sp)
+	{
+	CK_RV rv;
+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
+	CK_ULONG found;
+	CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
+	CK_KEY_TYPE k_type = CKK_RSA;
+	CK_ULONG ul_key_attr_count = 7;
+	CK_BBOOL rollback = CK_FALSE;
+
+	CK_ATTRIBUTE  a_key_template[] =
+		{
+		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
+		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
+		{CKA_TOKEN, &pk11_false, sizeof (pk11_false)},
+		{CKA_ENCRYPT, &pk11_true, sizeof (pk11_true)},
+		{CKA_VERIFY_RECOVER, &pk11_true, sizeof (pk11_true)},
+		{CKA_MODULUS, (void *)NULL, 0},
+		{CKA_PUBLIC_EXPONENT, (void *)NULL, 0}
+		};
+
+	int i;
+
+	a_key_template[0].pValue = &o_key;
+	a_key_template[1].pValue = &k_type;
+
+	a_key_template[5].ulValueLen = BN_num_bytes(rsa->n);
+	a_key_template[5].pValue = (CK_VOID_PTR)OPENSSL_malloc(
+		(size_t)a_key_template[5].ulValueLen);
+	if (a_key_template[5].pValue == NULL)
+		{
+		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
+		goto malloc_err;
+		}
+
+	BN_bn2bin(rsa->n, a_key_template[5].pValue);
+
+	a_key_template[6].ulValueLen = BN_num_bytes(rsa->e);
+	a_key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
+		(size_t)a_key_template[6].ulValueLen);
+	if (a_key_template[6].pValue == NULL)
+		{
+		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
+		goto malloc_err;
+		}
+
+	BN_bn2bin(rsa->e, a_key_template[6].pValue);
+
+	/* see find_lock array definition for more info on object locking */
+	LOCK_OBJSTORE(OP_RSA);
+
+	rv = pFuncList->C_FindObjectsInit(sp->session, a_key_template,
+		ul_key_attr_count);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
+		    PK11_R_FINDOBJECTSINIT, rv);
+		goto err;
+		}
+
+	rv = pFuncList->C_FindObjects(sp->session, &h_key, 1, &found);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
+		    PK11_R_FINDOBJECTS, rv);
+		goto err;
+		}
+
+	rv = pFuncList->C_FindObjectsFinal(sp->session);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
+		    PK11_R_FINDOBJECTSFINAL, rv);
+		goto err;
+		}
+
+	if (found == 0)
+		{
+		rv = pFuncList->C_CreateObject(sp->session,
+			a_key_template, ul_key_attr_count, &h_key);
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
+			    PK11_R_CREATEOBJECT, rv);
+			goto err;
+			}
+		}
+
+	if ((sp->opdata_rsa_n_num = BN_dup(rsa->n)) == NULL)
+		{
+		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
+		rollback = CK_TRUE;
+		goto err;
+		}
+
+	if ((sp->opdata_rsa_e_num = BN_dup(rsa->e)) == NULL)
+		{
+		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
+		BN_free(sp->opdata_rsa_n_num);
+		sp->opdata_rsa_n_num = NULL;
+		rollback = CK_TRUE;
+		goto err;
+		}
+
+	/* LINTED: E_CONSTANT_CONDITION */
+	KEY_HANDLE_REFHOLD(h_key, OP_RSA, CK_FALSE, rollback, err);
+	sp->opdata_rsa_pub = rsa;
+
+err:
+	if (rollback)
+		{
+		/*
+		 * We do not care about the return value from C_DestroyObject()
+		 * since we are doing rollback.
+		 */
+		if (found == 0)
+			(void) pFuncList->C_DestroyObject(sp->session, h_key);
+		h_key = CK_INVALID_HANDLE;
+		}
+
+	UNLOCK_OBJSTORE(OP_RSA);
+
+malloc_err:
+	for (i = 5; i <= 6; i++)
+		{
+		if (a_key_template[i].pValue != NULL)
+			{
+			OPENSSL_free(a_key_template[i].pValue);
+			a_key_template[i].pValue = NULL;
+			}
+		}
+
+	return (h_key);
+	}
+
+/*
+ * Function similar to pk11_get_public_rsa_key(). In addition to 'n' and 'e'
+ * components, it also caches 'd' if present. Note that if RSA keys by reference
+ * are used, 'd' is never extracted from the token in which case it would be
+ * NULL here.
+ */
+static CK_OBJECT_HANDLE
+pk11_get_private_rsa_key(RSA* rsa, PK11_SESSION *sp)
+	{
+	CK_RV rv;
+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
+	int i;
+	CK_ULONG found;
+	CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
+	CK_KEY_TYPE k_type = CKK_RSA;
+	CK_ULONG ul_key_attr_count = 14;
+	CK_BBOOL rollback = CK_FALSE;
+
+	/*
+	 * Both CKA_TOKEN and CKA_SENSITIVE have to be CK_FALSE for session keys
+	 */
+	CK_ATTRIBUTE  a_key_template[] =
+		{
+		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
+		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
+		{CKA_TOKEN, &pk11_false, sizeof (pk11_false)},
+		{CKA_SENSITIVE, &pk11_false, sizeof (pk11_false)},
+		{CKA_DECRYPT, &pk11_true, sizeof (pk11_true)},
+		{CKA_SIGN, &pk11_true, sizeof (pk11_true)},
+		{CKA_MODULUS, (void *)NULL, 0},
+		{CKA_PUBLIC_EXPONENT, (void *)NULL, 0},
+		{CKA_PRIVATE_EXPONENT, (void *)NULL, 0},
+		{CKA_PRIME_1, (void *)NULL, 0},
+		{CKA_PRIME_2, (void *)NULL, 0},
+		{CKA_EXPONENT_1, (void *)NULL, 0},
+		{CKA_EXPONENT_2, (void *)NULL, 0},
+		{CKA_COEFFICIENT, (void *)NULL, 0},
+		};
+
+	a_key_template[0].pValue = &o_key;
+	a_key_template[1].pValue = &k_type;
+
+	/* Put the private key components into the template */
+	if (init_template_value(rsa->n, &a_key_template[6].pValue,
+		&a_key_template[6].ulValueLen) == 0 ||
+	    init_template_value(rsa->e, &a_key_template[7].pValue,
+		&a_key_template[7].ulValueLen) == 0 ||
+	    init_template_value(rsa->d, &a_key_template[8].pValue,
+		&a_key_template[8].ulValueLen) == 0 ||
+	    init_template_value(rsa->p, &a_key_template[9].pValue,
+		&a_key_template[9].ulValueLen) == 0 ||
+	    init_template_value(rsa->q, &a_key_template[10].pValue,
+		&a_key_template[10].ulValueLen) == 0 ||
+	    init_template_value(rsa->dmp1, &a_key_template[11].pValue,
+		&a_key_template[11].ulValueLen) == 0 ||
+	    init_template_value(rsa->dmq1, &a_key_template[12].pValue,
+		&a_key_template[12].ulValueLen) == 0 ||
+	    init_template_value(rsa->iqmp, &a_key_template[13].pValue,
+		&a_key_template[13].ulValueLen) == 0)
+		{
+		PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
+		goto malloc_err;
+		}
+
+	/* see find_lock array definition for more info on object locking */
+	LOCK_OBJSTORE(OP_RSA);
+
+	/*
+	 * We are getting the private key but the private 'd' component is NULL.
+	 * That means this is key by reference RSA key. In that case, we can
+	 * use only public components for searching for the private key handle.
+	 */
+	if (rsa->d == NULL)
+		{
+		ul_key_attr_count = 8;
+		/*
+		 * We will perform the search in the token, not in the existing
+		 * session keys.
+		 */
+		a_key_template[2].pValue = &pk11_true;
+		}
+
+	rv = pFuncList->C_FindObjectsInit(sp->session, a_key_template,
+		ul_key_attr_count);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
+		    PK11_R_FINDOBJECTSINIT, rv);
+		goto err;
+		}
+
+	rv = pFuncList->C_FindObjects(sp->session, &h_key, 1, &found);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
+		    PK11_R_FINDOBJECTS, rv);
+		goto err;
+		}
+
+	rv = pFuncList->C_FindObjectsFinal(sp->session);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
+		    PK11_R_FINDOBJECTSFINAL, rv);
+		goto err;
+		}
+
+	if (found == 0)
+		{
+		/*
+		 * We have an RSA structure with 'n'/'e' components only so we
+		 * tried to find the private key in the keystore. If it was
+		 * really a token key we have a problem. Note that for other key
+		 * types we just create a new session key using the private
+		 * components from the RSA structure.
+		 */
+		if (rsa->d == NULL)
+			{
+			PK11err(PK11_F_GET_PRIV_RSA_KEY,
+			    PK11_R_PRIV_KEY_NOT_FOUND);
+			goto err;
+			}
+
+		rv = pFuncList->C_CreateObject(sp->session,
+			a_key_template, ul_key_attr_count, &h_key);
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
+				PK11_R_CREATEOBJECT, rv);
+			goto err;
+			}
+		}
+
+	/*
+	 * When RSA keys by reference code is used, we never extract private
+	 * components from the keystore. In that case 'd' was set to NULL and we
+	 * expect the application to properly cope with that. It is documented
+	 * in openssl(5). In general, if keys by reference are used we expect it
+	 * to be used exclusively using the high level API and then there is no
+	 * problem. If the application expects the private components to be read
+	 * from the keystore then that is not a supported way of usage.
+	 */
+	if (rsa->d != NULL)
+		{
+		if ((sp->opdata_rsa_d_num = BN_dup(rsa->d)) == NULL)
+			{
+			PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
+			rollback = CK_TRUE;
+			goto err;
+			}
+		}
+	else
+		sp->opdata_rsa_d_num = NULL;
+
+	/*
+	 * For the key by reference code, we need public components as well
+	 * since 'd' component is always NULL. For that reason, we always cache
+	 * 'n'/'e' components as well.
+	 */
+	if ((sp->opdata_rsa_n_num = BN_dup(rsa->n)) == NULL)
+		{
+		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
+		sp->opdata_rsa_n_num = NULL;
+		rollback = CK_TRUE;
+		goto err;
+		}
+	if ((sp->opdata_rsa_e_num = BN_dup(rsa->e)) == NULL)
+		{
+		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
+		BN_free(sp->opdata_rsa_n_num);
+		sp->opdata_rsa_n_num = NULL;
+		rollback = CK_TRUE;
+		goto err;
+		}
+
+	/* LINTED: E_CONSTANT_CONDITION */
+	KEY_HANDLE_REFHOLD(h_key, OP_RSA, CK_FALSE, rollback, err);
+	sp->opdata_rsa_priv = rsa;
+
+err:
+	if (rollback)
+		{
+		/*
+		 * We do not care about the return value from C_DestroyObject()
+		 * since we are doing rollback.
+		 */
+		if (found == 0)
+			(void) pFuncList->C_DestroyObject(sp->session, h_key);
+		h_key = CK_INVALID_HANDLE;
+		}
+
+	UNLOCK_OBJSTORE(OP_RSA);
+
+malloc_err:
+	/*
+	 * 6 to 13 entries in the key template are key components.
+	 * They need to be freed upon exit or error.
+	 */
+	for (i = 6; i <= 13; i++)
+		{
+		if (a_key_template[i].pValue != NULL)
+			{
+			(void) memset(a_key_template[i].pValue, 0,
+				a_key_template[i].ulValueLen);
+			OPENSSL_free(a_key_template[i].pValue);
+			a_key_template[i].pValue = NULL;
+			}
+		}
+
+	return (h_key);
+	}
+
+/*
+ * Check for cache miss. Objects are cleaned only if we have a full cache miss,
+ * meaning that it's a different RSA key pair. Return 1 for cache hit, 0 for
+ * cache miss.
+ */
+static int
+pk11_check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa)
+	{
+	/*
+	 * Provide protection against RSA structure reuse by making the
+	 * check for cache hit stronger. Only public components of RSA
+	 * key matter here so it is sufficient to compare them with values
+	 * cached in PK11_SESSION structure.
+	 *
+	 * We must check the handle as well since with key by reference, public
+	 * components 'n'/'e' are cached in private keys as well. That means we
+	 * could have a cache hit in a private key when looking for a public
+	 * key. That would not work, you cannot have one PKCS#11 object for
+	 * both data signing and verifying.
+	 */
+	if (sp->opdata_rsa_pub == rsa &&
+	    BN_cmp(sp->opdata_rsa_n_num, rsa->n) == 0 &&
+	    BN_cmp(sp->opdata_rsa_e_num, rsa->e) == 0)
+		{
+		if (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE)
+			return (1);
+		else
+			/*
+			 * No public key object yet but we have the right RSA
+			 * structure with potentially existing private key
+			 * object. We can just create a public object and move
+			 * on with this session structure.
+			 */
+			return (0);
+		}
+
+	/*
+	 * A different RSA key pair was using this session structure previously
+	 * or it's an empty structure. Destroy what we can.
+	 */
+	(void) pk11_destroy_rsa_object_pub(sp, CK_TRUE);
+	(void) pk11_destroy_rsa_object_priv(sp, CK_TRUE);
+	return (0);
+	}
+
+/*
+ * Check for cache miss. Objects are cleaned only if we have a full cache miss,
+ * meaning that it's a different RSA key pair. Return 1 for cache hit, 0 for
+ * cache miss.
+ */
+static int
+pk11_check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa)
+	{
+	/*
+	 * Provide protection against RSA structure reuse by making the
+	 * check for cache hit stronger. Comparing public exponent of RSA
+	 * key with value cached in PK11_SESSION structure should
+	 * be sufficient. Note that we want to compare the public component
+	 * since with the keys by reference mechanism, private components are
+	 * not in the RSA structure. Also, see pk11_check_new_rsa_key_pub()
+	 * about why we compare the handle as well.
+	 */
+	if (sp->opdata_rsa_priv == rsa &&
+	    BN_cmp(sp->opdata_rsa_n_num, rsa->n) == 0 &&
+	    BN_cmp(sp->opdata_rsa_e_num, rsa->e) == 0)
+		{
+		if (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE)
+			return (1);
+		else
+			/*
+			 * No private key object yet but we have the right RSA
+			 * structure with potentially existing public key
+			 * object. We can just create a private object and move
+			 * on with this session structure.
+			 */
+			return (0);
+		}
+
+	/*
+	 * A different RSA key pair was using this session structure previously
+	 * or it's an empty structure. Destroy what we can.
+	 */
+	(void) pk11_destroy_rsa_object_priv(sp, CK_TRUE);
+	(void) pk11_destroy_rsa_object_pub(sp, CK_TRUE);
+	return (0);
+	}
+#endif
+
+#ifndef OPENSSL_NO_DSA
+/* The DSA function implementation */
+/* ARGSUSED */
+static int pk11_DSA_init(DSA *dsa)
+	{
+	return (1);
+	}
+
+/* ARGSUSED */
+static int pk11_DSA_finish(DSA *dsa)
+	{
+	return (1);
+	}
+
+
+static DSA_SIG *
+pk11_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
+	{
+	BIGNUM *r = NULL, *s = NULL;
+	int i;
+	DSA_SIG *dsa_sig = NULL;
+
+	CK_RV rv;
+	CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
+	CK_MECHANISM *p_mech = &Mechanism_dsa;
+	CK_OBJECT_HANDLE h_priv_key;
+
+	/*
+	 * The signature is the concatenation of r and s,
+	 * each is 20 bytes long
+	 */
+	unsigned char sigret[DSA_SIGNATURE_LEN];
+	unsigned long siglen = DSA_SIGNATURE_LEN;
+	unsigned int siglen2 = DSA_SIGNATURE_LEN / 2;
+
+	PK11_SESSION *sp = NULL;
+
+	if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
+		{
+		PK11err(PK11_F_DSA_SIGN, PK11_R_MISSING_KEY_COMPONENT);
+		goto ret;
+		}
+
+	i = BN_num_bytes(dsa->q); /* should be 20 */
+	if (dlen > i)
+		{
+		PK11err(PK11_F_DSA_SIGN, PK11_R_INVALID_SIGNATURE_LENGTH);
+		goto ret;
+		}
+
+	if ((sp = pk11_get_session(OP_DSA)) == NULL)
+		goto ret;
+
+	(void) check_new_dsa_key_priv(sp, dsa);
+
+	h_priv_key = sp->opdata_dsa_priv_key;
+	if (h_priv_key == CK_INVALID_HANDLE)
+		h_priv_key = sp->opdata_dsa_priv_key =
+			pk11_get_private_dsa_key((DSA *)dsa,
+			    &sp->opdata_dsa_priv,
+			    &sp->opdata_dsa_priv_num, sp->session);
+
+	if (h_priv_key != CK_INVALID_HANDLE)
+		{
+		rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
+
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGNINIT, rv);
+			goto ret;
+			}
+
+			(void) memset(sigret, 0, siglen);
+			rv = pFuncList->C_Sign(sp->session,
+			    (unsigned char *) dgst, dlen, sigret,
+			    (CK_ULONG_PTR) &siglen);
+
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGN, rv);
+			goto ret;
+			}
+		}
+
+
+	if ((s = BN_new()) == NULL)
+		{
+		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
+		goto ret;
+		}
+
+	if ((r = BN_new()) == NULL)
+		{
+		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
+		goto ret;
+		}
+
+	if ((dsa_sig = DSA_SIG_new()) == NULL)
+		{
+		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
+		goto ret;
+		}
+
+	if (BN_bin2bn(sigret, siglen2, r) == NULL ||
+	    BN_bin2bn(&sigret[siglen2], siglen2, s) == NULL)
+		{
+		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
+		goto ret;
+		}
+
+	dsa_sig->r = r;
+	dsa_sig->s = s;
+
+ret:
+	if (dsa_sig == NULL)
+		{
+		if (r != NULL)
+			BN_free(r);
+		if (s != NULL)
+			BN_free(s);
+		}
+
+	pk11_return_session(sp, OP_DSA);
+	return (dsa_sig);
+	}
+
+static int
+pk11_dsa_do_verify(const unsigned char *dgst, int dlen, DSA_SIG *sig,
+	DSA *dsa)
+	{
+	int i;
+	CK_RV rv;
+	int retval = 0;
+	CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
+	CK_MECHANISM *p_mech = &Mechanism_dsa;
+	CK_OBJECT_HANDLE h_pub_key;
+
+	unsigned char sigbuf[DSA_SIGNATURE_LEN];
+	unsigned long siglen = DSA_SIGNATURE_LEN;
+	unsigned long siglen2 = DSA_SIGNATURE_LEN/2;
+
+	PK11_SESSION *sp = NULL;
+
+	if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0)
+		{
+		PK11err(PK11_F_DSA_VERIFY,
+			PK11_R_INVALID_DSA_SIGNATURE_R);
+		goto ret;
+		}
+
+	if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0)
+		{
+		PK11err(PK11_F_DSA_VERIFY,
+			PK11_R_INVALID_DSA_SIGNATURE_S);
+		goto ret;
+		}
+
+	i = BN_num_bytes(dsa->q); /* should be 20 */
+
+	if (dlen > i)
+		{
+		PK11err(PK11_F_DSA_VERIFY,
+			PK11_R_INVALID_SIGNATURE_LENGTH);
+		goto ret;
+		}
+
+	if ((sp = pk11_get_session(OP_DSA)) == NULL)
+		goto ret;
+
+	(void) check_new_dsa_key_pub(sp, dsa);
+
+	h_pub_key = sp->opdata_dsa_pub_key;
+	if (h_pub_key == CK_INVALID_HANDLE)
+		h_pub_key = sp->opdata_dsa_pub_key =
+			pk11_get_public_dsa_key((DSA *)dsa, &sp->opdata_dsa_pub,
+			    &sp->opdata_dsa_pub_num, sp->session);
+
+	if (h_pub_key != CK_INVALID_HANDLE)
+		{
+		rv = pFuncList->C_VerifyInit(sp->session, p_mech,
+			h_pub_key);
+
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFYINIT,
+			    rv);
+			goto ret;
+			}
+
+		/*
+		 * The representation of each of the two big numbers could
+		 * be shorter than DSA_SIGNATURE_LEN/2 bytes so we need
+		 * to act accordingly and shift if necessary.
+		 */
+		(void) memset(sigbuf, 0, siglen);
+		BN_bn2bin(sig->r, sigbuf + siglen2 - BN_num_bytes(sig->r));
+		BN_bn2bin(sig->s, &sigbuf[siglen2] + siglen2 -
+		    BN_num_bytes(sig->s));
+
+		rv = pFuncList->C_Verify(sp->session,
+			(unsigned char *) dgst, dlen, sigbuf, (CK_ULONG)siglen);
+
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFY, rv);
+			goto ret;
+			}
+		}
+
+	retval = 1;
+ret:
+
+	pk11_return_session(sp, OP_DSA);
+	return (retval);
+	}
+
+
+/*
+ * Create a public key object in a session from a given dsa structure.
+ * The *dsa_pub_num pointer is non-NULL for DSA public keys.
+ */
+static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa,
+    DSA **key_ptr, BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session)
+	{
+	CK_RV rv;
+	CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
+	CK_ULONG found;
+	CK_KEY_TYPE k_type = CKK_DSA;
+	CK_ULONG ul_key_attr_count = 8;
+	CK_BBOOL rollback = CK_FALSE;
+	int i;
+
+	CK_ATTRIBUTE  a_key_template[] =
+		{
+		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
+		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
+		{CKA_TOKEN, &pk11_false, sizeof (pk11_false)},
+		{CKA_VERIFY, &pk11_true, sizeof (pk11_true)},
+		{CKA_PRIME, (void *)NULL, 0},		/* p */
+		{CKA_SUBPRIME, (void *)NULL, 0},	/* q */
+		{CKA_BASE, (void *)NULL, 0},		/* g */
+		{CKA_VALUE, (void *)NULL, 0}		/* pub_key - y */
+		};
+
+	a_key_template[0].pValue = &o_key;
+	a_key_template[1].pValue = &k_type;
+
+	if (init_template_value(dsa->p, &a_key_template[4].pValue,
+		&a_key_template[4].ulValueLen) == 0 ||
+	    init_template_value(dsa->q, &a_key_template[5].pValue,
+		&a_key_template[5].ulValueLen) == 0 ||
+	    init_template_value(dsa->g, &a_key_template[6].pValue,
+		&a_key_template[6].ulValueLen) == 0 ||
+	    init_template_value(dsa->pub_key, &a_key_template[7].pValue,
+		&a_key_template[7].ulValueLen) == 0)
+		{
+		PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
+		goto malloc_err;
+		}
+
+	/* see find_lock array definition for more info on object locking */
+	LOCK_OBJSTORE(OP_DSA);
+	rv = pFuncList->C_FindObjectsInit(session, a_key_template,
+		ul_key_attr_count);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
+		    PK11_R_FINDOBJECTSINIT, rv);
+		goto err;
+		}
+
+	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
+		    PK11_R_FINDOBJECTS, rv);
+		goto err;
+		}
+
+	rv = pFuncList->C_FindObjectsFinal(session);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
+		    PK11_R_FINDOBJECTSFINAL, rv);
+		goto err;
+		}
+
+	if (found == 0)
+		{
+		rv = pFuncList->C_CreateObject(session,
+			a_key_template, ul_key_attr_count, &h_key);
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
+			    PK11_R_CREATEOBJECT, rv);
+			goto err;
+			}
+		}
+
+	if (dsa_pub_num != NULL)
+		if ((*dsa_pub_num = BN_dup(dsa->pub_key)) == NULL)
+			{
+			PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
+			rollback = CK_TRUE;
+			goto err;
+			}
+
+	/* LINTED: E_CONSTANT_CONDITION */
+	KEY_HANDLE_REFHOLD(h_key, OP_DSA, CK_FALSE, rollback, err);
+	if (key_ptr != NULL)
+		*key_ptr = dsa;
+
+err:
+	if (rollback)
+		{
+		/*
+		 * We do not care about the return value from C_DestroyObject()
+		 * since we are doing rollback.
+		 */
+		if (found == 0)
+			(void) pFuncList->C_DestroyObject(session, h_key);
+		h_key = CK_INVALID_HANDLE;
+		}
+
+	UNLOCK_OBJSTORE(OP_DSA);
+
+malloc_err:
+	for (i = 4; i <= 7; i++)
+		{
+		if (a_key_template[i].pValue != NULL)
+			{
+			OPENSSL_free(a_key_template[i].pValue);
+			a_key_template[i].pValue = NULL;
+			}
+		}
+
+	return (h_key);
+	}
+
+/*
+ * Create a private key object in the session from a given dsa structure
+ * The *dsa_priv_num pointer is non-NULL for DSA private keys.
+ */
+static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa,
+    DSA **key_ptr, BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session)
+	{
+	CK_RV rv;
+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
+	CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
+	int i;
+	CK_ULONG found;
+	CK_KEY_TYPE k_type = CKK_DSA;
+	CK_ULONG ul_key_attr_count = 9;
+	CK_BBOOL rollback = CK_FALSE;
+
+	/*
+	 * Both CKA_TOKEN and CKA_SENSITIVE have to be CK_FALSE for session keys
+	 */
+	CK_ATTRIBUTE  a_key_template[] =
+		{
+		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
+		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
+		{CKA_TOKEN, &pk11_false, sizeof (pk11_false)},
+		{CKA_SENSITIVE, &pk11_false, sizeof (pk11_false)},
+		{CKA_SIGN, &pk11_true, sizeof (pk11_true)},
+		{CKA_PRIME, (void *)NULL, 0},		/* p */
+		{CKA_SUBPRIME, (void *)NULL, 0},	/* q */
+		{CKA_BASE, (void *)NULL, 0},		/* g */
+		{CKA_VALUE, (void *)NULL, 0}		/* priv_key - x */
+		};
+
+	a_key_template[0].pValue = &o_key;
+	a_key_template[1].pValue = &k_type;
+
+	/* Put the private key components into the template */
+	if (init_template_value(dsa->p, &a_key_template[5].pValue,
+		&a_key_template[5].ulValueLen) == 0 ||
+	    init_template_value(dsa->q, &a_key_template[6].pValue,
+		&a_key_template[6].ulValueLen) == 0 ||
+	    init_template_value(dsa->g, &a_key_template[7].pValue,
+		&a_key_template[7].ulValueLen) == 0 ||
+	    init_template_value(dsa->priv_key, &a_key_template[8].pValue,
+		&a_key_template[8].ulValueLen) == 0)
+		{
+		PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
+		goto malloc_err;
+		}
+
+	/* see find_lock array definition for more info on object locking */
+	LOCK_OBJSTORE(OP_DSA);
+	rv = pFuncList->C_FindObjectsInit(session, a_key_template,
+		ul_key_attr_count);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
+		    PK11_R_FINDOBJECTSINIT, rv);
+		goto err;
+		}
+
+	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
+		    PK11_R_FINDOBJECTS, rv);
+		goto err;
+		}
+
+	rv = pFuncList->C_FindObjectsFinal(session);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
+		    PK11_R_FINDOBJECTSFINAL, rv);
+		goto err;
+		}
+
+	if (found == 0)
+		{
+		rv = pFuncList->C_CreateObject(session,
+			a_key_template, ul_key_attr_count, &h_key);
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
+			    PK11_R_CREATEOBJECT, rv);
+			goto err;
+			}
+		}
+
+	if (dsa_priv_num != NULL)
+		if ((*dsa_priv_num = BN_dup(dsa->priv_key)) == NULL)
+			{
+			PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
+			rollback = CK_TRUE;
+			goto err;
+			}
+
+	/* LINTED: E_CONSTANT_CONDITION */
+	KEY_HANDLE_REFHOLD(h_key, OP_DSA, CK_FALSE, rollback, err);
+	if (key_ptr != NULL)
+		*key_ptr = dsa;
+
+err:
+	if (rollback)
+		{
+		/*
+		 * We do not care about the return value from C_DestroyObject()
+		 * since we are doing rollback.
+		 */
+		if (found == 0)
+			(void) pFuncList->C_DestroyObject(session, h_key);
+		h_key = CK_INVALID_HANDLE;
+		}
+
+	UNLOCK_OBJSTORE(OP_DSA);
+
+malloc_err:
+	/*
+	 * 5 to 8 entries in the key template are key components.
+	 * They need to be freed apon exit or error.
+	 */
+	for (i = 5; i <= 8; i++)
+		{
+		if (a_key_template[i].pValue != NULL)
+			{
+			(void) memset(a_key_template[i].pValue, 0,
+				a_key_template[i].ulValueLen);
+			OPENSSL_free(a_key_template[i].pValue);
+			a_key_template[i].pValue = NULL;
+			}
+		}
+
+	return (h_key);
+	}
+
+/*
+ * Check for cache miss and clean the object pointer and handle
+ * in such case. Return 1 for cache hit, 0 for cache miss.
+ */
+static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa)
+	{
+	/*
+	 * Provide protection against DSA structure reuse by making the
+	 * check for cache hit stronger. Only public key component of DSA
+	 * key matters here so it is sufficient to compare it with value
+	 * cached in PK11_SESSION structure.
+	 */
+	if ((sp->opdata_dsa_pub != dsa) ||
+	    (BN_cmp(sp->opdata_dsa_pub_num, dsa->pub_key) != 0))
+		{
+		/*
+		 * We do not check the return value because even in case of
+		 * failure the sp structure will have both key pointer
+		 * and object handle cleaned and pk11_destroy_object()
+		 * reports the failure to the OpenSSL error message buffer.
+		 */
+		(void) pk11_destroy_dsa_object_pub(sp, CK_TRUE);
+		return (0);
+		}
+	return (1);
+	}
+
+/*
+ * Check for cache miss and clean the object pointer and handle
+ * in such case. Return 1 for cache hit, 0 for cache miss.
+ */
+static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa)
+	{
+	/*
+	 * Provide protection against DSA structure reuse by making the
+	 * check for cache hit stronger. Only private key component of DSA
+	 * key matters here so it is sufficient to compare it with value
+	 * cached in PK11_SESSION structure.
+	 */
+	if ((sp->opdata_dsa_priv != dsa) ||
+	    (BN_cmp(sp->opdata_dsa_priv_num, dsa->priv_key) != 0))
+		{
+		/*
+		 * We do not check the return value because even in case of
+		 * failure the sp structure will have both key pointer
+		 * and object handle cleaned and pk11_destroy_object()
+		 * reports the failure to the OpenSSL error message buffer.
+		 */
+		(void) pk11_destroy_dsa_object_priv(sp, CK_TRUE);
+		return (0);
+		}
+	return (1);
+	}
+#endif
+
+
+#ifndef OPENSSL_NO_DH
+/* The DH function implementation */
+/* ARGSUSED */
+static int pk11_DH_init(DH *dh)
+	{
+	return (1);
+	}
+
+/* ARGSUSED */
+static int pk11_DH_finish(DH *dh)
+	{
+	return (1);
+	}
+
+/*
+ * Generate DH key-pair.
+ *
+ * Warning: Unlike OpenSSL's DH_generate_key(3) we ignore dh->priv_key
+ * and override it even if it is set. OpenSSL does not touch dh->priv_key
+ * if set and just computes dh->pub_key. It looks like PKCS#11 standard
+ * is not capable of providing this functionality. This could be a problem
+ * for applications relying on OpenSSL's semantics.
+ */
+static int pk11_DH_generate_key(DH *dh)
+	{
+	CK_ULONG i;
+	CK_RV rv, rv1;
+	int reuse_mem_len = 0, ret = 0;
+	PK11_SESSION *sp = NULL;
+	CK_BYTE_PTR reuse_mem;
+
+	CK_MECHANISM mechanism = {CKM_DH_PKCS_KEY_PAIR_GEN, NULL_PTR, 0};
+	CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
+	CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
+
+	CK_ULONG ul_pub_key_attr_count = 3;
+	CK_ATTRIBUTE pub_key_template[] =
+		{
+		{CKA_PRIVATE, &pk11_false, sizeof (pk11_false)},
+		{CKA_PRIME, (void *)NULL, 0},
+		{CKA_BASE, (void *)NULL, 0}
+		};
+
+	CK_ULONG ul_priv_key_attr_count = 3;
+	CK_ATTRIBUTE priv_key_template[] =
+		{
+		{CKA_PRIVATE, &pk11_false, sizeof (pk11_false)},
+		{CKA_SENSITIVE, &pk11_false, sizeof (pk11_false)},
+		{CKA_DERIVE, &pk11_true, sizeof (pk11_true)}
+		};
+
+	CK_ULONG pub_key_attr_result_count = 1;
+	CK_ATTRIBUTE pub_key_result[] =
+		{
+		{CKA_VALUE, (void *)NULL, 0}
+		};
+
+	CK_ULONG priv_key_attr_result_count = 1;
+	CK_ATTRIBUTE priv_key_result[] =
+		{
+		{CKA_VALUE, (void *)NULL, 0}
+		};
+
+	pub_key_template[1].ulValueLen = BN_num_bytes(dh->p);
+	if (pub_key_template[1].ulValueLen > 0)
+		{
+		/*
+		 * We must not increase ulValueLen by DH_BUF_RESERVE since that
+		 * could cause the same rounding problem. See definition of
+		 * DH_BUF_RESERVE above.
+		 */
+		pub_key_template[1].pValue =
+			OPENSSL_malloc(pub_key_template[1].ulValueLen +
+			DH_BUF_RESERVE);
+		if (pub_key_template[1].pValue == NULL)
+			{
+			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
+			goto err;
+			}
+
+		i = BN_bn2bin(dh->p, pub_key_template[1].pValue);
+		}
+	else
+		goto err;
+
+	pub_key_template[2].ulValueLen = BN_num_bytes(dh->g);
+	if (pub_key_template[2].ulValueLen > 0)
+		{
+		pub_key_template[2].pValue =
+			OPENSSL_malloc(pub_key_template[2].ulValueLen +
+			DH_BUF_RESERVE);
+		if (pub_key_template[2].pValue == NULL)
+			{
+			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
+			goto err;
+			}
+
+		i = BN_bn2bin(dh->g, pub_key_template[2].pValue);
+		}
+	else
+		goto err;
+
+	/*
+	 * Note: we are only using PK11_SESSION structure for getting
+	 *	 a session handle. The objects created in this function are
+	 *	 destroyed before return and thus not cached.
+	 */
+	if ((sp = pk11_get_session(OP_DH)) == NULL)
+		goto err;
+
+	rv = pFuncList->C_GenerateKeyPair(sp->session,
+	    &mechanism,
+	    pub_key_template,
+	    ul_pub_key_attr_count,
+	    priv_key_template,
+	    ul_priv_key_attr_count,
+	    &h_pub_key,
+	    &h_priv_key);
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_DH_GEN_KEY, PK11_R_GEN_KEY, rv);
+		goto err;
+		}
+
+	/*
+	 * Reuse the larger memory allocated. We know the larger memory
+	 * should be sufficient for reuse.
+	 */
+	if (pub_key_template[1].ulValueLen > pub_key_template[2].ulValueLen)
+		{
+		reuse_mem = pub_key_template[1].pValue;
+		reuse_mem_len = pub_key_template[1].ulValueLen + DH_BUF_RESERVE;
+		}
+	else
+		{
+		reuse_mem = pub_key_template[2].pValue;
+		reuse_mem_len = pub_key_template[2].ulValueLen + DH_BUF_RESERVE;
+		}
+
+	rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
+		pub_key_result, pub_key_attr_result_count);
+	rv1 = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
+		priv_key_result, priv_key_attr_result_count);
+
+	if (rv != CKR_OK || rv1 != CKR_OK)
+		{
+		rv = (rv != CKR_OK) ? rv : rv1;
+		PK11err_add_data(PK11_F_DH_GEN_KEY,
+		    PK11_R_GETATTRIBUTVALUE, rv);
+		goto err;
+		}
+
+	if (((CK_LONG) pub_key_result[0].ulValueLen) <= 0 ||
+		((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
+		{
+		PK11err(PK11_F_DH_GEN_KEY, PK11_R_GETATTRIBUTVALUE);
+		goto err;
+		}
+
+	/* Reuse the memory allocated */
+	pub_key_result[0].pValue = reuse_mem;
+	pub_key_result[0].ulValueLen = reuse_mem_len;
+
+	rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
+		pub_key_result, pub_key_attr_result_count);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_DH_GEN_KEY,
+		    PK11_R_GETATTRIBUTVALUE, rv);
+		goto err;
+		}
+
+	if (pub_key_result[0].type == CKA_VALUE)
+		{
+		if (dh->pub_key == NULL)
+			if ((dh->pub_key = BN_new()) == NULL)
+				{
+				PK11err(PK11_F_DH_GEN_KEY,
+					PK11_R_MALLOC_FAILURE);
+				goto err;
+				}
+		dh->pub_key = BN_bin2bn(pub_key_result[0].pValue,
+			pub_key_result[0].ulValueLen, dh->pub_key);
+		if (dh->pub_key == NULL)
+			{
+			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
+			goto err;
+			}
+		}
+
+	/* Reuse the memory allocated */
+	priv_key_result[0].pValue = reuse_mem;
+	priv_key_result[0].ulValueLen = reuse_mem_len;
+
+	rv = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
+		priv_key_result, priv_key_attr_result_count);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_DH_GEN_KEY,
+		    PK11_R_GETATTRIBUTVALUE, rv);
+		goto err;
+		}
+
+	if (priv_key_result[0].type == CKA_VALUE)
+		{
+		if (dh->priv_key == NULL)
+			if ((dh->priv_key = BN_new()) == NULL)
+				{
+				PK11err(PK11_F_DH_GEN_KEY,
+					PK11_R_MALLOC_FAILURE);
+				goto err;
+				}
+		dh->priv_key = BN_bin2bn(priv_key_result[0].pValue,
+			priv_key_result[0].ulValueLen, dh->priv_key);
+		if (dh->priv_key == NULL)
+			{
+			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
+			goto err;
+			}
+		}
+
+	ret = 1;
+
+err:
+
+	if (h_pub_key != CK_INVALID_HANDLE)
+		{
+		rv = pFuncList->C_DestroyObject(sp->session, h_pub_key);
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_DH_GEN_KEY,
+			    PK11_R_DESTROYOBJECT, rv);
+			}
+		}
+
+	if (h_priv_key != CK_INVALID_HANDLE)
+		{
+		rv = pFuncList->C_DestroyObject(sp->session, h_priv_key);
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_DH_GEN_KEY,
+			    PK11_R_DESTROYOBJECT, rv);
+			}
+		}
+
+	for (i = 1; i <= 2; i++)
+		{
+		if (pub_key_template[i].pValue != NULL)
+			{
+			OPENSSL_free(pub_key_template[i].pValue);
+			pub_key_template[i].pValue = NULL;
+			}
+		}
+
+	pk11_return_session(sp, OP_DH);
+	return (ret);
+	}
+
+static int pk11_DH_compute_key(unsigned char *key, const BIGNUM *pub_key,
+	DH *dh)
+	{
+	int i;
+	CK_MECHANISM mechanism = {CKM_DH_PKCS_DERIVE, NULL_PTR, 0};
+	CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
+	CK_KEY_TYPE key_type = CKK_GENERIC_SECRET;
+	CK_OBJECT_HANDLE h_derived_key = CK_INVALID_HANDLE;
+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
+
+	CK_ULONG ul_priv_key_attr_count = 2;
+	CK_ATTRIBUTE priv_key_template[] =
+		{
+		{CKA_CLASS, (void*) NULL, sizeof (key_class)},
+		{CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
+		};
+
+	CK_ULONG priv_key_attr_result_count = 1;
+	CK_ATTRIBUTE priv_key_result[] =
+		{
+		{CKA_VALUE, (void *)NULL, 0}
+		};
+
+	CK_RV rv;
+	int ret = -1;
+	PK11_SESSION *sp = NULL;
+
+	if (dh->priv_key == NULL)
+		goto err;
+
+	priv_key_template[0].pValue = &key_class;
+	priv_key_template[1].pValue = &key_type;
+
+	if ((sp = pk11_get_session(OP_DH)) == NULL)
+		goto err;
+
+	mechanism.ulParameterLen = BN_num_bytes(pub_key);
+	mechanism.pParameter = OPENSSL_malloc(mechanism.ulParameterLen);
+	if (mechanism.pParameter == NULL)
+		{
+		PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
+		goto err;
+		}
+	BN_bn2bin(pub_key, mechanism.pParameter);
+
+	(void) check_new_dh_key(sp, dh);
+
+	h_key = sp->opdata_dh_key;
+	if (h_key == CK_INVALID_HANDLE)
+		h_key = sp->opdata_dh_key =
+			pk11_get_dh_key((DH*) dh, &sp->opdata_dh,
+			    &sp->opdata_dh_priv_num, sp->session);
+
+	if (h_key == CK_INVALID_HANDLE)
+		{
+		PK11err(PK11_F_DH_COMP_KEY, PK11_R_CREATEOBJECT);
+		goto err;
+		}
+
+	rv = pFuncList->C_DeriveKey(sp->session,
+	    &mechanism,
+	    h_key,
+	    priv_key_template,
+	    ul_priv_key_attr_count,
+	    &h_derived_key);
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_DERIVEKEY, rv);
+		goto err;
+		}
+
+	rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
+	    priv_key_result, priv_key_attr_result_count);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
+		    rv);
+		goto err;
+		}
+
+	if (((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
+		{
+		PK11err(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE);
+		goto err;
+		}
+	priv_key_result[0].pValue =
+		OPENSSL_malloc(priv_key_result[0].ulValueLen);
+	if (!priv_key_result[0].pValue)
+		{
+		PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
+		goto err;
+		}
+
+	rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
+		priv_key_result, priv_key_attr_result_count);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
+		    rv);
+		goto err;
+		}
+
+	/*
+	 * OpenSSL allocates the output buffer 'key' which is the same
+	 * length of the public key. It is long enough for the derived key
+	 */
+	if (priv_key_result[0].type == CKA_VALUE)
+		{
+		/*
+		 * CKM_DH_PKCS_DERIVE mechanism is not supposed to strip
+		 * leading zeros from a computed shared secret. However,
+		 * OpenSSL always did it so we must do the same here. The
+		 * vagueness of the spec regarding leading zero bytes was
+		 * finally cleared with TLS 1.1 (RFC 4346) saying that leading
+		 * zeros are stripped before the computed data is used as the
+		 * pre-master secret.
+		 */
+		for (i = 0; i < priv_key_result[0].ulValueLen; ++i)
+			{
+			if (((char *)priv_key_result[0].pValue)[i] != 0)
+				break;
+			}
+
+		(void) memcpy(key, ((char *)priv_key_result[0].pValue) + i,
+			priv_key_result[0].ulValueLen - i);
+		ret = priv_key_result[0].ulValueLen - i;
+		}
+
+err:
+
+	if (h_derived_key != CK_INVALID_HANDLE)
+		{
+		rv = pFuncList->C_DestroyObject(sp->session, h_derived_key);
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_DH_COMP_KEY,
+			    PK11_R_DESTROYOBJECT, rv);
+			}
+		}
+	if (priv_key_result[0].pValue)
+		{
+		OPENSSL_free(priv_key_result[0].pValue);
+		priv_key_result[0].pValue = NULL;
+		}
+
+	if (mechanism.pParameter)
+		{
+		OPENSSL_free(mechanism.pParameter);
+		mechanism.pParameter = NULL;
+		}
+
+	pk11_return_session(sp, OP_DH);
+	return (ret);
+	}
+
+
+static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh,
+	DH **key_ptr, BIGNUM **dh_priv_num, CK_SESSION_HANDLE session)
+	{
+	CK_RV rv;
+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
+	CK_OBJECT_CLASS class = CKO_PRIVATE_KEY;
+	CK_KEY_TYPE key_type = CKK_DH;
+	CK_ULONG found;
+	CK_BBOOL rollback = CK_FALSE;
+	int i;
+
+	CK_ULONG ul_key_attr_count = 7;
+	CK_ATTRIBUTE key_template[] =
+		{
+		{CKA_CLASS, (void*) NULL, sizeof (class)},
+		{CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
+		{CKA_DERIVE, &pk11_true, sizeof (pk11_true)},
+		{CKA_PRIVATE, &pk11_false, sizeof (pk11_false)},
+		{CKA_PRIME, (void *) NULL, 0},
+		{CKA_BASE, (void *) NULL, 0},
+		{CKA_VALUE, (void *) NULL, 0},
+		};
+
+	key_template[0].pValue = &class;
+	key_template[1].pValue = &key_type;
+
+	key_template[4].ulValueLen = BN_num_bytes(dh->p);
+	key_template[4].pValue = (CK_VOID_PTR)OPENSSL_malloc(
+		(size_t)key_template[4].ulValueLen);
+	if (key_template[4].pValue == NULL)
+		{
+		PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
+		goto malloc_err;
+		}
+
+	BN_bn2bin(dh->p, key_template[4].pValue);
+
+	key_template[5].ulValueLen = BN_num_bytes(dh->g);
+	key_template[5].pValue = (CK_VOID_PTR)OPENSSL_malloc(
+		(size_t)key_template[5].ulValueLen);
+	if (key_template[5].pValue == NULL)
+		{
+		PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
+		goto malloc_err;
+		}
+
+	BN_bn2bin(dh->g, key_template[5].pValue);
+
+	key_template[6].ulValueLen = BN_num_bytes(dh->priv_key);
+	key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
+		(size_t)key_template[6].ulValueLen);
+	if (key_template[6].pValue == NULL)
+		{
+		PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
+		goto malloc_err;
+		}
+
+	BN_bn2bin(dh->priv_key, key_template[6].pValue);
+
+	/* see find_lock array definition for more info on object locking */
+	LOCK_OBJSTORE(OP_DH);
+	rv = pFuncList->C_FindObjectsInit(session, key_template,
+		ul_key_attr_count);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSINIT, rv);
+		goto err;
+		}
+
+	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTS, rv);
+		goto err;
+		}
+
+	rv = pFuncList->C_FindObjectsFinal(session);
+
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSFINAL,
+		    rv);
+		goto err;
+		}
+
+	if (found == 0)
+		{
+		rv = pFuncList->C_CreateObject(session,
+			key_template, ul_key_attr_count, &h_key);
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_CREATEOBJECT,
+			    rv);
+			goto err;
+			}
+		}
+
+	if (dh_priv_num != NULL)
+		if ((*dh_priv_num = BN_dup(dh->priv_key)) == NULL)
+			{
+			PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
+			rollback = CK_TRUE;
+			goto err;
+			}
+
+	/* LINTED: E_CONSTANT_CONDITION */
+	KEY_HANDLE_REFHOLD(h_key, OP_DH, CK_FALSE, rollback, err);
+	if (key_ptr != NULL)
+		*key_ptr = dh;
+
+err:
+	if (rollback)
+		{
+		/*
+		 * We do not care about the return value from C_DestroyObject()
+		 * since we are doing rollback.
+		 */
+		if (found == 0)
+			(void) pFuncList->C_DestroyObject(session, h_key);
+		h_key = CK_INVALID_HANDLE;
+		}
+
+	UNLOCK_OBJSTORE(OP_DH);
+
+malloc_err:
+	for (i = 4; i <= 6; i++)
+		{
+		if (key_template[i].pValue != NULL)
+			{
+			OPENSSL_free(key_template[i].pValue);
+			key_template[i].pValue = NULL;
+			}
+		}
+
+	return (h_key);
+	}
+
+/*
+ * Check for cache miss and clean the object pointer and handle
+ * in such case. Return 1 for cache hit, 0 for cache miss.
+ *
+ * Note: we rely on pk11_destroy_dh_key_objects() to set sp->opdata_dh
+ *       to CK_INVALID_HANDLE even when it fails to destroy the object.
+ */
+static int check_new_dh_key(PK11_SESSION *sp, DH *dh)
+	{
+	/*
+	 * Provide protection against DH structure reuse by making the
+	 * check for cache hit stronger. Private key component of DH key
+	 * is unique so it is sufficient to compare it with value cached
+	 * in PK11_SESSION structure.
+	 */
+	if ((sp->opdata_dh != dh) ||
+	    (BN_cmp(sp->opdata_dh_priv_num, dh->priv_key) != 0))
+		{
+		/*
+		 * We do not check the return value because even in case of
+		 * failure the sp structure will have both key pointer
+		 * and object handle cleaned and pk11_destroy_object()
+		 * reports the failure to the OpenSSL error message buffer.
+		 */
+		(void) pk11_destroy_dh_object(sp, CK_TRUE);
+		return (0);
+		}
+	return (1);
+	}
+#endif
+
+/*
+ * Local function to simplify key template population
+ * Return 0 -- error, 1 -- no error
+ */
+static int
+init_template_value(BIGNUM *bn, CK_VOID_PTR *p_value,
+	CK_ULONG *ul_value_len)
+	{
+	CK_ULONG len;
+
+	/*
+	 * This function can be used on non-initialized BIGNUMs. It is easier to
+	 * check that here than individually in the callers.
+	 */
+	if (bn != NULL)
+		len = BN_num_bytes(bn);
+
+	if (bn == NULL || len == 0)
+		return (1);
+
+	*ul_value_len = len;
+	*p_value = (CK_VOID_PTR)OPENSSL_malloc((size_t)*ul_value_len);
+	if (*p_value == NULL)
+		return (0);
+
+	BN_bn2bin(bn, *p_value);
+
+	return (1);
+	}
+
+static void
+attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn)
+	{
+		if (attr->ulValueLen > 0)
+			*bn = BN_bin2bn(attr_data, attr->ulValueLen, NULL);
+	}
+
+/*
+ * Find one object in the token. It is an error if we can not find the object or
+ * if we find more objects based on the template we got.
+ *
+ * Returns:
+ *	1 OK
+ *	0 no object or more than 1 object found
+ */
+static int
+find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
+    CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey)
+	{
+	CK_RV rv;
+	CK_ULONG objcnt;
+
+	LOCK_OBJSTORE(op);
+	if ((rv = pFuncList->C_FindObjectsInit(s, ptempl, nattr)) != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_FIND_ONE_OBJECT,
+		    PK11_R_FINDOBJECTSINIT, rv);
+		goto err;
+		}
+
+	rv = pFuncList->C_FindObjects(s, pkey, 1, &objcnt);
+	if (rv != CKR_OK)
+		{
+		PK11err_add_data(PK11_F_FIND_ONE_OBJECT, PK11_R_FINDOBJECTS,
+		    rv);
+		goto err;
+		}
+
+	if (objcnt > 1)
+		{
+		PK11err(PK11_F_FIND_ONE_OBJECT,
+		    PK11_R_MORE_THAN_ONE_OBJECT_FOUND);
+		goto err;
+		}
+	else
+		if (objcnt == 0)
+			{
+			PK11err(PK11_F_FIND_ONE_OBJECT, PK11_R_NO_OBJECT_FOUND);
+			goto err;
+			}
+
+	(void) pFuncList->C_FindObjectsFinal(s);
+	UNLOCK_OBJSTORE(op);
+	return (1);
+err:
+	UNLOCK_OBJSTORE(op);
+	return (0);
+	}
+
+/*
+ * OpenSSL 1.0.0 introduced ENGINE API for the PKEY EVP functions. Sadly,
+ * "openssl dgst -dss1 ..." now uses a new function EVP_DigestSignInit() which
+ * internally needs a PKEY method for DSA even when in the engine. So, to avoid
+ * a regression when moving from 0.9.8 to 1.0.0, we use an internal OpenSSL
+ * structure for the DSA PKEY methods to make it work. It is a future project to
+ * make it work with HW acceleration.
+ *
+ * Note that at the time of 1.0.0d release there is no documentation as to how
+ * the PKEY EVP functions are to be implemented in an engine. There is only one
+ * engine shipped with 1.0.0d that uses the PKEY EVP methods, the GOST engine.
+ * It was used as an example when fixing the above mentioned regression problem.
+ */
+int
+pk11_engine_pkey_methods(ENGINE *e, EVP_PKEY_METHOD **pmeth, const int **nids,
+    int nid)
+	{
+	if (pmeth == NULL)
+		{
+		*nids = pk11_pkey_meth_nids;
+		return (1);
+		}
+
+	switch (nid)
+		{
+		case NID_dsa:
+			*pmeth = (EVP_PKEY_METHOD *)EVP_PKEY_meth_find(nid);
+			return (1);
+		}
+
+	/* Error branch. */
+	*pmeth = NULL;
+	return (0);
+	}
+
+#endif	/* OPENSSL_NO_HW_PK11 */
+#endif	/* OPENSSL_NO_HW */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/engines/pkcs11/e_pk11_uri.c	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,887 @@
+/*
+ * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    [email protected].
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <strings.h>
+#include <libgen.h>
+#include <pthread.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <openssl/crypto.h>
+
+#ifndef OPENSSL_NO_HW
+#ifndef OPENSSL_NO_HW_PK11
+
+#include <security/cryptoki.h>
+#include <security/pkcs11.h>
+#include "e_pk11.h"
+#include "e_pk11_uri.h"
+
+/*
+ * The keystore used is always from the pubkey slot so we need to know which one
+ * was selected so that we can get the information needed for the URI
+ * processing.
+ */
+extern CK_SLOT_ID pubkey_SLOTID;
+extern CK_FUNCTION_LIST_PTR pFuncList;
+
+/*
+ * Cached PIN so that child can use it during the re-login. Note that we do not
+ * cache the PIN by default.
+ */
+static char *token_pin;
+
+static int mlock_pin_in_memory(char *pin);
+static char *run_askpass(char *dialog);
+
+/*
+ * Get the PIN. Either run the command and use its standard output as a PIN to
+ * fill in the PKCS11 URI structure, or read the PIN from the terminal. Using
+ * the external command is of higher precedence. The memory for PIN is allocated
+ * in this function and the PIN is always NULL terminated. The caller must take
+ * care of freeing the memory used for the PIN. The maximum PIN length accepted
+ * is PK11_MAX_PIN_LEN.
+ *
+ * The function is used also during the re-initialization of the engine after
+ * the fork.
+ *
+ * The function must not be called under the protection of the mutex "uri_lock"
+ * because the lock is acquired in the prefork function.
+ *
+ * Returns:
+ *	0 in case of troubles (and sets "*pin" to NULL)
+ *	1 if we got the PIN
+ */
+#define	EXEC_SPEC	"exec:"
+#define	BUILTIN_SPEC	"builtin"
+int
+pk11_get_pin(char *dialog, char **pin)
+	{
+	/* Initialize as an error. */
+	*pin = NULL;
+
+	if (strcmp(dialog, BUILTIN_SPEC) == 0)
+		{
+		/* The getpassphrase() function is not MT safe. */
+		(void) pthread_mutex_lock(uri_lock);
+		/* Note that OpenSSL is not localized at all. */
+		*pin = getpassphrase("Enter token PIN: ");
+		if (*pin == NULL)
+			{
+			PK11err(PK11_F_GET_PIN, PK11_R_COULD_NOT_READ_PIN);
+			(void) pthread_mutex_unlock(uri_lock);
+			goto err;
+			}
+		else
+			{
+			char *pw;
+
+			/*
+			 * getpassphrase() uses an internal  buffer to hold the
+			 * entered password. Note that it terminates the buffer
+			 * with '\0'.
+			 */
+			if ((pw = strdup(*pin)) == NULL)
+				{
+				PK11err(PK11_F_GET_PIN, PK11_R_MALLOC_FAILURE);
+				(void) pthread_mutex_unlock(uri_lock);
+				goto err;
+				}
+			/* Zero the internal buffer to get rid of the PIN. */
+			memset(*pin, 0, strlen(*pin));
+			*pin = pw;
+			(void) pthread_mutex_unlock(uri_lock);
+			}
+		}
+	else
+		{
+		/*
+		 * This is the "exec:" case. We will get the PIN from the output
+		 * of an external command.
+		 */
+		if (strncmp(dialog, EXEC_SPEC, strlen(EXEC_SPEC)) == 0)
+			{
+			dialog += strlen(EXEC_SPEC);
+			if ((*pin = run_askpass(dialog)) == NULL)
+				goto err;
+			}
+		else
+			{
+			/*
+			 * Invalid specification in the passphrasedialog
+			 * keyword.
+			 */
+			PK11err(PK11_F_GET_PIN, PK11_R_BAD_PASSPHRASE_SPEC);
+			goto err;
+			}
+		}
+
+	return (1);
+err:
+	return (0);
+	}
+
+/*
+ * Process the PKCS#11 URI and get the PIN. It uses information from the
+ * passphrasedialog keyword to get the PIN. If passphrasedialog is not present
+ * it is not considered an error since it depends on the token attributes
+ * whether C_Login() is required. The function expects an allocated 'uri_struct'
+ * structure.
+ *
+ * Returns:
+ *	0 if URI is not valid at all, or if we could not get the PIN
+ * 	1 if all is OK
+ *	2 if the URI is not the PKCS#11 URI. In that case, put the string
+ *	pointer to the filename to "*file". Note that the pointer just points
+ *	inside of the "uristr", possibly skipping the file:// prefix if present.
+ */
+int
+pk11_process_pkcs11_uri(const char *uristr, pkcs11_uri *uri_struct,
+	const char **file)
+	{
+	char *uristr2, *l1, *l2, *tok, *name;
+
+	/* Check the "file://" case. */
+	if (strncmp(uristr, FILE_URI_PREFIX, strlen(FILE_URI_PREFIX)) == 0)
+		{
+		*file = uristr + strlen(FILE_URI_PREFIX);
+		return (2);
+		}
+
+	/*  This is the "pkcs11:" case. */
+	if (strncmp(uristr, PK11_URI_PREFIX, strlen(PK11_URI_PREFIX)) != 0)
+		{
+		/* Not PKCS#11 URI at all, could be a filename. */
+		*file = (const char *)uristr;
+		return (2);
+		}
+	else
+		{
+		/* Dup the string and skip over the pkcs11: prefix then. */
+		uristr2 = strdup(uristr + strlen(PK11_URI_PREFIX));
+		if (uristr2 == NULL)
+			{
+			PK11err(PK11_F_CHECK_TOKEN_ATTRS,
+			    PK11_R_MALLOC_FAILURE);
+			goto err;
+			}
+		}
+
+	/* Initialize the structure. */
+	memset(uri_struct, 0, sizeof (*uri_struct));
+
+	/*
+	 * Using strtok_r() would silently skip over multiple semicolons. We
+	 * must check that before moving on. We must also avoid ';' as the first
+	 * and the last character in the URI.
+	 */
+	if (strstr(uristr2, ";;") != NULL || uristr2[0] == ';' ||
+	    (strlen(uristr2) > 0 && uristr2[strlen(uristr2) - 1] == ';'))
+		goto bad_uri;
+
+	tok = strtok_r(uristr2, ";", &l1);
+	for (; tok != NULL; tok = strtok_r(NULL, ";", &l1))
+		{
+		/* "tok" is not empty so there will be something in "name". */
+		name = strtok_r(tok, "=", &l2);
+		/* Check whether there is '=' at all. */
+		if (l2 == NULL)
+			goto bad_uri;
+
+		/*
+		 * Fill out the URI structure. We do not accept duplicit
+		 * attributes.
+		 */
+		if (strcmp(name, PK11_TOKEN) == 0)
+			{
+			if (uri_struct->token == NULL)
+				{
+				if ((uri_struct->token = strdup(l2)) == NULL)
+					goto no_mem;
+				}
+			else
+				goto bad_uri;
+			}
+		else if (strcmp(name, PK11_MANUF) == 0)
+			{
+			if (uri_struct->manuf == NULL)
+				{
+				if ((uri_struct->manuf = strdup(l2)) == NULL)
+					goto no_mem;
+				}
+			else
+				goto bad_uri;
+			}
+		else if (strcmp(name, PK11_SERIAL) == 0)
+			{
+			if (uri_struct->serial == NULL)
+				{
+				if ((uri_struct->serial = strdup(l2)) == NULL)
+					goto no_mem;
+				}
+			else
+				goto bad_uri;
+			}
+		else if (strcmp(name, PK11_MODEL) == 0)
+			{
+			if (uri_struct->model == NULL)
+				{
+				if ((uri_struct->model = strdup(l2)) == NULL)
+					goto no_mem;
+				}
+			else
+				goto bad_uri;
+			}
+		else if (strcmp(name, PK11_OBJECT) == 0)
+			{
+			if (uri_struct->object == NULL)
+				{
+				if ((uri_struct->object = strdup(l2)) == NULL)
+					goto no_mem;
+				}
+			else
+				goto bad_uri;
+			}
+		else if (strcmp(name, PK11_OBJECTTYPE) == 0)
+			{
+			if (uri_struct->objecttype == NULL)
+				{
+				uri_struct->objecttype = strdup(l2);
+				if (uri_struct->objecttype == NULL)
+					goto no_mem;
+				}
+			else
+				goto bad_uri;
+			}
+		else if (strcmp(name, PK11_ASKPASS) == 0)
+			{
+			if (uri_struct->askpass == NULL)
+				{
+				if ((uri_struct->askpass = strdup(l2)) == NULL)
+					goto no_mem;
+				}
+			else
+				goto bad_uri;
+			}
+		else
+			goto bad_uri;
+		}
+
+	/* The "object" token is mandatory in the PKCS#11 URI. */
+	if (uri_struct->object == NULL)
+		{
+		PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_MISSING_OBJECT_LABEL);
+		goto err;
+		}
+
+	free(uristr2);
+	return (1);
+bad_uri:
+	PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_INVALID_PKCS11_URI);
+	if (uristr2 != NULL)
+		free(uristr2);
+	return (0);
+no_mem:
+	PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_MALLOC_FAILURE);
+err:
+	pk11_free_pkcs11_uri(uri_struct, CK_FALSE);
+	if (uristr2 != NULL)
+		free(uristr2);
+	return (0);
+	}
+
+/*
+ * Free the PKCS11 URI structure and anything that might be inside.
+ */
+void
+pk11_free_pkcs11_uri(pkcs11_uri *uri_struct, CK_BBOOL free_uri_itself)
+	{
+	if (uri_struct->token != NULL)
+		free(uri_struct->token);
+	if (uri_struct->manuf != NULL)
+		free(uri_struct->manuf);
+	if (uri_struct->serial != NULL)
+		free(uri_struct->serial);
+	if (uri_struct->model != NULL)
+		free(uri_struct->model);
+	if (uri_struct->object != NULL)
+		free(uri_struct->object);
+	if (uri_struct->objecttype != NULL)
+		free(uri_struct->objecttype);
+	if (uri_struct->askpass != NULL)
+		free(uri_struct->askpass);
+
+	if (free_uri_itself == CK_TRUE)
+		OPENSSL_free(uri_struct);
+	}
+
+/*
+ * While our keystore is always the one used by the pubkey slot (which is
+ * usually the Metaslot) we must make sure that those URI attributes that
+ * specify the keystore match the real attributes of our slot keystore. Note
+ * that one can use the METASLOT_OBJECTSTORE_TOKEN environment variable to
+ * change the Metaslot's keystore from the softtoken to something else (see
+ * libpkcs11(3LIB)). The user might want to use such attributes in the PKCS#11
+ * URI to make sure that the intended keystore is used.
+ *
+ * Returns:
+ *	1 on success
+ *	0 on failure
+ */
+int
+pk11_check_token_attrs(pkcs11_uri *uri_struct)
+	{
+	CK_RV rv;
+	static CK_TOKEN_INFO_PTR token_info = NULL;
+
+	(void) pthread_mutex_lock(uri_lock);
+	if (token_info == NULL)
+		{
+		token_info = OPENSSL_malloc(sizeof (CK_TOKEN_INFO));
+		if (token_info == NULL)
+			{
+			PK11err(PK11_F_CHECK_TOKEN_ATTRS,
+			    PK11_R_MALLOC_FAILURE);
+			goto err;
+			}
+
+		rv = pFuncList->C_GetTokenInfo(pubkey_SLOTID, token_info);
+		if (rv != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_CHECK_TOKEN_ATTRS,
+			    PK11_R_GETTOKENINFO, rv);
+			goto err;
+			}
+		}
+
+	if (uri_struct->token != NULL)
+		if (strncmp(uri_struct->token, (char *)token_info->label,
+		    strlen(uri_struct->token) > 32 ? 32 :
+		    strlen(uri_struct->token)) != 0)
+			{
+			goto urierr;
+			}
+
+	if (uri_struct->manuf != NULL)
+		if (strncmp(uri_struct->manuf,
+		    (char *)token_info->manufacturerID,
+		    strlen(uri_struct->manuf) > 32 ? 32 :
+		    strlen(uri_struct->manuf)) != 0)
+			goto urierr;
+
+	if (uri_struct->model != NULL)
+		if (strncmp(uri_struct->model, (char *)token_info->model,
+		    strlen(uri_struct->model) > 16 ? 16 :
+		    strlen(uri_struct->model)) != 0)
+			goto urierr;
+
+	if (uri_struct->serial != NULL)
+		if (strncmp(uri_struct->serial,
+		    (char *)token_info->serialNumber,
+		    strlen(uri_struct->serial) > 16 ? 16 :
+		    strlen(uri_struct->serial)) != 0)
+			goto urierr;
+
+	(void) pthread_mutex_unlock(uri_lock);
+	return (1);
+
+urierr:
+	PK11err(PK11_F_CHECK_TOKEN_ATTRS, PK11_R_TOKEN_ATTRS_DO_NOT_MATCH);
+	/* Correct error already set above for the "err" label. */
+err:
+	(void) pthread_mutex_unlock(uri_lock);
+	return (0);
+	}
+
+/*
+ * Return the process PIN caching policy. We initialize it just once so if the
+ * process change OPENSSL_PKCS11_PIN_CACHING_POLICY during the operation it will
+ * not have any affect on the policy.
+ *
+ * We assume that the "uri_lock" mutex is already locked.
+ *
+ * Returns the caching policy number.
+ */
+int
+pk11_get_pin_caching_policy(void)
+	{
+	char *value = NULL;
+	static int policy = POLICY_NOT_INITIALIZED;
+
+	if (policy != POLICY_NOT_INITIALIZED)
+		return (policy);
+
+	value = getenv("OPENSSL_PKCS11_PIN_CACHING_POLICY");
+
+	if (value == NULL || strcmp(value, "none") == 0)
+		{
+		policy = POLICY_NONE;
+		goto done;
+		}
+
+	if (strcmp(value, "memory") == 0)
+		{
+		policy = POLICY_MEMORY;
+		goto done;
+		}
+
+	if (strcmp(value, "mlocked-memory") == 0)
+		{
+		policy = POLICY_MLOCKED_MEMORY;
+		goto done;
+		}
+
+	return (POLICY_WRONG_VALUE);
+done:
+	return (policy);
+	}
+
+/*
+ * Cache the PIN in memory once. We already know that we have either "memory" or
+ * "mlocked-memory" keyword correctly set.
+ *
+ * Returns:
+ *	1 on success
+ *	0 on failure
+ */
+int
+pk11_cache_pin(char *pin)
+	{
+	(void) pthread_mutex_lock(uri_lock);
+	/* We set the PIN only once since all URIs must have it the same. */
+	if (token_pin != NULL)
+		goto ok;
+
+	if (pk11_get_pin_caching_policy() == POLICY_MEMORY)
+		{
+		if ((token_pin = strdup(pin)) == NULL)
+			{
+			PK11err(PK11_F_CACHE_PIN, PK11_R_MALLOC_FAILURE);
+			goto err;
+			}
+		}
+	else
+		{
+		if (pk11_get_pin_caching_policy() == POLICY_MLOCKED_MEMORY)
+			{
+			if (mlock_pin_in_memory(pin) == 0)
+				goto err;
+			}
+		}
+
+ok:
+	(void) pthread_mutex_unlock(uri_lock);
+	return (1);
+err:
+	(void) pthread_mutex_unlock(uri_lock);
+	return (0);
+	}
+
+/*
+ * Cache the PIN in mlock(3C)ed memory. If mlock(3C) fails we will not resort to
+ * the normal memory caching.
+ *
+ * Note that this function must be called under the protection of the "uri_lock"
+ * mutex.
+ *
+ * Returns:
+ *	1 on success
+ *	0 on failure
+ */
+static int
+mlock_pin_in_memory(char *pin)
+	{
+	void *addr = NULL;
+	long pagesize = 0;
+
+	/* mlock(3C) locks pages so we need one whole page for the PIN. */
+	if ((pagesize = sysconf(_SC_PAGESIZE)) == -1)
+		{
+		PK11err(PK11_F_MLOCK_PIN_IN_MEMORY, PK11_R_SYSCONF_FAILED);
+		goto err;
+		}
+
+	/* This will ensure we have a page aligned pointer... */
+	if ((addr = mmap(0, pagesize, PROT_READ | PROT_WRITE,
+	    MAP_PRIVATE | MAP_ANON, -1, 0)) == MAP_FAILED)
+		{
+		PK11err(PK11_F_MLOCK_PIN_IN_MEMORY, PK11_R_MMAP_FAILED);
+		goto err;
+		}
+
+	/* ...because "addr" must be page aligned here. */
+	if (mlock(addr, pagesize) == -1)
+		{
+		/*
+		 * Missing the PRIV_PROC_LOCK_MEMORY privilege might be a common
+		 * problem so distinguish this situation from other issues.
+		 */
+		if (errno == EPERM)
+			PK11err(PK11_F_MLOCK_PIN_IN_MEMORY,
+			    PK11_R_PRIV_PROC_LOCK_MEMORY_MISSING);
+		else
+			PK11err(PK11_F_MLOCK_PIN_IN_MEMORY,
+			    PK11_R_MLOCK_FAILED);
+
+		/*
+		 * We already have a problem here so there is no need to check
+		 * that we could unmap the page. The PIN is not there yet
+		 * anyway.
+		 */
+		(void) munmap(addr, pagesize);
+		goto err;
+		}
+
+	/* Copy the PIN to the mlocked memory. */
+	token_pin = (char *)addr;
+	strlcpy(token_pin, pin, PK11_MAX_PIN_LEN + 1);
+	return (1);
+err:
+	return (0);
+	}
+
+/*
+ * Log in to the keystore if we are supposed to do that at all. Take care of
+ * reading and caching the PIN etc. Log in only once even when called from
+ * multiple threads.
+ *
+ * Returns:
+ *	1 on success
+ *	0 on failure
+ */
+int
+pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
+    pkcs11_uri *uri_struct, CK_BBOOL is_private)
+	{
+	CK_RV rv;
+
+	if ((pubkey_token_flags & CKF_TOKEN_INITIALIZED) == 0)
+		{
+		PK11err(PK11_F_TOKEN_LOGIN,
+		    PK11_R_TOKEN_NOT_INITIALIZED);
+		goto err;
+		}
+
+	/*
+	 * If login is required or needed but the PIN has not been even
+	 * initialized we can bail out right now. Note that we are supposed to
+	 * always log in if we are going to access private keys. However, we may
+	 * need to log in even for accessing public keys in case that the
+	 * CKF_LOGIN_REQUIRED flag is set.
+	 */
+	if ((pubkey_token_flags & CKF_LOGIN_REQUIRED ||
+	    is_private == CK_TRUE) && ~pubkey_token_flags &
+	    CKF_USER_PIN_INITIALIZED)
+		{
+		PK11err(PK11_F_TOKEN_LOGIN, PK11_R_TOKEN_PIN_NOT_SET);
+		goto err;
+		}
+
+	/*
+	 * Note on locking: it is possible that more than one thread gets into
+	 * pk11_get_pin() so we must deal with that. We cannot avoid it since we
+	 * cannot guard fork() in there with a lock because we could end up in
+	 * a dead lock in the child. Why? Remember we are in a multithreaded
+	 * environment so we must lock all mutexes in the prefork function to
+	 * avoid a situation in which a thread that did not call fork() held a
+	 * lock, making future unlocking impossible. We lock right before
+	 * C_Login().
+	 */
+	if (pubkey_token_flags & CKF_LOGIN_REQUIRED || is_private == CK_TRUE)
+		{
+		if (*login_done == CK_FALSE &&
+		    uri_struct->askpass == NULL)
+			{
+			PK11err(PK11_F_TOKEN_LOGIN,
+			    PK11_R_TOKEN_PIN_NOT_PROVIDED);
+			goto err;
+			}
+
+		if (*login_done == CK_FALSE &&
+		    uri_struct->askpass != NULL)
+			{
+			if (pk11_get_pin(uri_struct->askpass,
+			    &uri_struct->pin) == 0)
+				{
+				PK11err(PK11_F_TOKEN_LOGIN,
+				    PK11_R_TOKEN_PIN_NOT_PROVIDED);
+				goto err;
+				}
+			}
+
+		/*
+		 * Note that what we are logging into is the keystore from
+		 * pubkey_SLOTID because we work with OP_RSA session type here.
+		 * That also means that we can work with only one keystore in
+		 * the engine.
+		 *
+		 * We must make sure we do not try to login more than once.
+		 * Also, see the comment above on locking strategy.
+		 */
+		(void) pthread_mutex_lock(uri_lock);
+		if (*login_done == CK_FALSE)
+			{
+			if ((rv = pFuncList->C_Login(session,
+			    CKU_USER, (CK_UTF8CHAR*)uri_struct->pin,
+			    strlen(uri_struct->pin))) != CKR_OK)
+				{
+				PK11err_add_data(PK11_F_TOKEN_LOGIN,
+				    PK11_R_TOKEN_LOGIN_FAILED, rv);
+				goto err_locked;
+				}
+
+			*login_done = CK_TRUE;
+
+			/*
+			 * Cache the passphrasedialog for possible child (which
+			 * would need to relogin).
+			 */
+			if (passphrasedialog == NULL &&
+			    uri_struct->askpass != NULL)
+				{
+				passphrasedialog =
+				    strdup(uri_struct->askpass);
+
+				if (passphrasedialog == NULL)
+					{
+					PK11err_add_data(PK11_F_TOKEN_LOGIN,
+					    PK11_R_MALLOC_FAILURE, rv);
+					goto err_locked;
+					}
+				}
+
+			/*
+			 * Check the PIN caching policy. Note that user might
+			 * have provided a PIN even when no PIN was required -
+			 * in that case we always remove the PIN from memory.
+			 */
+			if (pk11_get_pin_caching_policy() ==
+			    POLICY_WRONG_VALUE)
+				{
+				PK11err(PK11_F_TOKEN_LOGIN,
+				    PK11_R_PIN_CACHING_POLICY_INVALID);
+				goto err_locked;
+				}
+
+			if (pk11_get_pin_caching_policy() != POLICY_NONE)
+				if (pk11_cache_pin(uri_struct->pin) == 0)
+					goto err_locked;
+			}
+		(void) pthread_mutex_unlock(uri_lock);
+		}
+	else
+		{
+			/*
+			 * If token does not require login we take it as the
+			 * login was done.
+			 */
+			*login_done = CK_TRUE;
+		}
+
+	/*
+	 * If we raced at pk11_get_pin() we must make sure that all threads that
+	 * called pk11_get_pin() will erase the PIN from memory, not just the
+	 * one that called C_Login(). Note that if we were supposed to cache the
+	 * PIN it was already cached by now so filling "uri_struct.pin" with
+	 * zero bytes is always OK since pk11_cache_pin() makes a copy of it.
+	 */
+	if (uri_struct->pin != NULL)
+		memset(uri_struct->pin, 0, strlen(uri_struct->pin));
+
+	return (1);
+
+err_locked:
+	(void) pthread_mutex_unlock(uri_lock);
+err:
+	/* Always get rid of the PIN. */
+	if (uri_struct->pin != NULL)
+		memset(uri_struct->pin, 0, strlen(uri_struct->pin));
+	return (0);
+	}
+
+/*
+ * Log in to the keystore in the child if we were logged in in the parent. There
+ * are similarities in the code with pk11_token_login() but still it is quite
+ * different so we need a separate function for this.
+ *
+ * Note that this function is called under the locked session mutex when fork is
+ * detected. That means that C_Login() will be called from the child just once.
+ *
+ * Returns:
+ *	1 on success
+ *	0 on failure
+ */
+int
+pk11_token_relogin(CK_SESSION_HANDLE session)
+	{
+	CK_RV rv;
+
+	/*
+	 * We are in the child so check if we should login to the token again.
+	 * Note that it is enough to log in to the token through one session
+	 * only, all already open and all future sessions can access the token
+	 * then.
+	 */
+	if (passphrasedialog != NULL)
+		{
+		char *pin = NULL;
+
+		/* If we cached the PIN then use it. */
+		if (token_pin != NULL)
+			pin = token_pin;
+		else if (pk11_get_pin(passphrasedialog, &pin) == 0)
+			goto err;
+
+		(void) pthread_mutex_lock(uri_lock);
+		if ((rv = pFuncList->C_Login(session, CKU_USER,
+		    (CK_UTF8CHAR_PTR)pin, strlen(pin))) != CKR_OK)
+			{
+			PK11err_add_data(PK11_F_TOKEN_RELOGIN,
+			    PK11_R_TOKEN_LOGIN_FAILED, rv);
+			(void) pthread_mutex_unlock(uri_lock);
+			goto err;
+			}
+		(void) pthread_mutex_unlock(uri_lock);
+
+		/* Forget the PIN now if we did not cache it before. */
+		if (pin != token_pin)
+			{
+			memset(pin, 0, strlen(pin));
+			OPENSSL_free(pin);
+			}
+		}
+
+	return (1);
+err:
+	return (0);
+	}
+
+/*
+ * This function forks and runs an external command. It would be nice if we
+ * could use popen(3C)/pclose(3C) for that but unfortunately we need to be able
+ * to get rid of the PIN from the memory. With p(open|close) function calls we
+ * cannot control the stdio's memory used for buffering and our tests showed
+ * that the PIN really stays there even after pclose().
+ *
+ * Returns:
+ *	allocated buffer on success
+ *	NULL on failure
+ */
+static char *
+run_askpass(char *dialog)
+	{
+	pid_t pid;
+	int n, p[2];
+	char *buf = NULL;
+
+	if (pipe(p) == -1)
+		{
+		PK11err(PK11_F_RUN_ASKPASS, PK11_R_PIPE_FAILED);
+		return (NULL);
+		}
+
+	switch (pid = fork())
+		{
+		case -1:
+			PK11err(PK11_F_RUN_ASKPASS, PK11_R_FORK_FAILED);
+			return (NULL);
+		/* child */
+		case 0:
+			/*
+			 * This should make sure that dup2() will not fail on
+			 * file descriptor shortage.
+			 */
+			close(p[0]);
+			(void) dup2(p[1], 1);
+			close(p[1]);
+			/*
+			 * Note that we cannot use PK11err() here since we are
+			 * in the child. However, parent will get read() error
+			 * so do not worry.
+			 */
+			(void) execl(dialog, basename(dialog), NULL);
+			exit(1);
+		/* parent */
+		default:
+			/* +1 is for the terminating '\0' */
+			buf = (char *)OPENSSL_malloc(PK11_MAX_PIN_LEN + 1);
+			if (buf == NULL)
+				{
+				PK11err(PK11_F_RUN_ASKPASS,
+				    PK11_R_MALLOC_FAILURE);
+				return (NULL);
+				}
+
+			close(p[1]);
+			n = read(p[0], buf, PK11_MAX_PIN_LEN);
+			if (n == -1 || n == 0)
+				{
+				PK11err(PK11_F_RUN_ASKPASS,
+				    PK11_R_PIN_NOT_READ_FROM_COMMAND);
+				OPENSSL_free(buf);
+				return (NULL);
+				}
+			buf[n] = '\0';
+
+			(void) waitpid(pid, NULL, 0);
+		}
+
+	return (buf);
+	}
+
+#endif	/* OPENSSL_NO_HW_PK11 */
+#endif	/* OPENSSL_NO_HW */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/engines/pkcs11/e_pk11_uri.h	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    [email protected].
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (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	E_PK11_URI_H
+#define	E_PK11_URI_H
+
+#include <security/pkcs11t.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/* PKCS#11 URI related prefixes and attributes. */
+#define	PK11_URI_PREFIX		"pkcs11:"
+#define	FILE_URI_PREFIX		"file://"
+#define	PK11_TOKEN		"token"
+#define	PK11_MANUF		"manuf"
+#define	PK11_SERIAL		"serial"
+#define	PK11_MODEL		"model"
+#define	PK11_OBJECT		"object"
+#define	PK11_OBJECTTYPE		"objecttype"
+#define	PK11_ASKPASS		"passphrasedialog"
+
+/* PIN caching policy. */
+#define	POLICY_NOT_INITIALIZED	0
+#define	POLICY_NONE		1
+#define	POLICY_MEMORY		2
+#define	POLICY_MLOCKED_MEMORY	3
+#define	POLICY_WRONG_VALUE	4
+
+/*
+ * That's what getpassphrase(3c) supports.
+ */
+#define	PK11_MAX_PIN_LEN	256
+
+/* Add new attributes of the PKCS#11 URI here. */
+typedef struct pkcs11_uri_struct {
+	char	*object;	/* object label, the only mandatory info */
+	char	*objecttype;	/* (private|public|cert), currently unused */
+	char	*token;		/* token label */
+	char	*manuf;		/* manufacturer label */
+	char	*serial;	/* serial number label */
+	char	*model;		/* model label */
+	char	*askpass;	/* full path to the command to get the PIN */
+	/* Not part of the PKCS11 URI itself. */
+	char	*pin;		/* token PIN */
+} pkcs11_uri;
+
+/* For URI processing. */
+extern pthread_mutex_t *uri_lock;
+
+int pk11_get_pin(char *dialog, char **pin);
+int pk11_get_pin_caching_policy(void);
+int pk11_process_pkcs11_uri(const char *uristr, pkcs11_uri *uri_struct,
+	const char **file);
+int pk11_check_token_attrs(pkcs11_uri *uri_struct);
+void pk11_free_pkcs11_uri(pkcs11_uri *uri_struct, CK_BBOOL free_uri_itself);
+int pk11_cache_pin(char *pin);
+int pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
+	pkcs11_uri *uri_struct, CK_BBOOL is_private);
+int pk11_token_relogin(CK_SESSION_HANDLE session);
+
+#ifdef	__cplusplus
+}
+#endif
+#endif /* E_PK11_URI_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/patches/008-6193522.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,54 @@
+diff -ruN openssl-0.9.8a/apps/CA.pl.in openssl-0.9.8a/apps/CA.pl.in
+--- openssl-0.9.8a/apps/CA.pl.in	2005-07-04 23:44:22.000000000 +0200
++++ openssl-0.9.8a/apps/CA.pl.in	2009-04-21 16:08:45.354925289 +0200
+@@ -53,7 +53,7 @@
+ $X509="$openssl x509";
+ $PKCS12="$openssl pkcs12";
+ 
+-$CATOP="./demoCA";
++$CATOP="/etc/openssl";
+ $CAKEY="cakey.pem";
+ $CAREQ="careq.pem";
+ $CACERT="cacert.pem";
+diff -ruN openssl-0.9.8a/apps/openssl.cnf openssl-0.9.8a/apps/openssl.cnf
+--- openssl-0.9.8a/apps/openssl.cnf	2005-09-16 14:20:24.000000000 +0200
++++ openssl-0.9.8a/apps/openssl.cnf	2009-04-21 16:07:13.910980196 +0200
+@@ -39,7 +39,7 @@
+ ####################################################################
+ [ CA_default ]
+ 
+-dir		= ./demoCA		# Where everything is kept
++dir		= /etc/openssl		# Where everything is kept
+ certs		= $dir/certs		# Where the issued certs are kept
+ crl_dir		= $dir/crl		# Where the issued crl are kept
+ database	= $dir/index.txt	# database index file.
+@@ -49,7 +49,7 @@
+ 
+ certificate	= $dir/cacert.pem 	# The CA certificate
+ serial		= $dir/serial 		# The current serial number
+-crlnumber	= $dir/crlnumber	# the current crl number
++#crlnumber	= $dir/crlnumber	# the current crl number
+ 					# must be commented out to leave a V1 CRL
+ crl		= $dir/crl.pem 		# The current CRL
+ private_key	= $dir/private/cakey.pem# The private key
+@@ -126,17 +126,17 @@
+ 
+ [ req_distinguished_name ]
+ countryName			= Country Name (2 letter code)
+-countryName_default		= AU
++#countryName_default		= US
+ countryName_min			= 2
+ countryName_max			= 2
+ 
+ stateOrProvinceName		= State or Province Name (full name)
+-stateOrProvinceName_default	= Some-State
++#stateOrProvinceName_default	= Some-State
+ 
+ localityName			= Locality Name (eg, city)
+ 
+ 0.organizationName		= Organization Name (eg, company)
+-0.organizationName_default	= Internet Widgits Pty Ltd
++#0.organizationName_default	= Unconfigured OpenSSL Installation
+ 
+ # we can do this but it is not needed normally :-)
+ #1.organizationName		= Second Organization Name (eg, company)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/patches/015-pkcs11_engine-0.9.8a.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,196 @@
+#
+# This patch file adds the Solaris's pkcs11 engine.
+# This is Solaris-specific (developed in house): not suitable for upstream.
+#
+--- /tmp/Configure	Fri Feb 11 14:40:39 2011
++++ openssl-1.0.0d/Configure	Fri Feb 11 14:41:36 2011
+@@ -10,7 +10,7 @@
+ 
+ # see INSTALL for instructions.
+ 
+-my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [experimental-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-krb5] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
++my $usage="Usage: Configure --pk11-libname=PK11_LIB_LOCATION [no-<cipher> ...] [enable-<cipher> ...] [experimental-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-krb5] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
+ 
+ # Options:
+ #
+@@ -19,6 +19,9 @@
+ # --prefix      prefix for the OpenSSL include, lib and bin directories
+ #               (Default: the OPENSSLDIR directory)
+ #
++# --pk11-libname  PKCS#11 library name.
++#               (Default: none)
++#
+ # --install_prefix  Additional prefix for package builders (empty by
+ #               default).  This needn't be set in advance, you can
+ #               just as well use "make INSTALL_PREFIX=/whatever install".
+@@ -716,6 +719,9 @@
+ my $idx_arflags = $idx++;
+ my $idx_multilib = $idx++;
+ 
++# PKCS#11 engine patch
++my $pk11_libname="";
++
+ my $prefix="";
+ my $libdir="";
+ my $openssldir="";
+@@ -938,6 +944,10 @@
+ 				{
+ 				$prefix=$1;
+ 				}
++			elsif (/^--pk11-libname=(.*)$/)
++				{
++				$pk11_libname=$1;
++				}
+ 			elsif (/^--libdir=(.*)$/)
+ 				{
+ 				$libdir=$1;
+@@ -1105,6 +11115,13 @@
+ 	exit 0;
+ }
+ 
++if (! $pk11_libname)
++        {
++        print STDERR "You must set --pk11-libname for PKCS#11 library.\n";
++        print STDERR "See README.pkcs11 for more information.\n";
++        exit 1;
++        }
++
+ if ($target =~ m/^CygWin32(-.*)$/) {
+ 	$target = "Cygwin".$1;
+ }
+@@ -1279,6 +1296,8 @@
+ if ($flags ne "")	{ $cflags="$flags$cflags"; }
+ else			{ $no_user_cflags=1;       }
+ 
++$cflags="-DPK11_LIB_LOCATION=\"$pk11_libname\" $cflags";
++
+ # Kerberos settings.  The flavor must be provided from outside, either through
+ # the script "config" or manually.
+ if (!$no_krb5)
+@@ -1687,6 +1706,7 @@
+ 	s/^VERSION=.*/VERSION=$version/;
+ 	s/^MAJOR=.*/MAJOR=$major/;
+ 	s/^MINOR=.*/MINOR=$minor/;
++	s/^PK11_LIB_LOCATION=.*/PK11_LIB_LOCATION=$pk11_libname/;
+ 	s/^SHLIB_VERSION_NUMBER=.*/SHLIB_VERSION_NUMBER=$shlib_version_number/;
+ 	s/^SHLIB_VERSION_HISTORY=.*/SHLIB_VERSION_HISTORY=$shlib_version_history/;
+ 	s/^SHLIB_MAJOR=.*/SHLIB_MAJOR=$shlib_major/;
+--- /tmp/Makefile.org	Fri Feb 11 14:41:54 2011
++++ openssl-1.0.0d/Makefile.org	Fri Feb 11 14:38:01 2011
+@@ -26,6 +26,9 @@
+ INSTALL_PREFIX=
+ INSTALLTOP=/usr/local/ssl
+ 
++# You must set this through --pk11-libname configure option.
++PK11_LIB_LOCATION=
++
+ # Do not edit this manually. Use Configure --openssldir=DIR do change this!
+ OPENSSLDIR=/usr/local/ssl
+ 
+--- /tmp/Makefile	Mon Feb 14 14:59:22 2011
++++ openssl-1.0.0d/engines/Makefile	Mon Feb 14 15:00:35 2011
+@@ -26,7 +26,8 @@
+ APPS=
+ 
+ LIB=$(TOP)/libcrypto.a
+-LIBNAMES= 4758cca aep atalla cswift gmp chil nuron sureware ubsec padlock capi
++LIBNAMES= 4758cca aep atalla cswift gmp chil nuron sureware ubsec padlock capi \
++	  pk11
+ 
+ LIBSRC=	e_4758cca.c \
+ 	e_aep.c \
+@@ -38,7 +39,8 @@
+ 	e_sureware.c \
+ 	e_ubsec.c \
+ 	e_padlock.c \
+-	e_capi.c
++	e_capi.c \
++	e_pk11.c
+ LIBOBJ= e_4758cca.o \
+ 	e_aep.o \
+ 	e_atalla.o \
+@@ -49,7 +51,8 @@
+ 	e_sureware.o \
+ 	e_ubsec.o \
+ 	e_padlock.o \
+-	e_capi.o
++	e_capi.o \
++	e_pk11.o
+ 
+ SRC= $(LIBSRC)
+ 
+@@ -63,7 +66,8 @@
+ 	e_nuron_err.c e_nuron_err.h \
+ 	e_sureware_err.c e_sureware_err.h \
+ 	e_ubsec_err.c e_ubsec_err.h \
+-	e_capi_err.c e_capi_err.h
++	e_capi_err.c e_capi_err.h \
++	e_pk11.h e_pk11_uri.h e_pk11_err.h e_pk11_pub.c e_pk11_uri.c e_pk11_err.c
+ 
+ ALL=    $(GENERAL) $(SRC) $(HEADER)
+ 
+@@ -78,7 +82,7 @@
+ 		for l in $(LIBNAMES); do \
+ 			$(MAKE) -f ../Makefile.shared -e \
+ 				LIBNAME=$$l LIBEXTRAS=e_$$l.o \
+-				LIBDEPS='-L.. -lcrypto $(EX_LIBS)' \
++				LIBDEPS='-L.. -lcrypto -lcryptoutil $(EX_LIBS)' \
+ 				link_o.$(SHLIB_TARGET); \
+ 		done; \
+ 	else \
+--- crypto/engine/eng_all.c Thu Sep  5 12:59:50 2013
++++ openssl-1.0.1e/crypto/engine/eng_all.c Thu Sep  5 12:59:50 2013
+@@ -60,6 +60,16 @@
+ #include "cryptlib.h"
+ #include "eng_int.h"
+
++/*
++ * pkcs11 engine no longer is a built-in engine, and ENGINE_load_pk11() needs to be
++ * defined in libcrypto.so for ssh.  Instead of load pkcs11 engine, it load dynamic
++ * engines.
++ */
++void ENGINE_load_pk11(void)
++	{
++	ENGINE_load_dynamic();
++	}
++
+ void ENGINE_load_builtin_engines(void)
+ {
+     /* Some ENGINEs need this */
+--- crypto/dso/dso_lib.c Thu Sep  5 12:59:50 2013
++++ openssl-1.0.1e/crypto/dso/dso_lib.c Thu Sep  5 12:59:50 2013
+@@ -396,6 +396,24 @@
+         DSOerr(DSO_F_DSO_CONVERT_FILENAME, DSO_R_NO_FILENAME);
+         return (NULL);
+     }
++    /*
++     * For pkcs11 engine, use libpk11.so (instead of libpkcs11.so) to
++     * avoid the name collision with PKCS#11 library.
++     */
++    if (strcmp(filename, "pkcs11") == 0) {
++#ifdef  _LP64
++        char *fullpath = "/lib/openssl/engines/64/libpk11.so";
++#else
++        char *fullpath = "/lib/openssl/engines/libpk11.so";
++#endif
++        result = OPENSSL_malloc(strlen(fullpath) + 1);
++        if(result == NULL) {
++            DSOerr(DSO_F_DSO_CONVERT_FILENAME, ERR_R_MALLOC_FAILURE);
++            return(NULL);
++        }
++        BUF_strlcpy(result, fullpath, strlen(fullpath) + 1);
++        return (result);
++    }
+     if ((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) {
+         if (dso->name_converter != NULL)
+             result = dso->name_converter(dso, filename);
+--- /tmp/engine.h       Fri Feb 11 14:46:24 2011
++++ openssl-1.0.0d/crypto/engine/engine.h       Fri Feb 11 14:47:32 2011
+@@ -413,6 +413,7 @@
+ #  endif
+ # endif
+ void ENGINE_load_cryptodev(void);
++void ENGINE_load_pk11(void);
+ void ENGINE_load_rdrand(void);
+ void ENGINE_load_builtin_engines(void);
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/patches/018-compiler_opts.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,36 @@
+#
+# This was developed in house to support Solaris-specific options.
+# Not suitable for upstream.
+#
+--- openssl-1.0.0d/Configure	Thu Feb 10 20:02:41 2011
++++ /tmp/Configure	Thu Feb 10 20:01:51 2011
+@@ -153,6 +153,7 @@
+ my $x86_64_asm="x86_64cpuid.o:x86_64-gcc.o x86_64-mont.o x86_64-mont5.o x86_64-gf2m.o rsaz_exp.o rsaz-x86_64.o rsaz-avx2.o:ecp_nistz256.o ecp_nistz256-x86_64.o::aes-x86_64.o vpaes-x86_64.o bsaes-x86_64.o aesni-x86_64.o aesni-sha1-x86_64.o aesni-sha256-x86_64.o aesni-mb-x86_64.o::md5-x86_64.o:sha1-x86_64.o sha256-x86_64.o sha512-x86_64.o sha1-mb-x86_64.o sha256-mb-x86_64.o::rc4-x86_64.o rc4-md5-x86_64.o:::wp-x86_64.o:cmll-x86_64.o cmll_misc.o:ghash-x86_64.o aesni-gcm-x86_64.o:";
+ my $ia64_asm="ia64cpuid.o:bn-ia64.o ia64-mont.o:::aes_core.o aes_cbc.o aes-ia64.o::md5-ia64.o:sha1-ia64.o sha256-ia64.o sha512-ia64.o::rc4-ia64.o rc4_skey.o:::::ghash-ia64.o::void";
+ my $sparcv9_asm="sparcv9cap.o sparccpuid.o:bn-sparcv9.o sparcv9-mont.o sparcv9a-mont.o vis3-mont.o sparct4-mont.o sparcv9-gf2m.o::des_enc-sparc.o fcrypt_b.o dest4-sparcv9.o:aes_core.o aes_cbc.o aes-sparcv9.o aest4-sparcv9.o::md5-sparcv9.o:sha1-sparcv9.o sha256-sparcv9.o sha512-sparcv9.o::::::camellia.o cmll_misc.o cmll_cbc.o cmllt4-sparcv9.o:ghash-sparcv9.o::void";
++my $fips_sparcv9_asm="sparcv9cap.o sparccpuid.o:bn-sparcv9.o sparcv9-mont.o vis3-mont.o sparct4-mont.o sparcv9-gf2m.o::des_enc-sparc.o fcrypt_b.o dest4-sparcv9.o:aes_core.o aes_cbc.o aes-sparcv9.o aest4-sparcv9.o::md5-sparcv9.o:sha1-sparcv9.o sha256-sparcv9.o sha512-sparcv9.o::::::camellia.o cmll_misc.o cmll_cbc.o cmllt4-sparcv9.o:ghash-sparcv9.o::void";
+ my $sparcv8_asm=":sparcv8.o::des_enc-sparc.o fcrypt_b.o:::::::::::::void";
+ my $alpha_asm="alphacpuid.o:bn_asm.o alpha-mont.o::::::sha1-alpha.o:::::::ghash-alpha.o::void";
+ my $mips64_asm=":bn-mips.o mips-mont.o:::aes_cbc.o aes-mips.o:::sha1-mips.o sha256-mips.o sha512-mips.o::::::::";
+@@ -277,6 +278,21 @@
+ #"sunos-cc", "cc:-O4 -DNOPROTO -DNOCONST::(unknown):SUNOS::DES_UNROLL:${no_asm}::",
+ "sunos-gcc","gcc:-O3 -mcpu=v8 -Dssize_t=int::(unknown):SUNOS::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL DES_PTR DES_RISC1:${no_asm}::",
+ 
++#### Solaris configs, used for OpenSSL as delivered by S11.
++"solaris-x86-cc-sunw","cc:-m32 -xO3 -xspace -Xa::-D_REENTRANT::-lsocket -lnsl -lc:BN_LLONG RC4_CHUNK DES_PTR DES_UNROLL BF_PTR:${x86_elf_asm}:dlfcn:solaris-shared:-KPIC:-m32 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign -M/usr/lib/ld/map.noexdata:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
++#
++"solaris64-x86_64-cc-sunw","cc:-xO3 -m64 -xstrconst -Xa -DL_ENDIAN::-D_REENTRANT::-lsocket -lnsl -lc:SIXTY_FOUR_BIT_LONG RC4_CHUNK BF_PTR DES_PTR DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:solaris-shared:-KPIC:-m64 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign -M/usr/lib/ld/map.noexdata:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
++#
++"solaris-sparcv9-cc-sunw","cc:-xtarget=ultra -m32 -Qoption cg -xregs=no%appl -xO5 -xstrconst -xdepend -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -lc:BN_LLONG RC4_CHUNK_LL DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-m32 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
++#
++"solaris64-sparcv9-cc-sunw","cc:-xtarget=ultra -m64 -Qoption cg -xregs=no%appl -xO5 -xstrconst -xdepend -xspace -Xa -DB_ENDIAN::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -lc:BN_LLONG RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-m64 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):/usr/bin/ar rs::/64",
++"solaris-fips-sparcv9-cc-sunw","cc:-xtarget=ultra -m32 -Qoption cg -xregs=no%appl -xO5 -xstrconst -xdepend -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -lc:BN_LLONG RC4_CHUNK_LL DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${fips_sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-m32 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
++"solaris64-fips-sparcv9-cc-sunw","cc:-xtarget=ultra -m64 -Qoption cg -xregs=no%appl -xO5 -xstrconst -xdepend -xspace -Xa -DB_ENDIAN::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -lc:BN_LLONG RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${fips_sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-m64 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):/usr/bin/ar rs::/64",
++# Option -xF=%all instructs the compiler to place functions and data
++# variables into separate section fragments. This enables the link editor
++# to discard unused sections and files when linking wanboot-openssl.o
++"solaris64-sparcv9-cc-sunw-wanboot","cc:-xtarget=ultra -m64 -Qoption cg -xregs=no%appl -xO5 -xstrconst -xdepend -xspace -xannotate=no -xF=%all -Xa -DB_ENDIAN::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl:BN_LLONG RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-m64 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):/usr/bin/ar rs::/64",
++
+ #### IRIX 5.x configs
+ # -mips2 flag is added by ./config when appropriate.
+ "irix-gcc","gcc:-O3 -DB_ENDIAN::(unknown):::BN_LLONG MD2_CHAR RC4_INDEX RC4_CHAR RC4_CHUNK DES_UNROLL DES_RISC2 DES_PTR BF_PTR:${mips32_asm}:o32:dlfcn:irix-shared:::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/patches/020-remove_rpath.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,11 @@
+--- /export/openssl/openssl-1.0.0d/Makefile.shared	Sat Aug 21 13:36:49 2010
++++ openssl-1.0.0d/Makefile.shared	Mon Feb 14 14:25:51 2011
+@@ -393,7 +393,7 @@
+ 	@ if $(DETECT_GNU_LD); then \
+ 		$(DO_GNU_APP); \
+ 	else \
+-		LDFLAGS="$(CFLAGS) -R $(LIBRPATH)"; \
++		LDFLAGS="$(CFLAGS)"; \
+ 	fi; \
+ 	$(LINK_APP)
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/patches/023-noexstack.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,21 @@
+--- /tmp/Makefile.shared	Mon Feb 14 14:33:05 2011
++++ openssl-1.0.0d/Makefile.shared	Mon Feb 14 14:35:56 2011
+@@ -389,6 +389,7 @@
+ 		SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX -Wl,-Bsymbolic"; \
+ 	fi; \
+ 	$(LINK_SO_A)
++# Make sure the apps have non-executable stacks and data (x86/x64 only).
+ link_app.solaris:
+ 	@ if $(DETECT_GNU_LD); then \
+ 		$(DO_GNU_APP); \
+@@ -395,6 +396,10 @@
+ 	else \
+ 		LDFLAGS="$(CFLAGS)"; \
+ 	fi; \
++	if expr $(PLATFORM) : '.*x86.*' > /dev/null; then \
++		LDFLAGS="$${LDFLAGS} -M/usr/lib/ld/map.noexdata"; \
++	fi; \
++	LDFLAGS="$${LDFLAGS} -M/usr/lib/ld/map.noexstk -M/usr/lib/ld/map.pagealign"; \
+ 	$(LINK_APP)
+ 
+ # OpenServer 5 native compilers used
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/patches/027-6978791.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,12 @@
+--- /tmp/Makefile.shared	Mon Feb 14 14:39:29 2011
++++ openssl-1.0.0d/Makefile.shared	Mon Feb 14 14:50:52 2011
+@@ -387,6 +387,9 @@
+ 		ALLSYMSFLAGS="$${MINUSZ}allextract"; \
+ 		NOALLSYMSFLAGS="$${MINUSZ}defaultextract"; \
+ 		SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX -Wl,-Bsymbolic"; \
++		if [ $(LIBNAME) = "ssl" ]; then \
++			SHAREDFLAGS="$$SHAREDFLAGS $${MINUSZ}nodelete"; \
++		fi; \
+ 	fi; \
+ 	$(LINK_SO_A)
+ # Make sure the apps have non-executable stacks and data (x86/x64 only).
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/patches/028-enginesdir.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,54 @@
+#
+# This was developed in house to configure the engine dir.
+# Not suitable for upstream.
+#
+--- /tmp/18/Configure	Fri Feb 11 15:15:50 2011
++++ openssl-1.0.0d/Configure	Fri Feb 11 15:18:09 2011
+@@ -18,6 +18,8 @@
+ #               --prefix option is given; /usr/local/ssl otherwise)
+ # --prefix      prefix for the OpenSSL include, lib and bin directories
+ #               (Default: the OPENSSLDIR directory)
++# --enginesdir  engines shared library location
++#               (Default: $prefix/lib/engines)
+ #
+ # --pk11-libname  PKCS#11 library name.
+ #               (Default: none)
+@@ -741,6 +743,7 @@
+ my $prefix="";
+ my $libdir="";
+ my $openssldir="";
++my $enginesdir="";
+ my $exe_ext="";
+ my $install_prefix= "$ENV{'INSTALL_PREFIX'}";
+ my $cross_compile_prefix="";
+@@ -972,6 +975,10 @@
+ 				{
+ 				$openssldir=$1;
+ 				}
++			elsif (/^--enginesdir=(.*)$/)
++				{
++				$enginesdir=$1;
++				}
+ 			elsif (/^--install.prefix=(.*)$/)
+ 				{
+ 				$install_prefix=$1;
+@@ -1285,6 +1292,10 @@
+ # we're ready to tolerate, so don't...
+ $multilib="" if !-d "$prefix/lib$multilib";
+ 
++if ($enginesdir eq "") {
++	$enginesdir = "$prefix/lib/engines";
++}
++
+ $libdir="lib$multilib" if $libdir eq "";
+ 
+ $cflags = "$cflags$exp_cflags";
+@@ -1934,7 +1945,7 @@
+ 		}
+ 	elsif	(/^#define\s+ENGINESDIR/)
+ 		{
+-		my $foo = "$prefix/$libdir/engines";
++		my $foo = "$enginesdir";
+ 		$foo =~ s/\\/\\\\/g;
+ 		print OUT "#define ENGINESDIR \"$foo\"\n";
+ 		}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/patches/029-fork_safe.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,276 @@
+#
+# This file adds the code to setup internal mutexes and callback function.
+#	PSARC/2014/077
+#	PSARC/2015/043
+# This change was implemented in-house.  The issue was brought up to
+# the upstream engineers, but there was no commitment.
+#
+--- a/crypto/cryptlib.c	2016-05-03 06:44:42.000000000 -0700
++++ b/crypto/cryptlib.c	2016-09-02 08:47:23.640202700 -0700
+@@ -116,6 +116,7 @@
+ 
+ #include "cryptlib.h"
+ #include <openssl/safestack.h>
++#include <pthread.h>
+ 
+ #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
+ static double SSLeay_MSVC5_hack = 0.0; /* and for VC1.5 */
+@@ -184,6 +185,8 @@
+  */
+ static STACK_OF(CRYPTO_dynlock) *dyn_locks = NULL;
+ 
++static pthread_mutex_t *solaris_openssl_locks;
++
+ static void (MS_FAR *locking_callback) (int mode, int type,
+                                         const char *file, int line) = 0;
+ static int (MS_FAR *add_lock_callback) (int *pointer, int amount,
+@@ -373,7 +376,10 @@
+ void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func)
+                                          (const char *file, int line))
+ {
+-    dynlock_create_callback = func;
++    /*
++     * we now setup our own dynamic locking callback, and disallow
++     * setting of another locking callback.
++     */
+ }
+ 
+ void CRYPTO_set_dynlock_lock_callback(void (*func) (int mode,
+@@ -382,7 +388,10 @@
+                                                     const char *file,
+                                                     int line))
+ {
+-    dynlock_lock_callback = func;
++    /*
++     * we now setup our own dynamic locking callback, and disallow
++     * setting of another locking callback.
++     */
+ }
+ 
+ void CRYPTO_set_dynlock_destroy_callback(void (*func)
+@@ -389,7 +398,10 @@
+                                           (struct CRYPTO_dynlock_value *l,
+                                            const char *file, int line))
+ {
+-    dynlock_destroy_callback = func;
++    /*
++     * we now setup our own dynamic locking callback, and disallow
++     * setting of another locking callback.
++     */
+ }
+ 
+ void (*CRYPTO_get_locking_callback(void)) (int mode, int type,
+@@ -402,6 +414,127 @@
+     return (add_lock_callback);
+ }
+ 
++/*
++ * This is the locking callback function which all applications will be
++ * using when CRYPTO_lock() is called.
++ */ 
++static void solaris_locking_callback(int mode, int type, const char *file,
++    int line)
++{
++    if (mode & CRYPTO_LOCK) {
++        (void) pthread_mutex_lock(&solaris_openssl_locks[type]);
++    } else {
++        (void) pthread_mutex_unlock(&solaris_openssl_locks[type]);
++    }
++}
++
++/*
++ * Implement Solaris's own dynamic locking routines.
++ */
++static struct CRYPTO_dynlock_value *
++solaris_dynlock_create(const char *file, int line)
++{
++    int                        ret;
++    pthread_mutex_t    *dynlock;
++
++    dynlock = OPENSSL_malloc(sizeof(pthread_mutex_t));
++    if (dynlock == NULL) {
++        return (NULL);
++    }
++
++    ret = pthread_mutex_init(dynlock, NULL);
++    OPENSSL_assert(ret == 0);
++
++    return ((struct CRYPTO_dynlock_value *)dynlock);
++}
++
++static void
++solaris_dynlock_lock(int mode, struct CRYPTO_dynlock_value *dynlock,
++    const char *file, int line)
++{
++    int        ret;
++
++    if (mode & CRYPTO_LOCK) {
++        ret = pthread_mutex_lock((pthread_mutex_t *)dynlock);
++    } else {
++        ret = pthread_mutex_unlock((pthread_mutex_t *)dynlock);
++    }
++
++    OPENSSL_assert(ret == 0);
++}
++
++static void
++solaris_dynlock_destroy(struct CRYPTO_dynlock_value *dynlock,
++    const char *file, int line)
++{
++    int ret;
++    ret = pthread_mutex_destroy((pthread_mutex_t *)dynlock);
++    OPENSSL_assert(ret == 0);
++}
++
++
++static void solaris_fork_prep(void)
++{
++    int i;
++
++    for (i = 0; i < CRYPTO_NUM_LOCKS; i++) {
++        (void) pthread_mutex_lock(&solaris_openssl_locks[i]);
++    }
++}
++
++static void solaris_fork_post(void)
++{
++    int i;
++
++    for (i = CRYPTO_NUM_LOCKS - 1; i >= 0; i--) {
++        (void) pthread_mutex_unlock(&solaris_openssl_locks[i]);
++    }
++
++    OPENSSL_assert(dynlock_create_callback == solaris_dynlock_create);
++    OPENSSL_assert(dynlock_lock_callback == solaris_dynlock_lock);
++    OPENSSL_assert(dynlock_destroy_callback == solaris_dynlock_destroy);
++    OPENSSL_assert(locking_callback == solaris_locking_callback);
++}
++
++/*
++ * This is called by the _init() function to setup locks used by OpenSSL
++ * and locking callback functions.
++ */
++void
++solaris_locking_setup()
++{
++    int i;
++
++    /* setup the dynlock callback if not already */
++    if (dynlock_create_callback == NULL) {
++        dynlock_create_callback = solaris_dynlock_create;
++    }
++    if (dynlock_lock_callback == NULL) {
++        dynlock_lock_callback = solaris_dynlock_lock;
++    }
++    if (dynlock_destroy_callback == NULL) {
++        dynlock_destroy_callback = solaris_dynlock_destroy;
++    }
++    if (locking_callback == NULL) {
++	    locking_callback = solaris_locking_callback;
++    }
++
++    /* allocate and initialize locks needed by OpenSSL  */
++    solaris_openssl_locks =
++        OPENSSL_malloc(sizeof (pthread_mutex_t) * CRYPTO_NUM_LOCKS);
++    if (solaris_openssl_locks == NULL) {
++        fprintf(stderr,
++            "solaris_locking_setup: memory allocation failure.\n");
++        abort();
++    }
++    for (i = 0; i < CRYPTO_NUM_LOCKS; i++) {
++        (void) pthread_mutex_init(&solaris_openssl_locks[i], NULL);
++    }
++
++    (void) pthread_atfork(solaris_fork_prep, solaris_fork_post, solaris_fork_post);
++}
++
++
+ void CRYPTO_set_locking_callback(void (*func) (int mode, int type,
+                                                const char *file, int line))
+ {
+@@ -410,7 +541,11 @@
+      * started.
+      */
+     OPENSSL_init();
+-    locking_callback = func;
++
++    /*
++     * we now setup our own locking callback and mutexes, and disallow
++     * setting of another locking callback.
++     */
+ }
+ 
+ void CRYPTO_set_add_lock_callback(int (*func) (int *num, int mount, int type,
+@@ -471,9 +606,10 @@
+ 
+ int CRYPTO_THREADID_set_callback(void (*func) (CRYPTO_THREADID *))
+ {
+-    if (threadid_callback)
+-        return 0;
+-    threadid_callback = func;
++    /*
++     * Use the backup method (the address of 'errno') to identify the
++     * thread and disallow setting the threadid callback.
++     */
+     return 1;
+ }
+ 
+@@ -529,7 +665,10 @@
+ 
+ void CRYPTO_set_id_callback(unsigned long (*func) (void))
+ {
+-    id_callback = func;
++    /*
++     * Use the backup method to identify the thread/process.
++     * Setting the id callback is disallowed.
++     */
+ }
+ 
+ unsigned long CRYPTO_thread_id(void)
+--- openssl-1.0.1f/crypto/cryptlib.h.~1~	Fri Feb  7 10:41:42 2014
++++ openssl-1.0.1f/crypto/cryptlib.h	Thu Feb  6 16:04:16 2014
+@@ -104,6 +104,8 @@
+ void *OPENSSL_stderr(void);
+ extern int OPENSSL_NONPIC_relocated;
+ 
++void solaris_locking_setup();
++
+ #ifdef  __cplusplus
+ }
+ #endif
+--- openssl-1.0.1f/crypto/sparccpuid.S.~1~	Fri Feb  7 10:41:37 2014
++++ openssl-1.0.1f/crypto/sparccpuid.S	Thu Feb  6 16:04:14 2014
+@@ -525,5 +525,7 @@
+ .size	_sparcv9_vis1_instrument_bus2,.-_sparcv9_vis1_instrument_bus2
+
+ .section	".init",#alloc,#execinstr
++	call	solaris_locking_setup
++	nop
+ 	call	OPENSSL_cpuid_setup
+ 	nop
+--- openssl-1.0.1f/crypto/x86_64cpuid.pl.~1~	Wed Feb 12 13:20:09 2014
++++ openssl-1.0.1f/crypto/x86_64cpuid.pl	Wed Feb 12 13:21:20 2014
+@@ -20,7 +20,10 @@
+ print<<___;
+ .extern		OPENSSL_cpuid_setup
+ .hidden		OPENSSL_cpuid_setup
++.extern		solaris_locking_setup
++.hidden		solaris_locking_setup
+ .section	.init
++	call	solaris_locking_setup
+ 	call	OPENSSL_cpuid_setup
+ 
+ .hidden	OPENSSL_ia32cap_P
+--- openssl-1.0.1f/crypto/x86cpuid.pl.~1~	Wed Feb 12 13:38:03 2014
++++ openssl-1.0.1f/crypto/x86cpuid.pl	Wed Feb 12 13:38:31 2014
+@@ -379,8 +379,10 @@
+ 	&ret	();
+ &function_end_B("OPENSSL_ia32_rdseed");
+ 
++&initseg("solaris_locking_setup");
+ &initseg("OPENSSL_cpuid_setup");
+ 
++&hidden("solaris_locking_setup");
+ &hidden("OPENSSL_cpuid_setup");
+ &hidden("OPENSSL_ia32cap_P");
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/patches/032-aes_cbc_len_check.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,18 @@
+#
+# This was developed in house and reported to the upstream.
+#
+--- openssl-1.0.1e/crypto/evp/e_aes.c        Tue Jul  2 11:03:12 2013
++++ openssl-1.0.1e/crypto/evp/e_aes.c.new    Tue Jul  2 11:04:56 2013
+@@ -1016,8 +1016,12 @@
+ static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
+                           const unsigned char *in, size_t len)
+ {
++    size_t	bl = ctx->cipher->block_size;
+     EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data;
+ 
++    if (len < bl)
++        return 1;
++
+     if (dat->stream.cbc)
+         (*dat->stream.cbc) (in, out, len, &dat->ks, ctx->iv, ctx->encrypt);
+     else if (ctx->encrypt)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/patches/036-evp_leak.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,144 @@
+Patch developed in-house.  Solaris-specific; not suitable for upstream.
+
+--- openssl-1.0.1f/crypto/evp/evp_enc.c.orig    Mon Feb 11 07:26:04 2013
++++ openssl-1.0.1f/crypto/evp/evp_enc.c    Mon Feb  3 16:40:48 2014
+@@ -392,11 +392,13 @@
+
+     if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
+         ret = M_do_cipher(ctx, out, NULL, 0);
+-        if (ret < 0)
+-            return 0;
+-        else
++        if (ret < 0) {
++            ret = 0;
++            goto cleanup;
++        } else
+             *outl = ret;
+-        return 1;
++        ret = 1;
++        goto cleanup;
+     }
+
+     b = ctx->cipher->block_size;
+@@ -403,7 +405,8 @@
+     OPENSSL_assert(b <= sizeof ctx->buf);
+     if (b == 1) {
+         *outl = 0;
+-        return 1;
++        ret = 1;
++        goto cleanup;
+     }
+     bl = ctx->buf_len;
+     if (ctx->flags & EVP_CIPH_NO_PADDING) {
+@@ -410,10 +413,12 @@
+         if (bl) {
+             EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX,
+                    EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
+-            return 0;
++            ret = 0;
++            goto cleanup;
+         }
+         *outl = 0;
+-        return 1;
++        ret = 1;
++        goto cleanup;
+     }
+ 
+     n = b - bl;
+@@ -424,6 +429,11 @@
+     if (ret)
+         *outl = b;
+ 
++cleanup:
++    if (ctx->cipher->cleanup) {
++        ctx->cipher->cleanup(ctx);
++    }
++
+     return ret;
+ }
+ 
+@@ -491,6 +501,7 @@
+ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
+ {
+     int i, n;
++    int err = 1;
+     unsigned int b;
+     *outl = 0;
+ 
+@@ -496,11 +507,13 @@
+
+     if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
+         i = M_do_cipher(ctx, out, NULL, 0);
+-        if (i < 0)
+-            return 0;
+-        else
++        if (i < 0) {
++            err = 0;
++            goto cleanup;
++        } else
+             *outl = i;
+-        return 1;
++        err = 1;
++        goto cleanup;
+     }
+
+     b = ctx->cipher->block_size;
+@@ -508,10 +521,12 @@
+         if (ctx->buf_len) {
+             EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,
+                    EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
+-            return 0;
++            err = 0;
++            goto cleanup;
+         }
+         *outl = 0;
+-        return 1;
++        err = 1;
++        goto cleanup;
+     }
+     if (b > 1) {
+         if (ctx->buf_len || !ctx->final_used) {
+@@ -516,7 +531,8 @@
+     if (b > 1) {
+         if (ctx->buf_len || !ctx->final_used) {
+             EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_WRONG_FINAL_BLOCK_LENGTH);
+-            return (0);
++            err = 0;
++            goto cleanup;
+         }
+         OPENSSL_assert(b <= sizeof ctx->final);
+ 
+@@ -527,7 +543,8 @@
+         n = ctx->final[b - 1];
+         if (n == 0 || n > (int)b) {
+             EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT);
+-            return (0);
++            err = 0;
++            goto cleanup;
+         }
+         for (i = 0; i < n; i++) {
+             if (ctx->final[--b] != n) {
+@@ -532,7 +549,8 @@
+         for (i = 0; i < n; i++) {
+             if (ctx->final[--b] != n) {
+                 EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT);
+-                return (0);
++                err = 0;
++                goto cleanup;
+             }
+         }
+         n = ctx->cipher->block_size - n;
+@@ -541,7 +559,12 @@
+         *outl = n;
+     } else
+         *outl = 0;
+-    return (1);
++    err = 1;
++cleanup:
++    if (ctx->cipher->cleanup) {
++        ctx->cipher->cleanup(ctx);
++    }
++    return err;
+ }
+ 
+ void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/patches/039-internal_tests.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,17 @@
+#
+# Patch developed in-house. Solaris-specific; not suitable for upstream.
+#
+# Remove test 'test_ca' because it depends on directories
+# not present in the build directory. The rest of tests are ok.
+#
+--- a/test/Makefile.orig	Thu Apr  2 12:11:12 2015
++++ b/test/Makefile	Thu Apr  2 12:11:21 2015
+@@ -156,7 +156,7 @@
+ 	test_rand test_bn test_ec test_ecdsa test_ecdh \
+ 	test_enc test_x509 test_rsa test_crl test_sid \
+ 	test_gen test_req test_pkcs7 test_verify test_dh test_dsa \
+-	test_ss test_ca test_engine test_evp test_evp_extra test_ssl test_tsa test_ige \
++	test_ss test_engine test_evp test_evp_extra test_ssl test_tsa test_ige \
+ 	test_jpake test_srp test_cms test_ocsp test_v3name test_heartbeat \
+ 	test_constant_time test_verify_extra test_clienthello test_sslv2conftest \
+ 	test_dtls test_bad_dtls
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/patches/040-uninitialized_ctx.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,14 @@
+#
+# This was developed in house.  Upstreadm notified (PR#277).
+#
+diff -ru  openssl-1.0.1m/crypto/evp/evp_enc.c openssl-1.0.1m/crypto/evp/evp_enc.c.new
+--- openssl-1.0.1m/crypto/evp/evp_enc.c Thu May  7 09:46:32 2015
++++ openssl-1.0.1m/crypto/evp/evp_enc.c.new     Thu May  7 09:46:23 2015
+@@ -185,6 +185,7 @@
+                 EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE);
+                 return 0;
+             }
++            (void) memset(ctx->cipher_data, 0, ctx->cipher->ctx_size);
+         } else {
+             ctx->cipher_data = NULL;
+         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/patches/041_rm_sslv2_v3.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,521 @@
+#
+# This was developed in house.  Not applicable to the upstream.
+#
+--- openssl-1.0.1/ssl/ssl.h	Tue May 26 11:13:15 2015
++++ openssl-1.0.1/ssl/ssl.h.new	Tue May 26 11:32:09 2015
+@@ -2345,10 +2345,23 @@
+ /* This sets the 'default' SSL version that SSL_new() will create */
+ int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth);
+ 
++#ifndef __has_attribute
++# define __has_attribute(x) 0
++#endif
++
++/* Mark SSLv2_* functions deprecated */
++#if __has_attribute(deprecated) \
++    || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 301)) \
++    || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5130))
++# define DEPRECATED __attribute__((deprecated))
++#else
++# define DEPRECATED
++#endif
++
+ # ifndef OPENSSL_NO_SSL2_METHOD
+-const SSL_METHOD *SSLv2_method(void); /* SSLv2 */
+-const SSL_METHOD *SSLv2_server_method(void); /* SSLv2 */
+-const SSL_METHOD *SSLv2_client_method(void); /* SSLv2 */
++DEPRECATED const SSL_METHOD *SSLv2_method(void); /* SSLv2 */
++DEPRECATED const SSL_METHOD *SSLv2_server_method(void); /* SSLv2 */
++DEPRECATED const SSL_METHOD *SSLv2_client_method(void); /* SSLv2 */
+ # endif
+ 
+ # ifndef OPENSSL_NO_SSL3_METHOD
+--- openssl-1.0.1/doc/ssl/SSL_CIPHER_get_name.pod	Tue May 26 11:13:15 2015
++++ openssl-1.0.1/doc/ssl/SSL_CIPHER_get_name.pod.new	Tue May 26 11:32:09 2015
+@@ -25,7 +25,7 @@
+ 
+ SSL_CIPHER_get_version() returns string which indicates the SSL/TLS protocol
+ version that first defined the cipher.
+-This is currently B<SSLv2> or B<TLSv1/SSLv3>.
++This is currently B<TLSv1/SSLv3>.
+ In some cases it should possibly return "TLSv1.2" but does not;
+ use SSL_CIPHER_description() instead.
+ If B<cipher> is NULL, "(NONE)" is returned.
+@@ -56,7 +56,7 @@
+ 
+ =item <protocol version>
+ 
+-Protocol version: B<SSLv2>, B<SSLv3>, B<TLSv1.2>. The TLSv1.0 ciphers are
++Protocol version: B<SSLv3>, B<TLSv1.2>. The TLSv1.0 ciphers are
+ flagged with SSLv3. No new ciphers were added by TLSv1.1.
+ 
+ =item Kx=<key exchange>
+--- openssl-1.x/doc/ssl/SSL_CTX_new.pod	Tue Jan 20 04:33:36 2015
++++ openssl-1.x/doc/ssl/SSL_CTX_new.pod.new	Tue May 26 11:37:24 2015
+@@ -8,7 +8,6 @@
+ TLSv1_1_method, TLSv1_1_server_method, TLSv1_1_client_method,
+ TLSv1_method, TLSv1_server_method, TLSv1_client_method,
+ SSLv3_method, SSLv3_server_method, SSLv3_client_method,
+-SSLv2_method, SSLv2_server_method, SSLv2_client_method,
+ DTLS_method, DTLS_server_method, DTLS_client_method,
+ DTLSv1_2_method, DTLSv1_2_server_method, DTLSv1_2_client_method,
+ DTLSv1_method, DTLSv1_server_method, DTLSv1_client_method -
+@@ -70,7 +69,7 @@
+ These are the general-purpose I<version-flexible> SSL/TLS methods.
+ The actual protocol version used will be negotiated to the highest version
+ mutually supported by the client and the server.
+-The supported protocols are SSLv2, SSLv3, TLSv1, TLSv1.1 and TLSv1.2.
++The supported protocols are TLSv1, TLSv1.1 and TLSv1.2.
+ Most applications should use these method, and avoid the version specific
+ methods described below.
+ 
+@@ -116,20 +115,11 @@
+ =item SSLv3_method(), SSLv3_server_method(), SSLv3_client_method()
+ 
+ A TLS/SSL connection established with these methods will only understand the
+-SSLv3 protocol.  A client will send out SSLv3 client hello messages and will
+-indicate that it only understands SSLv3.  A server will only understand SSLv3
+-client hello messages.  The SSLv3 protocol is deprecated and should not be
+-used.
++SSLv3 protocol. However, SSLv3 is not supported by this relese of OpenSSL.
+ 
+ =item SSLv2_method(), SSLv2_server_method(), SSLv2_client_method()
+ 
+-A TLS/SSL connection established with these methods will only understand the
+-SSLv2 protocol.  A client will send out SSLv2 client hello messages and will
+-also indicate that it only understand SSLv2.  A server will only understand
+-SSLv2 client hello messages.  The SSLv2 protocol offers little to no security
+-and should not be used.
+-As of OpenSSL 1.0.2g, EXPORT ciphers and 56-bit DES are no longer available
+-with SSLv2.
++These functions are deprecated.
+ 
+ =item DTLS_method(), DTLS_server_method(), DTLS_client_method()
+ 
+--- openssl-1.0.1/doc/ssl/SSL_CTX_set_cipher_list.pod	Thu Mar 19 06:37:10 2015
++++ openssl-1.0.1/doc/ssl/SSL_CTX_set_cipher_list.pod.new	Tue May 26 11:38:09 2015
+@@ -54,10 +54,6 @@
+ keys), the "no shared cipher" (SSL_R_NO_SHARED_CIPHER) error is generated
+ and the handshake will fail.
+ 
+-If the cipher list does not contain any SSLv2 cipher suites (this is the
+-default) then SSLv2 is effectively disabled and neither clients nor servers
+-will attempt to use SSLv2.
+-
+ =head1 RETURN VALUES
+ 
+ SSL_CTX_set_cipher_list() and SSL_set_cipher_list() return 1 if any cipher
+--- openssl-1.0.1/doc/ssl/SSL_CTX_set_generate_session_id.pod	Thu Jan 15 06:43:49 2015
++++ openssl-1.0.1/doc/ssl/SSL_CTX_set_generate_session_id.pod.new	Tue May 26 11:40:47 2015
+@@ -32,9 +32,8 @@
+ 
+ When a new session is established between client and server, the server
+ generates a session id. The session id is an arbitrary sequence of bytes.
+-The length of the session id is 16 bytes for SSLv2 sessions and between
+-1 and 32 bytes for SSLv3/TLSv1. The session id is not security critical
+-but must be unique for the server. Additionally, the session id is
++The length of the session id is between 1 and 32 bytes for TLSv1. The session id is not
++security critical but must be unique for the server. Additionally, the session id is
+ transmitted in the clear when reusing the session so it must not contain
+ sensitive information.
+ 
+@@ -51,12 +50,6 @@
+ the callback B<must never> increase B<id_len> or write to the location
+ B<id> exceeding the given limit.
+ 
+-If a SSLv2 session id is generated and B<id_len> is reduced, it will be
+-restored after the callback has finished and the session id will be padded
+-with 0x00. It is not recommended to change the B<id_len> for SSLv2 sessions.
+-The callback can use the L<SSL_get_version(3)|SSL_get_version(3)> function
+-to check, whether the session is of type SSLv2.
+-
+ The location B<id> is filled with 0x00 before the callback is called, so the
+ callback may only fill part of the possible length and leave B<id_len>
+ untouched while maintaining reproducibility.
+@@ -63,9 +56,8 @@
+ 
+ Since the sessions must be distinguished, session ids must be unique.
+ Without the callback a random number is used, so that the probability
+-of generating the same session id is extremely small (2^128 possible ids
+-for an SSLv2 session, 2^256 for SSLv3/TLSv1). In order to assure the
+-uniqueness of the generated session id, the callback must call
++of generating the same session id is extremely small (2^256 for TLSv1).
++In order to assure the uniqueness of the generated session id, the callback must call
+ SSL_has_matching_session_id() and generate another id if a conflict occurs.
+ If an id conflict is not resolved, the handshake will fail.
+ If the application codes e.g. a unique host id, a unique process number, and
+@@ -85,10 +77,6 @@
+ the external cache is not tested with SSL_has_matching_session_id()
+ and the same race condition applies.
+ 
+-When calling SSL_has_matching_session_id() for an SSLv2 session with
+-reduced B<id_len>, the match operation will be performed using the
+-fixed length required and with a 0x00 padded id.
+-
+ The callback must return 0 if it cannot generate a session id for whatever
+ reason and return 1 on success.
+ 
+@@ -104,12 +92,7 @@
+                               unsigned int *id_len)
+       {
+       unsigned int count = 0;
+-      const char *version;
+ 
+-      version = SSL_get_version(ssl);
+-      if (!strcmp(version, "SSLv2"))
+-	  /* we must not change id_len */;
+-
+       do      {
+               RAND_pseudo_bytes(id, *id_len);
+               /* Prefix the session_id with the required prefix. NB: If our
+--- openssl-1.0.1/doc/ssl/SSL_CTX_set_options.pod	Tue Jan 20 04:33:36 2015
++++ openssl-1.0.1/doc/ssl/SSL_CTX_set_options.pod.new	Tue May 26 11:41:47 2015
+@@ -63,18 +63,11 @@
+ 
+ =item SSL_OP_MICROSOFT_SESS_ID_BUG
+ 
+-www.microsoft.com - when talking SSLv2, if session-id reuse is
+-performed, the session-id passed back in the server-finished message
+-is different from the one decided upon.
++As of OpenSSL 1.0.0 this option has no effect.
+ 
+ =item SSL_OP_NETSCAPE_CHALLENGE_BUG
+ 
+-Netscape-Commerce/1.12, when talking SSLv2, accepts a 32 byte
+-challenge but then appears to only use 16 bytes when generating the
+-encryption keys.  Using 16 bytes is ok but it should be ok to use 32.
+-According to the SSLv3 spec, one should use 32 bytes for the challenge
+-when operating in SSLv2/v3 compatibility mode, but as mentioned above,
+-this breaks this server so 16 bytes is the way to go.
++As of OpenSSL 1.0.0 this option has no effect.
+ 
+ =item SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
+ 
+--- openssl-1.0.1/doc/ssl/SSL_get_default_timeout.pod	Thu Jan 15 06:43:49 2015
++++ openssl-1.0.1/doc/ssl/SSL_get_default_timeout.pod.new	Tue May 26 11:42:15 2015
+@@ -24,7 +24,7 @@
+ timeout for the protocol will be used.
+ 
+ SSL_get_default_timeout() return this hardcoded value, which is 300 seconds
+-for all currently supported protocols (SSLv2, SSLv3, and TLSv1).
++for all currently supported protocols.
+ 
+ =head1 RETURN VALUES
+ 
+--- openssl-1.0.1/doc/ssl/SSL_get_version.pod	Thu Jan 15 06:43:49 2015
++++ openssl-1.0.1/doc/ssl/SSL_get_version.pod.new	Tue May 26 11:42:45 2015
+@@ -21,14 +21,6 @@
+ 
+ =over 4
+ 
+-=item SSLv2
+-
+-The connection uses the SSLv2 protocol.
+-
+-=item SSLv3
+-
+-The connection uses the SSLv3 protocol.
+-
+ =item TLSv1
+ 
+ The connection uses the TLSv1.0 protocol.
+--- openssl-1.0.1/doc/ssl/SSL_new.pod	Thu Jan 15 06:43:49 2015
++++ openssl-1.0.1/doc/ssl/SSL_new.pod.new	Tue May 26 11:43:12 2015
+@@ -14,7 +14,7 @@
+ 
+ SSL_new() creates a new B<SSL> structure which is needed to hold the
+ data for a TLS/SSL connection. The new structure inherits the settings
+-of the underlying context B<ctx>: connection method (SSLv2/v3/TLSv1),
++of the underlying context B<ctx>: connection method,
+ options, verification settings, timeout settings.
+ 
+ =head1 RETURN VALUES
+--- openssl-1.0.1/doc/ssl/SSL_shutdown.pod	Thu Mar 19 06:37:10 2015
++++ openssl-1.0.1/doc/ssl/SSL_shutdown.pod.new	Tue May 26 11:43:56 2015
+@@ -60,9 +60,7 @@
+ 
+ It is therefore recommended, to check the return value of SSL_shutdown()
+ and call SSL_shutdown() again, if the bidirectional shutdown is not yet
+-complete (return value of the first call is 0). As the shutdown is not
+-specially handled in the SSLv2 protocol, SSL_shutdown() will succeed on
+-the first call.
++complete (return value of the first call is 0).
+ 
+ The behaviour of SSL_shutdown() additionally depends on the underlying BIO. 
+ 
+--- openssl-1.0.1/doc/ssl/ssl.pod	Thu Mar 19 06:37:10 2015
++++ openssl-1.0.1/doc/ssl/ssl.pod.new	Tue May 26 11:47:38 2015
+@@ -9,9 +9,8 @@
+ 
+ =head1 DESCRIPTION
+ 
+-The OpenSSL B<ssl> library implements the Secure Sockets Layer (SSL v2/v3) and
+-Transport Layer Security (TLS v1) protocols. It provides a rich API which is
+-documented here.
++The OpenSSL B<ssl> library implements the Transport Layer Security (TLS v1)
++protocols. It provides a rich API which is documented here.
+ 
+ At first the library must be initialized; see
+ L<SSL_library_init(3)|SSL_library_init(3)>.
+@@ -45,8 +44,8 @@
+ =item B<SSL_METHOD> (SSL Method)
+ 
+ That's a dispatch structure describing the internal B<ssl> library
+-methods/functions which implement the various protocol versions (SSLv1, SSLv2
+-and TLSv1). It's needed to create an B<SSL_CTX>.
++methods/functions which implement the various protocol versions (TLSv1, ...).
++It's needed to create an B<SSL_CTX>.
+ 
+ =item B<SSL_CIPHER> (SSL Cipher)
+ 
+@@ -105,8 +104,8 @@
+ 
+ =item B<ssl23.h>
+ 
+-That's the sub header file dealing with the combined use of the SSLv2 and
+-SSLv3 protocols.
++That's the sub header file dealing with the combined use of different
++protocol version.
+ I<Usually you don't have to include it explicitly because
+ it's already included by ssl.h>.
+ 
+@@ -201,15 +200,15 @@
+ =item const SSL_METHOD *B<SSLv2_method>(void);
+ 
+ Constructor for the SSLv2 SSL_METHOD structure for clients, servers
+-or both.
++or both. (deprecated)
+ 
+ =item const SSL_METHOD *B<SSLv2_client_method>(void);
+ 
+-Constructor for the SSLv2 SSL_METHOD structure for clients.
++Constructor for the SSLv2 SSL_METHOD structure for clients. (deprecated)
+ 
+ =item const SSL_METHOD *B<SSLv2_server_method>(void);
+ 
+-Constructor for the SSLv2 SSL_METHOD structure for servers.
++Constructor for the SSLv2 SSL_METHOD structure for servers. (deprecated)
+ 
+ =back
+ 
+@@ -234,12 +233,12 @@
+ =item const char *B<SSL_CIPHER_get_name>(SSL_CIPHER *cipher);
+ 
+ Return the internal name of I<cipher> as a string. These are the various
+-strings defined by the I<SSL2_TXT_xxx>, I<SSL3_TXT_xxx> and I<TLS1_TXT_xxx>
++strings defined by the I<SSL3_TXT_xxx> and I<TLS1_TXT_xxx>
+ definitions in the header files.
+ 
+ =item char *B<SSL_CIPHER_get_version>(SSL_CIPHER *cipher);
+ 
+-Returns a string like "C<TLSv1/SSLv3>" or "C<SSLv2>" which indicates the
++Returns a string like "C<TLSv1/SSLv3>" which indicates the
+ SSL/TLS protocol version to which I<cipher> belongs (i.e. where it was defined
+ in the specification the first time).
+ 
+--- openssl-1.0.1/doc/apps/ciphers.pod	Thu Mar 19 06:37:10 2015
++++ openssl-1.0.1/doc/apps/ciphers.pod.new	Tue May 26 12:07:35 2015
+@@ -26,26 +24,18 @@
+ 
+ =item B<-v>
+ 
+-Verbose option. List ciphers with a complete description of
+-protocol version (SSLv2 or SSLv3; the latter includes TLS), key exchange,
+-authentication, encryption and mac algorithms used along with any key size
+-restrictions and whether the algorithm is classed as an "export" cipher.
+-Note that without the B<-v> option, ciphers may seem to appear twice
+-in a cipher list; this is when similar ciphers are available for
+-SSL v2 and for SSL v3/TLS v1.
++Verbose option. List ciphers with a complete description of protocol version,
++key exchange, authentication, encryption and mac algorithms used along with any
++key size restrictions and whether the algorithm is classed as an "export" cipher.
+ 
+ =item B<-V>
+ 
+ Like B<-v>, but include cipher suite codes in output (hex format).
+ 
+-=item B<-ssl3>, B<-tls1>
++=item B<-tls1>
+ 
+-This lists ciphers compatible with any of SSLv3, TLSv1, TLSv1.1 or TLSv1.2.
++This lists ciphers compatible with any of TLSv1, TLSv1.1 or TLSv1.2.
+ 
+-=item B<-ssl2>
+-
+-Only include SSLv2 ciphers.
+-
+ =item B<-h>, B<-?>
+ 
+ Print a brief usage message.
+@@ -588,16 +580,6 @@
+  TLS_PSK_WITH_AES_128_CBC_SHA              PSK-AES128-CBC-SHA
+  TLS_PSK_WITH_AES_256_CBC_SHA              PSK-AES256-CBC-SHA
+ 
+-=head2 Deprecated SSL v2.0 cipher suites.
+-
+- SSL_CK_RC4_128_WITH_MD5                 RC4-MD5
+- SSL_CK_RC4_128_EXPORT40_WITH_MD5        Not implemented.
+- SSL_CK_RC2_128_CBC_WITH_MD5             RC2-CBC-MD5
+- SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5    Not implemented.
+- SSL_CK_IDEA_128_CBC_WITH_MD5            IDEA-CBC-MD5
+- SSL_CK_DES_64_CBC_WITH_MD5              Not implemented.
+- SSL_CK_DES_192_EDE3_CBC_WITH_MD5        DES-CBC3-MD5
+-
+ =head1 NOTES
+ 
+ Some compiled versions of OpenSSL may not include all the ciphers
+--- openssl-1.0.1/doc/apps/s_client.pod	Thu Mar 19 06:37:10 2015
++++ openssl-1.0.1/doc/apps/s_client.pod.new	Tue May 26 12:15:40 2015
+@@ -32,11 +32,9 @@
+ [B<-ign_eof>]
+ [B<-no_ign_eof>]
+ [B<-quiet>]
+-[B<-ssl2>]
+-[B<-ssl3>]
+ [B<-tls1>]
++[B<-tls1_1>]
++[B<-tls1_2>]
+-[B<-no_ssl2>]
+-[B<-no_ssl3>]
+ [B<-no_tls1>]
+ [B<-no_tls1_1>]
+ [B<-no_tls1_2>]
+@@ -201,9 +199,9 @@
+ given as a hexadecimal number without leading 0x, for example -psk
+ 1a2b3c4d.
+ 
+-=item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2>
++=item B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2>
+ 
+-These options require or disable the use of the specified SSL or TLS protocols.
++These options require or disable the use of the specified TLS protocols.
+ By default the initial handshake uses a I<version-flexible> method which will
+ negotiate the highest mutually supported protocol version.
+ 
+@@ -227,10 +225,6 @@
+ supported cipher in the list sent by the client. See the B<ciphers>
+ command for more information.
+ 
+-=item B<-serverpref>
+-
+-use the server's cipher preferences; only used for SSLV2.
+-
+ =item B<-starttls protocol>
+ 
+ send the protocol-specific message(s) to switch to TLS for communication.
+@@ -314,8 +308,8 @@
+ then an HTTP command can be given such as "GET /" to retrieve a web page.
+ 
+ If the handshake fails then there are several possible causes, if it is
+-nothing obvious like no client certificate then the B<-bugs>, B<-ssl2>,
+-B<-ssl3>, B<-tls1>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1> options can be tried
++nothing obvious like no client certificate then the B<-bugs>, B<-tls1>, B<-tls1_1>,
++B<-tls1_2>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2> options can be tried
+ in case it is a buggy server. In particular you should play with these
+ options B<before> submitting a bug report to an OpenSSL mailing list.
+ 
+@@ -337,10 +331,6 @@
+ If there are problems verifying a server certificate then the
+ B<-showcerts> option can be used to show the whole chain.
+ 
+-Since the SSLv23 client hello cannot include compression methods or extensions
+-these will only be supported if its use is disabled, for example by using the
+-B<-no_sslv2> option.
+-
+ The B<s_client> utility is a test tool and is designed to continue the
+ handshake after any certificate verification errors. As a result it will
+ accept any certificate chain (trusted or not) sent by the peer. None test
+--- openssl-1.0.1/doc/apps/s_server.pod Thu Mar 19 06:37:10 2015
++++ openssl-1.0.1/doc/apps/s_server.pod.new     Tue May 26 12:15:02 2015
+@@ -39,12 +39,12 @@
+ [B<-serverpref>]
+ [B<-quiet>]
+ [B<-no_tmp_rsa>]
+-[B<-ssl2>]
+-[B<-ssl3>]
+ [B<-tls1>]
+-[B<-no_ssl2>]
+-[B<-no_ssl3>]
++[B<-tls1_1>]
++[B<-tls1_2>]
+ [B<-no_tls1>]
++[B<-no_tls1_1>]
++[B<-no_tls1_2>]
+ [B<-no_dhe>]
+ [B<-bugs>]
+ [B<-hack>]
+@@ -217,9 +217,9 @@
+ given as a hexadecimal number without leading 0x, for example -psk
+ 1a2b3c4d.
+ 
+-=item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2>
++=item B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2>
+ 
+-These options require or disable the use of the specified SSL or TLS protocols.
++These options require or disable the use of the specified TLS protocols.
+ By default the initial handshake uses a I<version-flexible> method which will
+ negotiate the highest mutually supported protocol version.
+ 
+--- openssl-1.0.1/doc/apps/s_time.pod	Thu Jan 15 06:43:49 2015
++++ openssl-1.0.1/doc/apps/s_time.pod.new	Tue May 26 12:20:09 2015
+@@ -19,8 +19,6 @@
+ [B<-verify depth>]
+ [B<-nbio>]
+ [B<-time seconds>]
+-[B<-ssl2>]
+-[B<-ssl3>]
+ [B<-bugs>]
+ [B<-cipher cipherlist>]
+ 
+@@ -92,19 +90,6 @@
+ 
+ turns on non-blocking I/O.
+ 
+-=item B<-ssl2>, B<-ssl3>
+-
+-these options disable the use of certain SSL or TLS protocols. By default
+-the initial handshake uses a method which should be compatible with all
+-servers and permit them to use SSL v3, SSL v2 or TLS as appropriate.
+-The timing program is not as rich in options to turn protocols on and off as
+-the L<s_client(1)|s_client(1)> program and may not connect to all servers.
+-
+-Unfortunately there are a lot of ancient and broken servers in use which
+-cannot handle this technique and will fail to connect. Some servers only
+-work if TLS is turned off with the B<-ssl3> option; others
+-will only support SSL v2 and may need the B<-ssl2> option.
+-
+ =item B<-bugs>
+ 
+ there are several known bug in SSL and TLS implementations. Adding this
+@@ -137,8 +122,7 @@
+ for details.
+ 
+ If the handshake fails then there are several possible causes, if it is
+-nothing obvious like no client certificate then the B<-bugs>, B<-ssl2>,
+-B<-ssl3> options can be tried
++nothing obvious like no client certificate then the B<-bugs> option can be tried
+ in case it is a buggy server. In particular you should play with these
+ options B<before> submitting a bug report to an OpenSSL mailing list.
+ 
+--- openssl-1.0.1/doc/apps/sess_id.pod	Thu Jan 15 06:43:49 2015
++++ openssl-1.0.1/doc/apps/sess_id.pod.new	Tue May 26 12:21:07 2015
+@@ -91,7 +91,7 @@
+ 
+ =item B<Protocol>
+ 
+-this is the protocol in use TLSv1, SSLv3 or SSLv2.
++this is the protocol in use.
+ 
+ =item B<Cipher>
+ 
+@@ -110,10 +110,6 @@
+ 
+ this is the SSL session master key.
+ 
+-=item B<Key-Arg>
+-
+-the key argument, this is only used in SSL v2.
+-
+ =item B<Start Time>
+ 
+ this is the session start time represented as an integer in standard Unix format.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/patches/043-x86_wrong_platform.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,15 @@
+#
+# This was developed in house to fix the wrong platform detection for Solaris.
+# Reported to the upstream.
+#
+--- openssl-1.0.2d/crypto/perlasm/x86gas.pl	Thu Jul  9 04:57:15 2015
++++ openssl-1.0.2d/crypto/perlasm/x86gas.pl.new	Thu Jul 30 15:17:14 2015
+@@ -196,8 +196,6 @@
+ 	    &::mov($dst,&::DWP("$indirect-$reflabel",$base));
+ 	    $non_lazy_ptr{"$nmdecor$sym"}=$indirect;
+ 	}
+-	elsif ($sym eq "OPENSSL_ia32cap_P" && $::elf>0)
+-	{   &::lea($dst,&::DWP("$sym-$reflabel",$base));   }
+ 	else
+ 	{   &::lea($dst,&::DWP("_GLOBAL_OFFSET_TABLE_+[.-$reflabel]",
+ 			    $base));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/patches/044-suppress_v8plus_abi_warnings.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,70 @@
+#
+# Patch developed in-house. Solaris-specific; not suitable for upstream.
+#
+# Suppress warnings about sparcv8+ ABI violation
+# when building T4-specific modules as 32-bit:
+#    v8+ ABI violation: illegal use of %i or %l register as rs1 in "brnz,a" instruction
+# This has been confirmed as a valid usecase and is thus intentional.
+#
+--- a/crypto/aes/Makefile.orig	čt dub 30 03:15:03 2015
++++ b/crypto/aes/Makefile	čt dub 30 03:19:32 2015
+@@ -75,6 +75,9 @@
+ aest4-sparcv9.s: asm/aest4-sparcv9.pl ../perlasm/sparcv9_modes.pl
+ 	$(PERL) asm/aest4-sparcv9.pl $(CFLAGS) > $@
+ 
++aest4-sparcv9.o: aest4-sparcv9.s
++	$(AS) $(ASFLAGS) -Wa,-n -o $@ $^
++
+ aes-ppc.s:	asm/aes-ppc.pl
+ 	$(PERL) asm/aes-ppc.pl $(PERLASM_SCHEME) $@
+ vpaes-ppc.s:	asm/vpaes-ppc.pl
+--- a/crypto/sha/Makefile.orig	čt dub 30 14:37:32 2015
++++ b/crypto/sha/Makefile	čt dub 30 14:40:49 2015
+@@ -73,6 +73,8 @@
+ sha1-sparcv9.S:	asm/sha1-sparcv9.pl;	$(PERL) asm/sha1-sparcv9.pl $@ $(CFLAGS)
+ sha256-sparcv9.S:asm/sha512-sparcv9.pl;	$(PERL) asm/sha512-sparcv9.pl $@ $(CFLAGS)
+ sha512-sparcv9.S:asm/sha512-sparcv9.pl;	$(PERL) asm/sha512-sparcv9.pl $@ $(CFLAGS)
++sha512-sparcv9.o: sha512-sparcv9.S
++	$(CC) $(CFLAGS) -Wa,-n -c -o $@ $^
+ 
+ sha1-ppc.s:	asm/sha1-ppc.pl;	$(PERL) asm/sha1-ppc.pl $(PERLASM_SCHEME) $@
+ sha256-ppc.s:	asm/sha512-ppc.pl;	$(PERL) asm/sha512-ppc.pl $(PERLASM_SCHEME) $@
+--- a/crypto/bn/Makefile.orig	čt dub 30 14:43:20 2015
++++ b/crypto/bn/Makefile	čt dub 30 14:45:11 2015
+@@ -79,8 +79,12 @@
+ 	$(PERL) asm/sparcv9-mont.pl $(CFLAGS) > $@
+ vis3-mont.s:		asm/vis3-mont.pl
+ 	$(PERL) asm/vis3-mont.pl $(CFLAGS) > $@
++vis3-mont.o:	vis3-mont.s
++	$(AS) $(ASFLAGS) -Wa,-n -o $@ $^
+ sparct4-mont.S:	asm/sparct4-mont.pl
+ 	$(PERL) asm/sparct4-mont.pl $(CFLAGS) > $@
++sparct4-mont.o:	sparct4-mont.S
++	$(CC) $(CFLAGS) -Wa,-n -c -o $@ $^
+ sparcv9-gf2m.S:	asm/sparcv9-gf2m.pl
+ 	$(PERL) asm/sparcv9-gf2m.pl $(CFLAGS) > $@
+ 
+--- a/crypto/camellia/Makefile.orig        Fri Aug 21 14:51:49 2015rypto/camellia/Makef
++++ b/crypto/camellia/Makefile     Fri Aug 21 14:53:18 2015.2d/crypto/camellia/Make
+@@ -51,6 +51,9 @@
+ cmllt4-sparcv9.s: asm/cmllt4-sparcv9.pl ../perlasm/sparcv9_modes.pl
+ 	$(PERL) asm/cmllt4-sparcv9.pl $(CFLAGS) > $@
+ 
++cmllt4-sparcv9.o: cmllt4-sparcv9.s
++	$(AS) $(ASFLAGS) -Wa,-n -o $@ $^
++
+ files:
+ 	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
+ 
+--- a/crypto/modes/Makefile.orig       Fri Aug 21 15:22:37 2015
++++ b/crypto/modes/Makefile    Fri Aug 21 15:26:12 2015
+@@ -54,6 +54,9 @@
+ 	$(PERL) asm/aesni-gcm-x86_64.pl $(PERLASM_SCHEME) > $@
+ ghash-sparcv9.s:	asm/ghash-sparcv9.pl
+ 	$(PERL) asm/ghash-sparcv9.pl $@ $(CFLAGS)
++ghash-sparcv9.o:	ghash-sparcv9.s
++	$(AS) $(ASFLAGS) -Wa,-n -o $@ $^
++
+ ghash-alpha.s:	asm/ghash-alpha.pl
+ 	([email protected]; trap "rm $$preproc" INT; \
+ 	$(PERL) asm/ghash-alpha.pl > $$preproc && \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/patches/045-openssl-usage.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,59 @@
+#
+# This patch fixes the usage bug: It shows '-ssl2' option even though it's not
+# available. The bug has been reported to the upstream: #3580.
+#
+--- openssl/apps/s_client.c.orig	Tue Sep 15 13:33:45 2015
++++ openssl/apps/s_client.c	Tue Sep 15 13:34:26 2015
+@@ -376,7 +376,9 @@
+                " -srp_strength int - minimal length in bits for N (default %d).\n",
+                SRP_MINIMAL_N);
+ #endif
++#ifndef OPENSSL_NO_SSL2
+     BIO_printf(bio_err, " -ssl2         - just use SSLv2\n");
++#endif
+ #ifndef OPENSSL_NO_SSL3_METHOD
+     BIO_printf(bio_err, " -ssl3         - just use SSLv3\n");
+ #endif
+--- openssl/apps/s_server.c.orig	Tue Sep 15 13:33:58 2015
++++ openssl/apps/s_server.c	Tue Sep 15 13:35:15 2015
+@@ -592,7 +592,9 @@
+     BIO_printf(bio_err,
+                " -srpuserseed string - A seed string for a default user salt.\n");
+ #endif
++#ifndef OPENSSL_NO_SSL2
+     BIO_printf(bio_err, " -ssl2         - Just talk SSLv2\n");
++#endif
+ #ifndef OPENSSL_NO_SSL3_METHOD
+     BIO_printf(bio_err, " -ssl3         - Just talk SSLv3\n");
+ #endif
+No differences encountered
+--- openssl/apps/s_time.c.orig	Tue Sep 15 13:33:53 2015
++++ openssl/apps/s_time.c	Tue Sep 15 13:35:01 2015
+@@ -190,8 +190,12 @@
+            SSL_CONNECT_NAME);
+ #ifdef FIONBIO
+     printf("-nbio         - Run with non-blocking IO\n");
++#ifndef OPENSSL_NO_SSL2
+     printf("-ssl2         - Just use SSLv2\n");
++#endif
++#ifndef OPENSSL_NO_SSL3_METHOD
+     printf("-ssl3         - Just use SSLv3\n");
++#endif
+     printf("-bugs         - Turn on SSL bug compatibility\n");
+     printf("-new          - Just time new connections\n");
+     printf("-reuse        - Just time connection reuse\n");
+--- openssl/apps/ciphers.c.orig	Tue Sep 15 13:34:02 2015
++++ openssl/apps/ciphers.c	Tue Sep 15 13:51:03 2015
+@@ -73,8 +73,12 @@
+     "usage: ciphers args\n",
+     " -v          - verbose mode, a textual listing of the SSL/TLS ciphers in OpenSSL\n",
+     " -V          - even more verbose\n",
++#ifndef OPENSSL_NO_SSL2
+     " -ssl2       - SSL2 mode\n",
++#endif
++#ifndef OPENSSL_NO_SSL3_METHOD
+     " -ssl3       - SSL3 mode\n",
++#endif
+     " -tls1       - TLS1 mode\n",
+     NULL
+ };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/patches/046-pkcs12-default-cipher.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,51 @@
+#
+# This was developed in house.  The change is internal to Solaris, and
+# it will not be contributed upstream.
+#
+# This patch will change the default cipher used to encrypt certificate
+# to 3DES as RC2 is considered weak cipher. The default cipher for 1.1 will
+# become 3DES.
+#
+--- openssl/apps/pkcs12.c	Tue May  3 06:44:42 2016
++++ openssl/apps/pkcs12.c.new	Wed May  4 15:11:00 2016
+@@ -142,12 +142,7 @@
+     if (!load_config(bio_err, NULL))
+         goto end;
+ 
+-# ifdef OPENSSL_FIPS
+-    if (FIPS_mode())
+-        cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+-    else
+-# endif
+-        cert_pbe = NID_pbe_WithSHA1And40BitRC2_CBC;
++    cert_pbe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC;
+ 
+     args = argv + 1;
+ 
+@@ -379,9 +374,9 @@
+         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");
++                   "-descert      encrypt PKCS#12 certificates with triple DES (default)\n");
+         BIO_printf(bio_err,
+-                   "-certpbe alg  specify certificate PBE algorithm (default RC2-40)\n");
++                   "-certpbe alg  specify certificate PBE algorithm (default 3DES)\n");
+         BIO_printf(bio_err,
+                    "-keypbe alg   specify private key PBE algorithm (default 3DES)\n");
+         BIO_printf(bio_err,
+--- openssl/doc/crypto/PKCS12_create.pod Fri May  6 09:10:00 2016
++++ openssl/doc/crypto/PKCS12_create.pod Fri May  6 09:14:16 2016
+@@ -30,9 +30,9 @@
+ The parameters B<nid_key>, B<nid_cert>, B<iter>, B<mac_iter> and B<keytype>
+ can all be set to zero and sensible defaults will be used.
+ 
+-These defaults are: 40 bit RC2 encryption for certificates, triple DES
+-encryption for private keys, a key iteration count of PKCS12_DEFAULT_ITER
+-(currently 2048) and a MAC iteration count of 1.
++These defaults are: triple DES encryption for certificates and private keys,
++a key iteration count of PKCS12_DEFAULT_ITER (currently 2048) and a MAC
++iteration count of 1.
+ 
+ The default MAC iteration count is 1 in order to retain compatibility with
+ old software which did not interpret MAC iteration counts. If such compatibility
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/patches/050-segfault_configfile.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,55 @@
+# This patch was developed in house.
+# The issue is fixed in the OpenSSL 1.1 release by the upstream,
+# but the code base has changed and the same fix can't be applied
+# without major code change.
+--- a/apps/ts.c	2016-06-21 13:43:24.299079900 -0700
++++ b/apps/ts.c	2016-06-21 14:06:28.055910010 -0700
+@@ -299,6 +299,9 @@
+             goto usage;
+         /* Load the config file for possible policy OIDs. */
+         conf = load_config_file(configfile);
++	 if (conf == NULL) {
++            goto cleanup;
++        }
+         ret = !query_command(data, digest, md, policy, no_nonce, cert,
+                              in, out, text);
+         break;
+@@ -401,6 +404,7 @@
+         else
+             BIO_printf(bio_err, "error on line %ld of config file "
+                        "'%s'\n", errorline, configfile);
++        goto errexit;
+     }
+ 
+     if (conf != NULL) {
+@@ -410,18 +414,27 @@
+         p = NCONF_get_string(conf, NULL, ENV_OID_FILE);
+         if (p != NULL) {
+             BIO *oid_bio = BIO_new_file(p, "r");
+-            if (!oid_bio)
++            if (!oid_bio) {
+                 ERR_print_errors(bio_err);
+-            else {
++                goto errexit;
++            } else {
+                 OBJ_create_objects(oid_bio);
+                 BIO_free_all(oid_bio);
+             }
+         } else
+             ERR_clear_error();
+-        if (!add_oid_section(bio_err, conf))
++        if (!add_oid_section(bio_err, conf)) {
+             ERR_print_errors(bio_err);
++            goto errexit;
++        }
+     }
+     return conf;
++
++errexit:
++    if (conf != NULL) {
++	NCONF_free(conf);
++    }
++    return (NULL);
+ }
+ 
+ /*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/patches/051-segfault_export.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,17 @@
+# This patch addresses multiple segmentation faults:
+# Pull Requests submitted to the upstream:
+#   https://github.com/openssl/openssl/pull/1243
+# Fixed by upstream:
+#   
+--- a/apps/s_client.c	Tue May  3 06:44:42 2016
++++ b/apps/s_client.c	Wed May  4 15:11:00 2016
+@@ -2633,7 +2633,8 @@ static void print_stuff(BIO *bio, SSL *s, int full)
+ #endif
+ 
+     SSL_SESSION_print(bio, SSL_get_session(s));
+-    if (keymatexportlabel != NULL) {
++    if ((SSL_get_session(s) != NULL) &&
++        (keymatexportlabel != NULL)) {
+         BIO_printf(bio, "Keying material exporter:\n");
+         BIO_printf(bio, "    Label: '%s'\n", keymatexportlabel);
+         BIO_printf(bio, "    Length: %i bytes\n", keymatexportlen);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/common/patches/054-xmpp-detection.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,17 @@
+# The patch is based on the following commit from the upstream:
+# https://github.com/openssl/openssl/commit/4e48c77572a9a96a301e362a3646cd3cc7eca0f9 
+# The fix is patched until the new version becomes available
+# from the upstream.
+--- a/apps/s_client.c
++++ b/apps/s_client.c
+@@ -1640,8 +1640,8 @@
+                    "xmlns='jabber:client' to='%s' version='1.0'>", host);
+         seen = BIO_read(sbio, mbuf, BUFSIZZ);
+         mbuf[seen] = 0;
+-        while (!strstr
+-               (mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'")) {
++        while (!strstr(mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'") &&
++               !strstr(mbuf, "<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"")) {
+             if (strstr(mbuf, "/stream:features>"))
+                 goto shut;
+             seen = BIO_read(sbio, mbuf, BUFSIZZ);
--- a/components/openssl/openssl-1.0.1-fips-140/Makefile	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,201 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
-#
-export PARFAIT_BUILD=no
-
-include ../../../make-rules/shared-macros.mk
-
-PATH=$(SPRO_VROOT)/bin:/usr/bin:/usr/gnu/bin:/usr/perl5/bin
-ifeq   ($(strip $(PARFAIT_BUILD)),yes)
-PATH=$(PARFAIT_TOOLS):$(SPRO_VROOT)/bin:/usr/bin:/usr/gnu/bin:/usr/perl5/bin
-endif
-
-COMPONENT_NAME =	openssl-fips-140
-# Note that this is the OpenSSL version that is used to build FIPS-140 certified
-# libraries. However, we use the FIPS canister version for the IPS package.
-COMPONENT_VERSION =	1.0.1u
-IPS_COMPONENT_VERSION = 2.0.6
-COMPONENT_PROJECT_URL=	http://www.openssl.org/
-COMPONENT_SRC_NAME =	openssl
-COMPONENT_SRC =		$(COMPONENT_SRC_NAME)-$(COMPONENT_VERSION)
-COMPONENT_ARCHIVE =	$(COMPONENT_SRC).tar.gz
-COMPONENT_ARCHIVE_HASH=	\
-    sha256:4312b4ca1215b6f2c97007503d80db80d5157f76f8f7d3febbe6b4c56ff26739
-COMPONENT_ARCHIVE_URL =	$(COMPONENT_PROJECT_URL)source/$(COMPONENT_ARCHIVE)
-COMPONENT_BUGDB=	library/openssl
-
-TPNO=			31796
-
-# OpenSSL FIPS directory
-OPENSSL_FIPS_DIR = $(COMPONENT_DIR)/../openssl-fips
-
-# Note that the SPARC patch above does not fit this pattern. That is intentional
-# and a reason why we can add it to the EXTRA_PATCHES variable so that we use it
-# only on SPARC.
-PATCH_PATTERN = [0-9][0-9]*.patch
-
-include $(WS_MAKE_RULES)/prep.mk
-include $(WS_MAKE_RULES)/configure.mk
-include $(WS_MAKE_RULES)/ips.mk
-include $(WS_MAKE_RULES)/lint-libraries.mk
-
-# OpenSSL does not use autoconf but its own configure system.
-CONFIGURE_SCRIPT = $(SOURCE_DIR)/Configure
-
-# Used in the configure options below.
-PKCS11_LIB32 = /usr/lib/libpkcs11.so.1
-PKCS11_LIB64 = /usr/lib/64/libpkcs11.so.1
-ENGINESDIR_32 = /lib/openssl/engines
-ENGINESDIR_64 = /lib/openssl/engines/64
-
-# Built openssl/openssl-fips component is used when building FIPS-140 libraries.
-# What we do here follows the OpenSSL FIPS-140 User Guide instructions.
-FIPS_BUILD_DIR_32 = $(shell echo $(BUILD_DIR_32) | \
-    sed -e 's/openssl-1.0.1-fips-140/openssl-fips/g' )
-FIPS_BUILD_DIR_64 = $(shell echo $(BUILD_DIR_64) | \
-    sed -e 's/openssl-1.0.1-fips-140/openssl-fips/g' )
-
-CONFIGURE_OPTIONS =  -DSOLARIS_OPENSSL -DNO_WINDOWS_BRAINDEATH
-CONFIGURE_OPTIONS += --openssldir=/etc/openssl
-CONFIGURE_OPTIONS += --prefix=/usr
-# We use OpenSSL install code for installing only manual pages and we do that
-# for 32-bit version only.
-CONFIGURE_OPTIONS += --install_prefix=$(PROTO_DIR)
-CONFIGURE_OPTIONS += no-ec2m
-CONFIGURE_OPTIONS += no-rc3
-CONFIGURE_OPTIONS += no-rc5
-CONFIGURE_OPTIONS += no-mdc2
-CONFIGURE_OPTIONS += no-idea
-CONFIGURE_OPTIONS += no-hw_4758_cca
-CONFIGURE_OPTIONS += no-hw_aep
-CONFIGURE_OPTIONS += no-hw_atalla
-CONFIGURE_OPTIONS += no-hw_chil
-CONFIGURE_OPTIONS += no-hw_gmp
-CONFIGURE_OPTIONS += no-hw_ncipher
-CONFIGURE_OPTIONS += no-hw_nuron
-CONFIGURE_OPTIONS += no-hw_padlock
-CONFIGURE_OPTIONS += no-hw_sureware
-CONFIGURE_OPTIONS += no-hw_ubsec
-CONFIGURE_OPTIONS += no-hw_cswift
-CONFIGURE_OPTIONS += threads
-CONFIGURE_OPTIONS += shared
-CONFIGURE_OPTIONS += fips --with-fipslibdir="$(FIPS_BUILD_DIR_$(BITS))/fips/"
-CONFIGURE_OPTIONS += --with-fipsdir="$(BUILD_DIR_$(BITS))"
-
-# MD2 is not enabled by default in OpensSSL but some software we have in
-# Userland needs it. One example is nmap.
-CONFIGURE_OPTIONS += enable-md2
-CONFIGURE_OPTIONS += no-seed
-
-# Disable SSLv2 protocol
-CONFIGURE_OPTIONS += no-ssl2
-
-# We define our own compiler and linker option sets for Solaris. See Configure
-# for more information.
-CONFIGURE_OPTIONS32_i386 =	solaris-x86-cc-sunw
-CONFIGURE_OPTIONS32_sparc =	solaris-sparcv8-cc-sunw
-CONFIGURE_OPTIONS64_i386 =	solaris64-x86_64-cc-sunw
-CONFIGURE_OPTIONS64_sparc =	solaris64-sparcv9-cc-sunw
-
-# Some additional options needed for our engines.
-CONFIGURE_OPTIONS += --pk11-libname=$(PKCS11_LIB$(BITS))
-CONFIGURE_OPTIONS += --enginesdir=$(ENGINESDIR_$(BITS))
-CONFIGURE_OPTIONS += $(CONFIGURE_OPTIONS$(BITS)_$(MACH))
-
-# OpenSSL has its own configure system which must be run from the fully
-# populated source code directory. However, the Userland configuration phase is
-# run from the build directory. The easiest way to workaround it is to copy all
-# the source files there.
-COMPONENT_PRE_CONFIGURE_ACTION = \
-    ( $(CLONEY) $(SOURCE_DIR) $(BUILD_DIR)/$(MACH$(BITS)); )
-
-# We deliver only one opensslconf.h file which must be suitable for both 32 and
-# 64 bits. Depending on the configuration option, OpenSSL's Configure script
-# creates opensslconf.h for either 32 or 64 bits. A patch makes the resulting
-# header file usable on both architectures. The patch was generated against the
-# opensslconf.h version from the 32 bit build.
-COMPONENT_POST_CONFIGURE_ACTION = \
-   ( [ $(BITS) -eq 32 ] && $(GPATCH) -p1 $(@D)/crypto/opensslconf.h \
-      patches-post-config/opensslconf.patch; cd $(@D); $(MAKE) depend; )
-
-# We must make sure that openssl-fips component is built before this 1.0.1
-# component since in order to build FIPS-140 certified libraries, the canister
-# is needed. Note that we must unset BITS that would override the same variable
-# used in openssl-fips' Makefile, and we would end up up with both canisters
-# built in 64 (or 32) bits.
-$(COMPONENT_DIR)/../openssl-fips/build/$(MACH32)/.installed \
-$(COMPONENT_DIR)/../openssl-fips/build/$(MACH64)/.installed:
-	( unset BITS; \
-	$(MAKE) -C $(COMPONENT_DIR)/../openssl-fips install; )
-
-# download, clean, and clobber should all propogate to the fips bits
-download clobber clean::
-	(cd ../openssl-fips ; $(GMAKE) $@)
-
-# We do not ship our engines as patches since it would be more difficult to
-# update the files which have been under continuous development. We rather copy
-# the files to the right directories and let OpenSSL makefiles build it.
-# We also copy some FIPS specific header files needed to build FIPS version
-# of OpenSSL from FIPS module.
-COMPONENT_PRE_BUILD_ACTION = \
-    ( $(LN) -fs $(COMPONENT_DIR)/engines/pkcs11/*     $(@D)/engines; \
-      $(MKDIR) $(@D)/bin; \
-      $(LN) -fs $(OPENSSL_FIPS_DIR)/openssl-fips-ecp-$(IPS_COMPONENT_VERSION)/fips/fips.h $(@D)/include/openssl; \
-      $(LN) -fs $(OPENSSL_FIPS_DIR)/openssl-fips-ecp-$(IPS_COMPONENT_VERSION)/fips/fipssyms.h $(@D)/include/openssl; \
-      $(LN) -fs $(OPENSSL_FIPS_DIR)/openssl-fips-ecp-$(IPS_COMPONENT_VERSION)/fips/rand/fips_rand.h $(@D)/include/openssl; \
-      $(LN) -fs $(OPENSSL_FIPS_DIR)/openssl-fips-ecp-$(IPS_COMPONENT_VERSION)/fips/fipsld $(@D)/bin/; \
-      $(LN) -fs $(OPENSSL_FIPS_DIR)/build/$(MACH$(BITS))/fips/fips_standalone_sha1 $(@D)/bin/; \
-      $(LN) -fs $(COMPONENT_DIR)/build/$(MACH$(BITS))/fips_premain_dso $(@D)/bin/;)
-
-# OpenSSL does not install into <dir>/$(MACH64) for 64-bit install so no such
-# directory is created and Userland install code would fail when installing lint
-# libraries.
-COMPONENT_PRE_INSTALL_ACTION = ( $(MKDIR) $(PROTO_DIR)/usr/lib/$(MACH64); )
-
-$(SOURCE_DIR)/.prep: $(COMPONENT_DIR)/../openssl-fips/build/$(MACH32)/.installed \
-		     $(COMPONENT_DIR)/../openssl-fips/build/$(MACH64)/.installed
-
-build:			$(BUILD_32_and_64)
-
-# We follow what we do for install in openssl/openssl-1.0.0 component. Please
-# see the comment in Makefile in there for more information.
-install:	$(INSTALL_32_and_64)
-
-# We need to modify the default lint flags to include patched opensslconf.h from
-# the build directory. If we do not do that, lint will complain about md2.h
-# which is not enabled by default but it is in our opensslconf.h.
-LFLAGS_32 := -I$(BUILD_DIR_32)/include $(LINT_FLAGS)
-LFLAGS_64 := -I$(BUILD_DIR_64)/include $(LINT_FLAGS)
-
-# Set modified lint flags for our lint library targets.
-$(BUILD_DIR_32)/llib-lcrypto.ln: LINT_FLAGS=$(LFLAGS_32)
-$(BUILD_DIR_32)/llib-lssl.ln: LINT_FLAGS=$(LFLAGS_32)
-$(BUILD_DIR_64)/llib-lcrypto.ln: LINT_FLAGS=$(LFLAGS_64)
-$(BUILD_DIR_64)/llib-lssl.ln: LINT_FLAGS=$(LFLAGS_64)
-
-# There are also separate STC test suites 'openssl' and 'openssl-engine'
-# for regression testing. These internal tests are unit tests only.
-COMPONENT_TEST_TARGETS = test
-test:		$(TEST_32_and_64)
-
-
-REQUIRED_PACKAGES += system/library
--- a/components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11.c	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3661 +0,0 @@
-/*
- * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
- *
- */
-
-/* crypto/engine/e_pk11.c */
-/*
- * This product includes software developed by the OpenSSL Project for
- * use in the OpenSSL Toolkit (http://www.openssl.org/).
- *
- * This project also referenced hw_pkcs11-0.9.7b.patch written by
- * Afchine Madjlessi.
- */
-/*
- * ====================================================================
- * 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
- *    [email protected].
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * ([email protected]).  This product includes software written by Tim
- * Hudson ([email protected]).
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <strings.h>
-
-#include <openssl/e_os2.h>
-#include <openssl/crypto.h>
-#include <openssl/engine.h>
-#include <openssl/dso.h>
-#include <openssl/err.h>
-#include <openssl/bn.h>
-#include <openssl/md5.h>
-#include <openssl/pem.h>
-#ifndef OPENSSL_NO_RSA
-#include <openssl/rsa.h>
-#endif
-#ifndef OPENSSL_NO_DSA
-#include <openssl/dsa.h>
-#endif
-#ifndef OPENSSL_NO_DH
-#include <openssl/dh.h>
-#endif
-#include <openssl/rand.h>
-#include <openssl/objects.h>
-#include <openssl/x509.h>
-#include <openssl/aes.h>
-#include <dlfcn.h>
-#include <pthread.h>
-
-#ifndef OPENSSL_NO_HW
-#ifndef OPENSSL_NO_HW_PK11
-
-/* label for debug messages printed on stderr */
-#define	PK11_DBG	"PKCS#11 ENGINE DEBUG"
-/* prints a lot of debug messages on stderr about slot selection process */
-#undef	DEBUG_SLOT_SELECTION
-/*
- * Solaris specific code. See comment at check_hw_mechanisms() for more
- * information.
- */
-#if defined(__SVR4) && defined(__sun)
-#define	SOLARIS_HW_SLOT_SELECTION
-#endif
-
-#ifdef DEBUG_SLOT_SELECTION
-#define	DEBUG_SLOT_SEL(...) fprintf(stderr, __VA_ARGS__)
-#else
-#define	DEBUG_SLOT_SEL(...)
-#endif
-
-#include <security/cryptoki.h>
-#include <security/pkcs11.h>
-#include "e_pk11.h"
-#include "e_pk11_uri.h"
-
-static CK_BBOOL pk11_true = CK_TRUE;
-static CK_BBOOL pk11_false = CK_FALSE;
-#define	PK11_ENGINE_LIB_NAME "PKCS#11 engine"
-#include "e_pk11_err.c"
-#include "e_pk11_uri.c"
-#include "e_pk11_pub.c"
-
-/*
- * We use this lock to prevent multiple C_Login()s, guard getpassphrase(),
- * uri_struct manipulation, and static token info. All of that is used by the
- * RSA keys by reference feature.
- */
-pthread_mutex_t *uri_lock = NULL;
-
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-/*
- * Tables for symmetric ciphers and digest mechs found in the pkcs11_kernel
- * library. See comment at check_hw_mechanisms() for more information.
- */
-int *hw_cnids;
-int *hw_dnids;
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-
-/* PKCS#11 session caches and their locks for all operation types */
-static PK11_CACHE session_cache[OP_MAX];
-
-/*
- * We cache the flags so that we do not have to run C_GetTokenInfo() again when
- * logging into the token.
- */
-CK_FLAGS pubkey_token_flags;
-
-/*
- * As stated in v2.20, 11.7 Object Management Function, in section for
- * C_FindObjectsInit(), at most one search operation may be active at a given
- * time in a given session. Therefore, C_Find{,Init,Final}Objects() should be
- * grouped together to form one atomic search operation. This is already
- * ensured by the property of unique PKCS#11 session handle used for each
- * PK11_SESSION object.
- *
- * This is however not the biggest concern - maintaining consistency of the
- * underlying object store is more important. The same section of the spec also
- * says that one thread can be in the middle of a search operation while another
- * thread destroys the object matching the search template which would result in
- * invalid handle returned from the search operation.
- *
- * Hence, the following locks are used for both protection of the object stores.
- * They are also used for active list protection.
- */
-pthread_mutex_t *find_lock[OP_MAX] = { NULL };
-
-/*
- * lists of asymmetric key handles which are active (referenced by at least one
- * PK11_SESSION structure, either held by a thread or present in free_session
- * list) for given algorithm type
- */
-PK11_active *active_list[OP_MAX] = { NULL };
-
-/*
- * Create all secret key objects in a global session so that they are available
- * to use for other sessions. These other sessions may be opened or closed
- * without losing the secret key objects.
- */
-static CK_SESSION_HANDLE	global_session = CK_INVALID_HANDLE;
-
-/* Index for the supported ciphers */
-enum pk11_cipher_id {
-	PK11_DES_CBC,
-	PK11_DES3_CBC,
-	PK11_DES_ECB,
-	PK11_DES3_ECB,
-	PK11_RC4,
-	PK11_AES_128_CBC,
-	PK11_AES_192_CBC,
-	PK11_AES_256_CBC,
-	PK11_AES_128_ECB,
-	PK11_AES_192_ECB,
-	PK11_AES_256_ECB,
-	PK11_BLOWFISH_CBC,
-	PK11_AES_128_CTR,
-	PK11_AES_192_CTR,
-	PK11_AES_256_CTR,
-	PK11_CIPHER_MAX
-};
-
-/* Index for the supported digests */
-enum pk11_digest_id {
-	PK11_MD5,
-	PK11_SHA1,
-	PK11_SHA224,
-	PK11_SHA256,
-	PK11_SHA384,
-	PK11_SHA512,
-	PK11_DIGEST_MAX
-};
-
-typedef struct PK11_CIPHER_st
-	{
-	enum pk11_cipher_id	id;
-	int			nid;
-	int			iv_len;
-	int			min_key_len;
-	int			max_key_len;
-	CK_KEY_TYPE		key_type;
-	CK_MECHANISM_TYPE	mech_type;
-	} PK11_CIPHER;
-
-typedef struct PK11_DIGEST_st
-	{
-	enum pk11_digest_id	id;
-	int			nid;
-	CK_MECHANISM_TYPE	mech_type;
-	} PK11_DIGEST;
-
-/* ENGINE level stuff */
-static int pk11_init(ENGINE *e);
-static int pk11_library_init(ENGINE *e);
-static int pk11_finish(ENGINE *e);
-static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
-static int pk11_destroy(ENGINE *e);
-
-/* RAND stuff */
-static void pk11_rand_seed(const void *buf, int num);
-static void pk11_rand_add(const void *buf, int num, double add_entropy);
-static void pk11_rand_cleanup(void);
-static int pk11_rand_bytes(unsigned char *buf, int num);
-static int pk11_rand_status(void);
-
-/* These functions are also used in other files */
-PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
-void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
-
-/* active list manipulation functions used in this file */
-extern int pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type);
-extern void pk11_free_active_list(PK11_OPTYPE type);
-
-#ifndef OPENSSL_NO_RSA
-int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
-int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
-int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
-#endif
-#ifndef OPENSSL_NO_DSA
-int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
-int pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
-int pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
-#endif
-#ifndef OPENSSL_NO_DH
-int pk11_destroy_dh_key_objects(PK11_SESSION *session);
-int pk11_destroy_dh_object(PK11_SESSION *session, CK_BBOOL uselock);
-#endif
-
-/* Local helper functions */
-static int pk11_free_all_sessions(void);
-static int pk11_free_session_list(PK11_OPTYPE optype);
-static int pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype);
-static int pk11_destroy_cipher_key_objects(PK11_SESSION *session);
-static int pk11_destroy_object(CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE oh,
-    CK_BBOOL persistent);
-static const char *get_PK11_LIBNAME(void);
-static void free_PK11_LIBNAME(void);
-static long set_PK11_LIBNAME(const char *name);
-
-/* Symmetric cipher and digest support functions */
-static int cipher_nid_to_pk11(int nid);
-static int pk11_usable_ciphers(const int **nids);
-static int pk11_usable_digests(const int **nids);
-static int pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-	const unsigned char *iv, int enc);
-static int pk11_cipher_final(PK11_SESSION *sp);
-static int pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-	const unsigned char *in, size_t inl);
-static int pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx);
-static int pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
-	const int **nids, int nid);
-static int pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
-	const int **nids, int nid);
-static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
-	const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp);
-static int check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key,
-	int key_len);
-static int md_nid_to_pk11(int nid);
-static int pk11_digest_init(EVP_MD_CTX *ctx);
-static int pk11_digest_update(EVP_MD_CTX *ctx, const void *data,
-	size_t count);
-static int pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md);
-static int pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);
-static int pk11_digest_cleanup(EVP_MD_CTX *ctx);
-
-static int pk11_choose_slots(int *any_slot_found);
-static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
-    CK_SLOT_ID current_slot, int *current_slot_n_cipher,
-    int *local_cipher_nids);
-static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
-    CK_SLOT_ID current_slot, int *current_slot_n_digest,
-    int *local_digest_nids);
-static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR, int slot_id,
-    int *current_slot_n_cipher, int *local_cipher_nids,
-    PK11_CIPHER *cipher);
-static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
-    int *current_slot_n_digest, int *local_digest_nids,
-    PK11_DIGEST *digest);
-
-static int pk11_init_all_locks(void);
-static void pk11_free_all_locks(void);
-
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-static int check_hw_mechanisms(void);
-static int nid_in_table(int nid, int *nid_table);
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-
-#define	TRY_OBJ_DESTROY(sp, obj_hdl, retval, uselock, alg_type)	\
-	{								\
-	if (uselock)							\
-		LOCK_OBJSTORE(alg_type);				\
-	if (pk11_active_delete(obj_hdl, alg_type) == 1)			\
-		{							\
-		retval = pk11_destroy_object(sp->session, obj_hdl,	\
-		    sp->persistent);					\
-		}							\
-	if (uselock)							\
-		UNLOCK_OBJSTORE(alg_type);				\
-	}
-
-static int cipher_nids[PK11_CIPHER_MAX];
-static int digest_nids[PK11_DIGEST_MAX];
-static int cipher_count		= 0;
-static int digest_count		= 0;
-static CK_BBOOL pk11_have_rsa	= CK_FALSE;
-static CK_BBOOL pk11_have_dsa	= CK_FALSE;
-static CK_BBOOL pk11_have_dh	= CK_FALSE;
-static CK_BBOOL pk11_have_random = CK_FALSE;
-
-/*
- * Static list of ciphers.
- * Note, that ciphers array is indexed by member PK11_CIPHER.id,
- * thus ciphers[i].id == i
- * Rows must be kept in sync with enum pk11_cipher_id.
- */
-static PK11_CIPHER ciphers[] =
-	{
-	{ PK11_DES_CBC,		NID_des_cbc,		8,	 8,   8,
-		CKK_DES,	CKM_DES_CBC, },
-	{ PK11_DES3_CBC,	NID_des_ede3_cbc,	8,	24,  24,
-		CKK_DES3,	CKM_DES3_CBC, },
-	{ PK11_DES_ECB,		NID_des_ecb,		0,	 8,   8,
-		CKK_DES,	CKM_DES_ECB, },
-	{ PK11_DES3_ECB,	NID_des_ede3_ecb,	0,	24,  24,
-		CKK_DES3,	CKM_DES3_ECB, },
-	{ PK11_RC4,		NID_rc4,		0,	16, 256,
-		CKK_RC4,	CKM_RC4, },
-	{ PK11_AES_128_CBC,	NID_aes_128_cbc,	16,	16,  16,
-		CKK_AES,	CKM_AES_CBC, },
-	{ PK11_AES_192_CBC,	NID_aes_192_cbc,	16,	24,  24,
-		CKK_AES,	CKM_AES_CBC, },
-	{ PK11_AES_256_CBC,	NID_aes_256_cbc,	16,	32,  32,
-		CKK_AES,	CKM_AES_CBC, },
-	{ PK11_AES_128_ECB,	NID_aes_128_ecb,	0,	16,  16,
-		CKK_AES,	CKM_AES_ECB, },
-	{ PK11_AES_192_ECB,	NID_aes_192_ecb,	0,	24,  24,
-		CKK_AES,	CKM_AES_ECB, },
-	{ PK11_AES_256_ECB,	NID_aes_256_ecb,	0,	32,  32,
-		CKK_AES,	CKM_AES_ECB, },
-	{ PK11_BLOWFISH_CBC,	NID_bf_cbc,		8,	16,  16,
-		CKK_BLOWFISH,	CKM_BLOWFISH_CBC, },
-	/* we don't know the correct NIDs until the engine is initialized */
-	{ PK11_AES_128_CTR,	NID_aes_128_ctr,	16,	16,  16,
-		CKK_AES,	CKM_AES_CTR, },
-	{ PK11_AES_192_CTR,	NID_aes_192_ctr,	16,	24,  24,
-		CKK_AES,	CKM_AES_CTR, },
-	{ PK11_AES_256_CTR,	NID_aes_256_ctr,	16,	32,  32,
-		CKK_AES,	CKM_AES_CTR, },
-	};
-
-/*
- * Static list of digests.
- * Note, that digests array is indexed by member PK11_DIGEST.id,
- * thus digests[i].id == i
- * Rows must be kept in sync with enum pk11_digest_id.
- */
-static PK11_DIGEST digests[] =
-	{
-	{PK11_MD5,	NID_md5,	CKM_MD5, },
-	{PK11_SHA1,	NID_sha1,	CKM_SHA_1, },
-	{PK11_SHA224,	NID_sha224,	CKM_SHA224, },
-	{PK11_SHA256,	NID_sha256,	CKM_SHA256, },
-	{PK11_SHA384,	NID_sha384,	CKM_SHA384, },
-	{PK11_SHA512,	NID_sha512,	CKM_SHA512, },
-	{0,		NID_undef,	0xFFFF, },
-	};
-
-/*
- * Structure to be used for the cipher_data/md_data in
- * EVP_CIPHER_CTX/EVP_MD_CTX structures in order to use the same pk11
- * session in multiple cipher_update calls
- */
-typedef struct PK11_CIPHER_STATE_st
-	{
-	PK11_SESSION	*sp;
-	} PK11_CIPHER_STATE;
-
-
-/*
- * libcrypto EVP stuff - this is how we get wired to EVP so the engine gets
- * called when libcrypto requests a cipher NID.
- *
- * Note how the PK11_CIPHER_STATE is used here.
- */
-
-/* DES CBC EVP */
-static const EVP_CIPHER pk11_des_cbc =
-	{
-	NID_des_cbc,
-	8, 8, 8,
-	EVP_CIPH_CBC_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-/* 3DES CBC EVP */
-static const EVP_CIPHER pk11_3des_cbc =
-	{
-	NID_des_ede3_cbc,
-	8, 24, 8,
-	EVP_CIPH_CBC_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-/*
- * ECB modes don't use an Initial Vector so that's why set_asn1_parameters and
- * get_asn1_parameters fields are set to NULL.
- */
-static const EVP_CIPHER pk11_des_ecb =
-	{
-	NID_des_ecb,
-	8, 8, 8,
-	EVP_CIPH_ECB_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	NULL,
-	NULL,
-	NULL
-	};
-
-static const EVP_CIPHER pk11_3des_ecb =
-	{
-	NID_des_ede3_ecb,
-	8, 24, 8,
-	EVP_CIPH_ECB_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	NULL,
-	NULL,
-	NULL
-	};
-
-
-static const EVP_CIPHER pk11_aes_128_cbc =
-	{
-	NID_aes_128_cbc,
-	16, 16, 16,
-	EVP_CIPH_CBC_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-static const EVP_CIPHER pk11_aes_192_cbc =
-	{
-	NID_aes_192_cbc,
-	16, 24, 16,
-	EVP_CIPH_CBC_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-static const EVP_CIPHER pk11_aes_256_cbc =
-	{
-	NID_aes_256_cbc,
-	16, 32, 16,
-	EVP_CIPH_CBC_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-/*
- * ECB modes don't use IV so that's why set_asn1_parameters and
- * get_asn1_parameters are set to NULL.
- */
-static const EVP_CIPHER pk11_aes_128_ecb =
-	{
-	NID_aes_128_ecb,
-	16, 16, 0,
-	EVP_CIPH_ECB_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	NULL,
-	NULL,
-	NULL
-	};
-
-static const EVP_CIPHER pk11_aes_192_ecb =
-	{
-	NID_aes_192_ecb,
-	16, 24, 0,
-	EVP_CIPH_ECB_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	NULL,
-	NULL,
-	NULL
-	};
-
-static const EVP_CIPHER pk11_aes_256_ecb =
-	{
-	NID_aes_256_ecb,
-	16, 32, 0,
-	EVP_CIPH_ECB_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	NULL,
-	NULL,
-	NULL
-	};
-
-static EVP_CIPHER pk11_aes_128_ctr =
-	{
-	NID_aes_128_ctr,
-	16, 16, 16,
-	EVP_CIPH_CTR_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-static EVP_CIPHER pk11_aes_192_ctr =
-	{
-	NID_aes_192_ctr,
-	16, 24, 16,
-	EVP_CIPH_CTR_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-static EVP_CIPHER pk11_aes_256_ctr =
-	{
-	NID_aes_256_ctr,
-	16, 32, 16,
-	EVP_CIPH_CTR_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-static const EVP_CIPHER pk11_bf_cbc =
-	{
-	NID_bf_cbc,
-	8, 16, 8,
-	EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CBC_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-static const EVP_CIPHER pk11_rc4 =
-	{
-	NID_rc4,
-	1, 16, 0,
-	EVP_CIPH_VARIABLE_LENGTH,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	NULL,
-	NULL,
-	NULL
-	};
-
-static const EVP_MD pk11_md5 =
-	{
-	NID_md5,
-	NID_md5WithRSAEncryption,
-	MD5_DIGEST_LENGTH,
-	0,
-	pk11_digest_init,
-	pk11_digest_update,
-	pk11_digest_final,
-	pk11_digest_copy,
-	pk11_digest_cleanup,
-	EVP_PKEY_RSA_method,
-	MD5_CBLOCK,
-	sizeof (PK11_CIPHER_STATE),
-	};
-
-static const EVP_MD pk11_sha1 =
-	{
-	NID_sha1,
-	NID_sha1WithRSAEncryption,
-	SHA_DIGEST_LENGTH,
-	EVP_MD_FLAG_FIPS,
-	pk11_digest_init,
-	pk11_digest_update,
-	pk11_digest_final,
-	pk11_digest_copy,
-	pk11_digest_cleanup,
-	EVP_PKEY_RSA_method,
-	SHA_CBLOCK,
-	sizeof (PK11_CIPHER_STATE),
-	};
-
-static const EVP_MD pk11_sha224 =
-	{
-	NID_sha224,
-	NID_sha224WithRSAEncryption,
-	SHA224_DIGEST_LENGTH,
-	EVP_MD_FLAG_FIPS,
-	pk11_digest_init,
-	pk11_digest_update,
-	pk11_digest_final,
-	pk11_digest_copy,
-	pk11_digest_cleanup,
-	EVP_PKEY_RSA_method,
-	/* SHA-224 uses the same cblock size as SHA-256 */
-	SHA256_CBLOCK,
-	sizeof (PK11_CIPHER_STATE),
-	};
-
-static const EVP_MD pk11_sha256 =
-	{
-	NID_sha256,
-	NID_sha256WithRSAEncryption,
-	SHA256_DIGEST_LENGTH,
-	EVP_MD_FLAG_FIPS,
-	pk11_digest_init,
-	pk11_digest_update,
-	pk11_digest_final,
-	pk11_digest_copy,
-	pk11_digest_cleanup,
-	EVP_PKEY_RSA_method,
-	SHA256_CBLOCK,
-	sizeof (PK11_CIPHER_STATE),
-	};
-
-static const EVP_MD pk11_sha384 =
-	{
-	NID_sha384,
-	NID_sha384WithRSAEncryption,
-	SHA384_DIGEST_LENGTH,
-	EVP_MD_FLAG_FIPS,
-	pk11_digest_init,
-	pk11_digest_update,
-	pk11_digest_final,
-	pk11_digest_copy,
-	pk11_digest_cleanup,
-	EVP_PKEY_RSA_method,
-	/* SHA-384 uses the same cblock size as SHA-512 */
-	SHA512_CBLOCK,
-	sizeof (PK11_CIPHER_STATE),
-	};
-
-static const EVP_MD pk11_sha512 =
-	{
-	NID_sha512,
-	NID_sha512WithRSAEncryption,
-	SHA512_DIGEST_LENGTH,
-	EVP_MD_FLAG_FIPS,
-	pk11_digest_init,
-	pk11_digest_update,
-	pk11_digest_final,
-	pk11_digest_copy,
-	pk11_digest_cleanup,
-	EVP_PKEY_RSA_method,
-	SHA512_CBLOCK,
-	sizeof (PK11_CIPHER_STATE),
-	};
-
-/*
- * Initialization function. Sets up various PKCS#11 library components.
- * The definitions for control commands specific to this engine
- */
-#define	PK11_CMD_SO_PATH		ENGINE_CMD_BASE
-static const ENGINE_CMD_DEFN pk11_cmd_defns[] =
-	{
-		{
-		PK11_CMD_SO_PATH,
-		"SO_PATH",
-		"Specifies the path to the 'pkcs#11' shared library",
-		ENGINE_CMD_FLAG_STRING
-		},
-		{0, NULL, NULL, 0}
-	};
-
-
-static RAND_METHOD pk11_random =
-	{
-	pk11_rand_seed,
-	pk11_rand_bytes,
-	pk11_rand_cleanup,
-	pk11_rand_add,
-	pk11_rand_bytes,
-	pk11_rand_status
-	};
-
-
-/* Constants used when creating the ENGINE */
-static const char *engine_pk11_id = "pkcs11";
-static const char *engine_pk11_name = "PKCS #11 engine support";
-
-CK_FUNCTION_LIST_PTR pFuncList = NULL;
-static const char PK11_GET_FUNCTION_LIST[] = "C_GetFunctionList";
-
-/*
- * This is a static string constant for the DSO file name and the function
- * symbol names to bind to. We set it in the Configure script based on whether
- * this is 32 or 64 bit build.
- */
-static const char def_PK11_LIBNAME[] = PK11_LIB_LOCATION;
-
-/* Needed in e_pk11_pub.c as well so that's why it is not static. */
-CK_SLOT_ID pubkey_SLOTID = 0;
-static CK_SLOT_ID rand_SLOTID = 0;
-static CK_SLOT_ID SLOTID = 0;
-static CK_BBOOL pk11_library_initialized = CK_FALSE;
-static CK_BBOOL pk11_atfork_initialized = CK_FALSE;
-static int pk11_pid = 0;
-static ENGINE* pk11_engine = NULL;
-
-static DSO *pk11_dso = NULL;
-
-/* allocate and initialize all locks used by the engine itself */
-static int pk11_init_all_locks(void)
-	{
-	int type;
-
-#ifndef OPENSSL_NO_RSA
-	find_lock[OP_RSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
-	if (find_lock[OP_RSA] == NULL)
-		goto malloc_err;
-	(void) pthread_mutex_init(find_lock[OP_RSA], NULL);
-#endif /* OPENSSL_NO_RSA */
-
-	if ((uri_lock = OPENSSL_malloc(sizeof (pthread_mutex_t))) == NULL)
-		goto malloc_err;
-	(void) pthread_mutex_init(uri_lock, NULL);
-
-#ifndef OPENSSL_NO_DSA
-	find_lock[OP_DSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
-	if (find_lock[OP_DSA] == NULL)
-		goto malloc_err;
-	(void) pthread_mutex_init(find_lock[OP_DSA], NULL);
-#endif /* OPENSSL_NO_DSA */
-
-#ifndef OPENSSL_NO_DH
-	find_lock[OP_DH] = OPENSSL_malloc(sizeof (pthread_mutex_t));
-	if (find_lock[OP_DH] == NULL)
-		goto malloc_err;
-	(void) pthread_mutex_init(find_lock[OP_DH], NULL);
-#endif /* OPENSSL_NO_DH */
-
-	for (type = 0; type < OP_MAX; type++)
-		{
-		session_cache[type].lock =
-		    OPENSSL_malloc(sizeof (pthread_mutex_t));
-		if (session_cache[type].lock == NULL)
-			goto malloc_err;
-		(void) pthread_mutex_init(session_cache[type].lock, NULL);
-		}
-
-	return (1);
-
-malloc_err:
-	pk11_free_all_locks();
-	PK11err(PK11_F_INIT_ALL_LOCKS, PK11_R_MALLOC_FAILURE);
-	return (0);
-	}
-
-static void pk11_free_all_locks(void)
-	{
-	int type;
-
-#ifndef OPENSSL_NO_RSA
-	if (find_lock[OP_RSA] != NULL)
-		{
-		(void) pthread_mutex_destroy(find_lock[OP_RSA]);
-		OPENSSL_free(find_lock[OP_RSA]);
-		find_lock[OP_RSA] = NULL;
-		}
-#endif /* OPENSSL_NO_RSA */
-#ifndef OPENSSL_NO_DSA
-	if (find_lock[OP_DSA] != NULL)
-		{
-		(void) pthread_mutex_destroy(find_lock[OP_DSA]);
-		OPENSSL_free(find_lock[OP_DSA]);
-		find_lock[OP_DSA] = NULL;
-		}
-#endif /* OPENSSL_NO_DSA */
-#ifndef OPENSSL_NO_DH
-	if (find_lock[OP_DH] != NULL)
-		{
-		(void) pthread_mutex_destroy(find_lock[OP_DH]);
-		OPENSSL_free(find_lock[OP_DH]);
-		find_lock[OP_DH] = NULL;
-		}
-#endif /* OPENSSL_NO_DH */
-
-	for (type = 0; type < OP_MAX; type++)
-		{
-		if (session_cache[type].lock != NULL)
-			{
-			(void) pthread_mutex_destroy(session_cache[type].lock);
-			OPENSSL_free(session_cache[type].lock);
-			session_cache[type].lock = NULL;
-			}
-		}
-	/* Free uri_lock */
-	(void) pthread_mutex_destroy(uri_lock);
-	OPENSSL_free(uri_lock);
-	uri_lock = NULL;
-	}
-
-/*
- * This internal function is used by ENGINE_pk11() and "dynamic" ENGINE support.
- */
-static int bind_pk11(ENGINE *e)
-	{
-#ifndef OPENSSL_NO_RSA
-	const RSA_METHOD *rsa = NULL;
-	RSA_METHOD *pk11_rsa = PK11_RSA();
-#endif	/* OPENSSL_NO_RSA */
-	if (!pk11_library_initialized)
-		if (!pk11_library_init(e))
-			return (0);
-
-	if (!ENGINE_set_id(e, engine_pk11_id) ||
-	    !ENGINE_set_name(e, engine_pk11_name) ||
-	    !ENGINE_set_ciphers(e, pk11_engine_ciphers) ||
-	    !ENGINE_set_digests(e, pk11_engine_digests))
-		return (0);
-
-	if (!ENGINE_set_pkey_meths(e, pk11_engine_pkey_methods))
-		return (0);
-
-#ifndef OPENSSL_NO_RSA
-	if (pk11_have_rsa == CK_TRUE)
-		{
-		if (!ENGINE_set_RSA(e, PK11_RSA()) ||
-		    !ENGINE_set_load_privkey_function(e, pk11_load_privkey) ||
-		    !ENGINE_set_load_pubkey_function(e, pk11_load_pubkey))
-			return (0);
-		DEBUG_SLOT_SEL("%s: registered RSA\n", PK11_DBG);
-		}
-#endif	/* OPENSSL_NO_RSA */
-#ifndef OPENSSL_NO_DSA
-	if (pk11_have_dsa == CK_TRUE)
-		{
-		if (!ENGINE_set_DSA(e, PK11_DSA()))
-			return (0);
-		DEBUG_SLOT_SEL("%s: registered DSA\n", PK11_DBG);
-		}
-#endif	/* OPENSSL_NO_DSA */
-#ifndef OPENSSL_NO_DH
-	if (pk11_have_dh == CK_TRUE)
-		{
-		if (!ENGINE_set_DH(e, PK11_DH()))
-			return (0);
-		DEBUG_SLOT_SEL("%s: registered DH\n", PK11_DBG);
-		}
-#endif	/* OPENSSL_NO_DH */
-	if (pk11_have_random)
-		{
-		if (!ENGINE_set_RAND(e, &pk11_random))
-			return (0);
-		DEBUG_SLOT_SEL("%s: registered random\n", PK11_DBG);
-		}
-	if (!ENGINE_set_init_function(e, pk11_init) ||
-	    !ENGINE_set_destroy_function(e, pk11_destroy) ||
-	    !ENGINE_set_finish_function(e, pk11_finish) ||
-	    !ENGINE_set_ctrl_function(e, pk11_ctrl) ||
-	    !ENGINE_set_cmd_defns(e, pk11_cmd_defns))
-		return (0);
-
-/*
- * Apache calls OpenSSL function RSA_blinding_on() once during startup
- * which in turn calls bn_mod_exp. Since we do not implement bn_mod_exp
- * here, we wire it back to the OpenSSL software implementation.
- * Since it is used only once, performance is not a concern.
- */
-#ifndef OPENSSL_NO_RSA
-	rsa = RSA_PKCS1_SSLeay();
-	pk11_rsa->rsa_mod_exp = rsa->rsa_mod_exp;
-	pk11_rsa->bn_mod_exp = rsa->bn_mod_exp;
-#endif	/* OPENSSL_NO_RSA */
-
-	/* Ensure the pk11 error handling is set up */
-	ERR_load_pk11_strings();
-
-	return (1);
-	}
-
-static int bind_helper(ENGINE *e, const char *id)
-	{
-	if (id && (strcmp(id, engine_pk11_id) != 0))
-		return (0);
-
-	if (!bind_pk11(e))
-		return (0);
-
-	return (1);
-	}
-
-IMPLEMENT_DYNAMIC_CHECK_FN()
-IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
-
-/*
- * These are the static string constants for the DSO file name and
- * the function symbol names to bind to.
- */
-static const char *PK11_LIBNAME = NULL;
-
-static const char *get_PK11_LIBNAME(void)
-	{
-	if (PK11_LIBNAME)
-		return (PK11_LIBNAME);
-
-	return (def_PK11_LIBNAME);
-	}
-
-static void free_PK11_LIBNAME(void)
-	{
-	if (PK11_LIBNAME)
-		OPENSSL_free((void*)PK11_LIBNAME);
-
-	PK11_LIBNAME = NULL;
-	}
-
-static long set_PK11_LIBNAME(const char *name)
-	{
-	free_PK11_LIBNAME();
-
-	return ((PK11_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
-	}
-
-/* acquire all engine specific mutexes before fork */
-static void pk11_fork_prepare(void)
-	{
-	int i;
-
-	if (!pk11_library_initialized)
-		return;
-
-	LOCK_OBJSTORE(OP_RSA);
-	LOCK_OBJSTORE(OP_DSA);
-	LOCK_OBJSTORE(OP_DH);
-	(void) pthread_mutex_lock(uri_lock);
-	for (i = 0; i < OP_MAX; i++)
-		{
-		(void) pthread_mutex_lock(session_cache[i].lock);
-		}
-	}
-
-/* release all engine specific mutexes */
-static void pk11_fork_parent(void)
-	{
-	int i;
-
-	if (!pk11_library_initialized)
-		return;
-
-	for (i = OP_MAX - 1; i >= 0; i--)
-		{
-		(void) pthread_mutex_unlock(session_cache[i].lock);
-		}
-	UNLOCK_OBJSTORE(OP_DH);
-	UNLOCK_OBJSTORE(OP_DSA);
-	UNLOCK_OBJSTORE(OP_RSA);
-	(void) pthread_mutex_unlock(uri_lock);
-	}
-
-/*
- * same situation as in parent - we need to unlock all locks to make them
- * accessible to all threads.
- */
-static void pk11_fork_child(void)
-	{
-	int i;
-
-	if (!pk11_library_initialized)
-		return;
-
-	for (i = OP_MAX - 1; i >= 0; i--)
-		{
-		(void) pthread_mutex_unlock(session_cache[i].lock);
-		}
-	UNLOCK_OBJSTORE(OP_DH);
-	UNLOCK_OBJSTORE(OP_DSA);
-	UNLOCK_OBJSTORE(OP_RSA);
-	(void) pthread_mutex_unlock(uri_lock);
-	}
-
-/* Initialization function for the pk11 engine */
-static int pk11_init(ENGINE *e)
-{
-	return (pk11_library_init(e));
-}
-
-
-/*
- * Helper function that unsets reference to current engine (pk11_engine = NULL).
- *
- * Use of local variable only seems clumsy, it needs to be this way!
- * This is to prevent double free in the unlucky scenario:
- *     ENGINE_free calls pk11_destroy calls pk11_finish calls ENGINE_free
- * Setting pk11_engine to NULL prior to ENGINE_free() avoids this.
- */
-static void pk11_engine_free()
-	{
-	ENGINE* old_engine = pk11_engine;
-
-	if (old_engine)
-		{
-		pk11_engine = NULL;
-		}
-	}
-
-
-/*
- * Initialization function. Sets up various PKCS#11 library components.
- * It selects a slot based on predefined critiera. In the process, it also
- * count how many ciphers and digests to support. Since the cipher and
- * digest information is needed when setting default engine, this function
- * needs to be called before calling ENGINE_set_default.
- */
-/* ARGSUSED */
-static int pk11_library_init(ENGINE *e)
-	{
-	CK_C_GetFunctionList p;
-	CK_RV rv = CKR_OK;
-	CK_INFO info;
-	CK_ULONG ul_state_len;
-	int any_slot_found;
-	int i;
-
-	if (e != pk11_engine)
-		{
-		pk11_engine_free();
-		pk11_engine = e;
-		}
-
-	/*
-	 * pk11_library_initialized is set to 0 in pk11_finish() which is called
-	 * from ENGINE_finish(). However, if there is still at least one
-	 * existing functional reference to the engine (see engine(3) for more
-	 * information), pk11_finish() is skipped. For example, this can happen
-	 * if an application forgets to clear one cipher context. In case of a
-	 * fork() when the application is finishing the engine so that it can be
-	 * reinitialized in the child, forgotten functional reference causes
-	 * pk11_library_initialized to stay 1. In that case we need the PID
-	 * check so that we properly initialize the engine again.
-	 */
-	if (pk11_library_initialized)
-		{
-		if (pk11_pid == getpid())
-			{
-			return (1);
-			}
-		else
-			{
-			global_session = CK_INVALID_HANDLE;
-			/*
-			 * free the locks first to prevent memory leak in case
-			 * the application calls fork() without finishing the
-			 * engine first.
-			 */
-			pk11_free_all_locks();
-			}
-		}
-
-	/*
-	 * If initialization of the locks fails pk11_init_all_locks()
-	 * will do the cleanup.
-	 */
-	if (!pk11_init_all_locks())
-		goto err;
-	for (i = 0; i < OP_MAX; i++)
-		session_cache[i].head = NULL;
-	/*
-	 * Initialize active lists. We only use active lists
-	 * for asymmetric ciphers.
-	 */
-	for (i = 0; i < OP_MAX; i++)
-		active_list[i] = NULL;
-
-	/* Attempt to load PKCS#11 library. */
-	if (!pk11_dso)
-		{
-		pk11_dso = DSO_load(NULL, get_PK11_LIBNAME(), NULL, 0);
-		if (pk11_dso == NULL)
-			{
-			PK11err(PK11_F_LOAD, PK11_R_DSO_FAILURE);
-			goto err;
-			}
-		}
-
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-	if (check_hw_mechanisms() == 0)
-		goto err;
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-
-	/* get the C_GetFunctionList function from the loaded library */
-	p = (CK_C_GetFunctionList)DSO_bind_func(pk11_dso,
-		PK11_GET_FUNCTION_LIST);
-	if (!p)
-		{
-		PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
-		goto err;
-		}
-
-	/* get the full function list from the loaded library */
-	rv = p(&pFuncList);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_Initialize(NULL_PTR);
-	if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
-		{
-		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_INITIALIZE, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_GetInfo(&info);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_GETINFO, rv);
-		goto err;
-		}
-
-	if (pk11_choose_slots(&any_slot_found) == 0)
-		goto err;
-
-	/*
-	 * The library we use, set in def_PK11_LIBNAME, may not offer any
-	 * slot(s). In that case, we must not proceed but we must not return an
-	 * error. The reason is that applications that try to set up the PKCS#11
-	 * engine don't exit on error during the engine initialization just
-	 * because no slot was present.
-	 */
-	if (any_slot_found == 0)
-		return (1);
-
-	if (global_session == CK_INVALID_HANDLE)
-		{
-		/* Open the global_session for the new process */
-		rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
-			NULL_PTR, NULL_PTR, &global_session);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_LIBRARY_INIT,
-			    PK11_R_OPENSESSION, rv);
-			goto err;
-			}
-		}
-
-	/*
-	 * Disable digest if C_GetOperationState is not supported since
-	 * this function is required by OpenSSL digest copy function
-	 */
-	if (pFuncList->C_GetOperationState(global_session, NULL, &ul_state_len)
-			== CKR_FUNCTION_NOT_SUPPORTED) {
-		DEBUG_SLOT_SEL("%s: C_GetOperationState() not supported, "
-		    "setting digest_count to 0\n", PK11_DBG);
-		digest_count = 0;
-	}
-
-	pk11_library_initialized = CK_TRUE;
-	pk11_pid = getpid();
-
-	if (!pk11_atfork_initialized)
-		{
-		if (pthread_atfork(pk11_fork_prepare, pk11_fork_parent,
-		    pk11_fork_child) != 0)
-			{
-			PK11err(PK11_F_LIBRARY_INIT, PK11_R_ATFORK_FAILED);
-			goto err;
-			}
-		pk11_atfork_initialized = CK_TRUE;
-		}
-
-	return (1);
-
-err:
-	return (0);
-	}
-
-/* Destructor (complements the "ENGINE_pk11()" constructor) */
-/* ARGSUSED */
-static int pk11_destroy(ENGINE *e)
-	{
-	int rtn = 1;
-
-	free_PK11_LIBNAME();
-	ERR_unload_pk11_strings();
-
-	if (pk11_library_initialized == CK_TRUE)
-		rtn = pk11_finish(e);
-
-	return (rtn);
-	}
-
-/*
- * Termination function to clean up the session, the token, and the pk11
- * library.
- */
-/* ARGSUSED */
-static int pk11_finish(ENGINE *e)
-	{
-	int i;
-
-	/*
-	 * Make sure, right engine instance is being destroyed.
-	 * Engine e may be the wrong instance if
-	 *	1) either someone calls ENGINE_load_pk11 twice
-	 *	2) or last ref. to an already finished engine is being destroyed
-	 */
-	if (e != pk11_engine)
-		goto err;
-
-	if (pk11_dso == NULL)
-		{
-		PK11err(PK11_F_FINISH, PK11_R_NOT_LOADED);
-		goto err;
-		}
-
-	OPENSSL_assert(pFuncList != NULL);
-
-	if (pk11_free_all_sessions() == 0)
-		goto err;
-
-	/* free all active lists */
-	for (i = 0; i < OP_MAX; i++)
-		pk11_free_active_list(i);
-
-	/* Global session is not present when there are no slots. */
-	if (global_session != CK_INVALID_HANDLE)
-		{
-		pFuncList->C_CloseSession(global_session);
-		global_session = CK_INVALID_HANDLE;
-		}
-
-	/*
-	 * Since we are part of a library (libcrypto.so), calling this function
-	 * may have side-effects.
-	 */
-#if 0
-	pFuncList->C_Finalize(NULL);
-#endif
-
-	if (!DSO_free(pk11_dso))
-		{
-		PK11err(PK11_F_FINISH, PK11_R_DSO_FAILURE);
-		goto err;
-		}
-	pk11_dso = NULL;
-	pFuncList = NULL;
-	pk11_library_initialized = CK_FALSE;
-	pk11_pid = 0;
-	pk11_engine_free();
-	/*
-	 * There is no way how to unregister atfork handlers (other than
-	 * unloading the library) so we just free the locks. For this reason
-	 * the atfork handlers check if the engine is initialized and bail out
-	 * immediately if not. This is necessary in case a process finishes
-	 * the engine before calling fork().
-	 */
-	pk11_free_all_locks();
-
-	return (1);
-
-err:
-	return (0);
-	}
-
-/* Standard engine interface function to set the dynamic library path */
-/* ARGSUSED */
-static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
-	{
-	int initialized = ((pk11_dso == NULL) ? 0 : 1);
-
-	switch (cmd)
-		{
-	case PK11_CMD_SO_PATH:
-		if (p == NULL)
-			{
-			PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
-			return (0);
-			}
-
-		if (initialized)
-			{
-			PK11err(PK11_F_CTRL, PK11_R_ALREADY_LOADED);
-			return (0);
-			}
-
-		return (set_PK11_LIBNAME((const char *)p));
-	default:
-		break;
-		}
-
-	PK11err(PK11_F_CTRL, PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED);
-
-	return (0);
-	}
-
-
-/* Required function by the engine random interface. It does nothing here */
-static void pk11_rand_cleanup(void)
-	{
-	return;
-	}
-
-/* ARGSUSED */
-static void pk11_rand_add(const void *buf, int num, double add)
-	{
-	PK11_SESSION *sp;
-
-	if ((sp = pk11_get_session(OP_RAND)) == NULL)
-		return;
-
-	/*
-	 * Ignore any errors (e.g. CKR_RANDOM_SEED_NOT_SUPPORTED) since
-	 * the calling functions do not care anyway
-	 */
-	pFuncList->C_SeedRandom(sp->session, (unsigned char *) buf, num);
-	pk11_return_session(sp, OP_RAND);
-
-	return;
-	}
-
-static void pk11_rand_seed(const void *buf, int num)
-	{
-	pk11_rand_add(buf, num, 0);
-	}
-
-static int pk11_rand_bytes(unsigned char *buf, int num)
-	{
-	CK_RV rv;
-	PK11_SESSION *sp;
-
-	if ((sp = pk11_get_session(OP_RAND)) == NULL)
-		return (0);
-
-	rv = pFuncList->C_GenerateRandom(sp->session, buf, num);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_RAND_BYTES, PK11_R_GENERATERANDOM, rv);
-		pk11_return_session(sp, OP_RAND);
-		return (0);
-		}
-
-	pk11_return_session(sp, OP_RAND);
-	return (1);
-	}
-
-/* Required function by the engine random interface. It does nothing here */
-static int pk11_rand_status(void)
-	{
-	return (1);
-	}
-
-/* Free all BIGNUM structures from PK11_SESSION. */
-static void pk11_free_nums(PK11_SESSION *sp, PK11_OPTYPE optype)
-	{
-	switch (optype)
-		{
-#ifndef	OPENSSL_NO_RSA
-		case OP_RSA:
-			if (sp->opdata_rsa_n_num != NULL)
-				{
-				BN_free(sp->opdata_rsa_n_num);
-				sp->opdata_rsa_n_num = NULL;
-				}
-			if (sp->opdata_rsa_e_num != NULL)
-				{
-				BN_free(sp->opdata_rsa_e_num);
-				sp->opdata_rsa_e_num = NULL;
-				}
-			if (sp->opdata_rsa_d_num != NULL)
-				{
-				BN_free(sp->opdata_rsa_d_num);
-				sp->opdata_rsa_d_num = NULL;
-				}
-			break;
-#endif
-#ifndef	OPENSSL_NO_DSA
-		case OP_DSA:
-			if (sp->opdata_dsa_pub_num != NULL)
-				{
-				BN_free(sp->opdata_dsa_pub_num);
-				sp->opdata_dsa_pub_num = NULL;
-				}
-			if (sp->opdata_dsa_priv_num != NULL)
-				{
-				BN_free(sp->opdata_dsa_priv_num);
-				sp->opdata_dsa_priv_num = NULL;
-				}
-			break;
-#endif
-#ifndef	OPENSSL_NO_DH
-		case OP_DH:
-			if (sp->opdata_dh_priv_num != NULL)
-				{
-				BN_free(sp->opdata_dh_priv_num);
-				sp->opdata_dh_priv_num = NULL;
-				}
-			break;
-#endif
-		default:
-			break;
-		}
-	}
-
-/*
- * Get new PK11_SESSION structure ready for use. Every process must have
- * its own freelist of PK11_SESSION structures so handle fork() here
- * by destroying the old and creating new freelist.
- * The returned PK11_SESSION structure is disconnected from the freelist.
- */
-PK11_SESSION *
-pk11_get_session(PK11_OPTYPE optype)
-	{
-	PK11_SESSION *sp = NULL, *sp1, *freelist;
-	pthread_mutex_t *freelist_lock;
-	static pid_t pid = 0;
-	pid_t new_pid;
-	CK_RV rv;
-
-	switch (optype)
-		{
-		case OP_RSA:
-		case OP_DSA:
-		case OP_DH:
-		case OP_RAND:
-		case OP_DIGEST:
-		case OP_CIPHER:
-			freelist_lock = session_cache[optype].lock;
-			break;
-		default:
-			PK11err(PK11_F_GET_SESSION,
-				PK11_R_INVALID_OPERATION_TYPE);
-			return (NULL);
-		}
-	(void) pthread_mutex_lock(freelist_lock);
-
-	/*
-	 * Will use it to find out if we forked. We cannot use the PID field in
-	 * the session structure because we could get a newly allocated session
-	 * here, with no PID information.
-	 */
-	if (pid == 0)
-		pid = getpid();
-
-	freelist = session_cache[optype].head;
-	sp = freelist;
-
-	/*
-	 * If the free list is empty, allocate new uninitialized (filled
-	 * with zeroes) PK11_SESSION structure otherwise return first
-	 * structure from the freelist.
-	 */
-	if (sp == NULL)
-		{
-		if ((sp = OPENSSL_malloc(sizeof (PK11_SESSION))) == NULL)
-			{
-			PK11err(PK11_F_GET_SESSION,
-				PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-		(void) memset(sp, 0, sizeof (PK11_SESSION));
-
-		/*
-		 * It is a new session so it will look like a cache miss to the
-		 * code below. So, we must not try to to destroy its members so
-		 * mark them as unused.
-		 */
-		sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
-		sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
-		}
-	else
-		freelist = sp->next;
-
-	/*
-	 * Check whether we have forked. In that case, we must get rid of all
-	 * inherited sessions and start allocating new ones.
-	 */
-	if (pid != (new_pid = getpid()))
-		{
-		pid = new_pid;
-
-		/*
-		 * We are a new process and thus need to free any inherited
-		 * PK11_SESSION objects aside from the first session (sp) which
-		 * is the only PK11_SESSION structure we will reuse (for the
-		 * head of the list).
-		 */
-		while ((sp1 = freelist) != NULL)
-			{
-			freelist = sp1->next;
-			/*
-			 * NOTE: we do not want to call pk11_free_all_sessions()
-			 * here because it would close underlying PKCS#11
-			 * sessions and destroy all objects.
-			 */
-			pk11_free_nums(sp1, optype);
-			OPENSSL_free(sp1);
-			}
-
-		/* we have to free the active list as well. */
-		pk11_free_active_list(optype);
-
-		/* Initialize the process */
-		rv = pFuncList->C_Initialize(NULL_PTR);
-		if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
-			{
-			PK11err_add_data(PK11_F_GET_SESSION, PK11_R_INITIALIZE,
-			    rv);
-			OPENSSL_free(sp);
-			sp = NULL;
-			goto err;
-			}
-
-		/*
-		 * Choose slot here since the slot table is different on this
-		 * process. If we are here then we must have found at least one
-		 * usable slot before so we don't need to check any_slot_found.
-		 * See pk11_library_init()'s usage of this function for more
-		 * information.
-		 */
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-		if (check_hw_mechanisms() == 0)
-			goto err;
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-		if (pk11_choose_slots(NULL) == 0)
-			goto err;
-
-		/* Open the global_session for the new process */
-		rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
-			NULL_PTR, NULL_PTR, &global_session);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_GET_SESSION, PK11_R_OPENSESSION,
-			    rv);
-			OPENSSL_free(sp);
-			sp = NULL;
-			goto err;
-			}
-
-		/*
-		 * It is an inherited session from our parent so it needs
-		 * re-initialization.
-		 */
-		if (pk11_setup_session(sp, optype) == 0)
-			{
-			OPENSSL_free(sp);
-			sp = NULL;
-			goto err;
-			}
-		if (pk11_token_relogin(sp->session) == 0)
-			{
-			/*
-			 * We will keep the session in the cache list and let
-			 * the caller cope with the situation.
-			 */
-			freelist = sp;
-			sp = NULL;
-			goto err;
-			}
-		}
-
-	if (sp->pid == 0)
-		{
-		/* It is a new session and needs initialization. */
-		if (pk11_setup_session(sp, optype) == 0)
-			{
-			OPENSSL_free(sp);
-			sp = NULL;
-			}
-		}
-
-	/* set new head for the list of PK11_SESSION objects */
-	session_cache[optype].head = freelist;
-
-err:
-	if (sp != NULL)
-		sp->next = NULL;
-
-	(void) pthread_mutex_unlock(freelist_lock);
-
-	return (sp);
-	}
-
-
-void
-pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype)
-	{
-	pthread_mutex_t *freelist_lock;
-	PK11_SESSION *freelist;
-
-	/*
-	 * If this is a session from the parent it will be taken care of and
-	 * freed in pk11_get_session() as part of the post-fork clean up the
-	 * next time we will ask for a new session.
-	 */
-	if (sp == NULL || sp->pid != getpid())
-		return;
-
-	switch (optype)
-		{
-		case OP_RSA:
-		case OP_DSA:
-		case OP_DH:
-		case OP_RAND:
-		case OP_DIGEST:
-		case OP_CIPHER:
-			freelist_lock = session_cache[optype].lock;
-			break;
-		default:
-			PK11err(PK11_F_RETURN_SESSION,
-				PK11_R_INVALID_OPERATION_TYPE);
-			return;
-		}
-
-	(void) pthread_mutex_lock(freelist_lock);
-	freelist = session_cache[optype].head;
-	sp->next = freelist;
-	session_cache[optype].head = sp;
-	(void) pthread_mutex_unlock(freelist_lock);
-	}
-
-
-/* Destroy all objects. This function is called when the engine is finished */
-static int pk11_free_all_sessions()
-	{
-	int ret = 1;
-	int type;
-
-#ifndef OPENSSL_NO_RSA
-	(void) pk11_destroy_rsa_key_objects(NULL);
-#endif	/* OPENSSL_NO_RSA */
-#ifndef OPENSSL_NO_DSA
-	(void) pk11_destroy_dsa_key_objects(NULL);
-#endif	/* OPENSSL_NO_DSA */
-#ifndef OPENSSL_NO_DH
-	(void) pk11_destroy_dh_key_objects(NULL);
-#endif	/* OPENSSL_NO_DH */
-	(void) pk11_destroy_cipher_key_objects(NULL);
-
-	/*
-	 * We try to release as much as we can but any error means that we will
-	 * return 0 on exit.
-	 */
-	for (type = 0; type < OP_MAX; type++)
-		{
-		if (pk11_free_session_list(type) == 0)
-			ret = 0;
-		}
-
-	return (ret);
-	}
-
-/*
- * Destroy session structures from the linked list specified. Free as many
- * sessions as possible but any failure in C_CloseSession() means that we
- * return an error on return.
- */
-static int pk11_free_session_list(PK11_OPTYPE optype)
-	{
-	CK_RV rv;
-	PK11_SESSION *sp = NULL;
-	PK11_SESSION *freelist = NULL;
-	pid_t mypid = getpid();
-	pthread_mutex_t *freelist_lock;
-	int ret = 1;
-
-	switch (optype)
-		{
-		case OP_RSA:
-		case OP_DSA:
-		case OP_DH:
-		case OP_RAND:
-		case OP_DIGEST:
-		case OP_CIPHER:
-			freelist_lock = session_cache[optype].lock;
-			break;
-		default:
-			PK11err(PK11_F_FREE_ALL_SESSIONS,
-				PK11_R_INVALID_OPERATION_TYPE);
-			return (0);
-		}
-
-	(void) pthread_mutex_lock(freelist_lock);
-	freelist = session_cache[optype].head;
-	while ((sp = freelist) != NULL)
-		{
-		if (sp->session != CK_INVALID_HANDLE && sp->pid == mypid)
-			{
-			rv = pFuncList->C_CloseSession(sp->session);
-			if (rv != CKR_OK)
-				{
-				PK11err_add_data(PK11_F_FREE_ALL_SESSIONS,
-					PK11_R_CLOSESESSION, rv);
-				ret = 0;
-				}
-			}
-		freelist = sp->next;
-		pk11_free_nums(sp, optype);
-		OPENSSL_free(sp);
-		}
-
-	(void) pthread_mutex_unlock(freelist_lock);
-	return (ret);
-	}
-
-
-static int
-pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype)
-	{
-	CK_RV rv;
-	CK_SLOT_ID myslot;
-
-	switch (optype)
-		{
-		case OP_RSA:
-		case OP_DSA:
-		case OP_DH:
-			myslot = pubkey_SLOTID;
-			break;
-		case OP_RAND:
-			myslot = rand_SLOTID;
-			break;
-		case OP_DIGEST:
-		case OP_CIPHER:
-			myslot = SLOTID;
-			break;
-		default:
-			PK11err(PK11_F_SETUP_SESSION,
-			    PK11_R_INVALID_OPERATION_TYPE);
-			return (0);
-		}
-
-	sp->session = CK_INVALID_HANDLE;
-	DEBUG_SLOT_SEL("%s: myslot=%d optype=%d\n", PK11_DBG, myslot, optype);
-	rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
-		NULL_PTR, NULL_PTR, &sp->session);
-	if (rv == CKR_CRYPTOKI_NOT_INITIALIZED)
-		{
-		/*
-		 * We are probably a child process so force the
-		 * reinitialize of the session
-		 */
-		pk11_library_initialized = CK_FALSE;
-		if (!pk11_library_init(NULL))
-			return (0);
-		rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
-			NULL_PTR, NULL_PTR, &sp->session);
-		}
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION, rv);
-		return (0);
-		}
-
-	sp->pid = getpid();
-
-	switch (optype)
-		{
-#ifndef OPENSSL_NO_RSA
-		case OP_RSA:
-			sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
-			sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
-			sp->opdata_rsa_pub = NULL;
-			sp->opdata_rsa_n_num = NULL;
-			sp->opdata_rsa_e_num = NULL;
-			sp->opdata_rsa_priv = NULL;
-			sp->opdata_rsa_d_num = NULL;
-			break;
-#endif	/* OPENSSL_NO_RSA */
-#ifndef OPENSSL_NO_DSA
-		case OP_DSA:
-			sp->opdata_dsa_pub_key = CK_INVALID_HANDLE;
-			sp->opdata_dsa_priv_key = CK_INVALID_HANDLE;
-			sp->opdata_dsa_pub = NULL;
-			sp->opdata_dsa_pub_num = NULL;
-			sp->opdata_dsa_priv = NULL;
-			sp->opdata_dsa_priv_num = NULL;
-			break;
-#endif	/* OPENSSL_NO_DSA */
-#ifndef OPENSSL_NO_DH
-		case OP_DH:
-			sp->opdata_dh_key = CK_INVALID_HANDLE;
-			sp->opdata_dh = NULL;
-			sp->opdata_dh_priv_num = NULL;
-			break;
-#endif	/* OPENSSL_NO_DH */
-		case OP_CIPHER:
-			sp->opdata_cipher_key = CK_INVALID_HANDLE;
-			sp->opdata_encrypt = -1;
-			break;
-		}
-
-	/*
-	 * We always initialize the session as containing a non-persistent
-	 * object. The key load functions set it to persistent if that is so.
-	 */
-	sp->persistent = CK_FALSE;
-	return (1);
-	}
-
-#ifndef OPENSSL_NO_RSA
-/*
- * Destroy all non-NULL RSA parameters. For the RSA keys by reference code,
- * public components 'n'/'e' are the key components we use to check for the
- * cache hit even for the private keys. So, no matter whether we are destroying
- * a public or a private key, we always free what we can.
- */
-static void
-destroy_all_rsa_params(PK11_SESSION *sp)
-	{
-	if (sp->opdata_rsa_n_num != NULL)
-		{
-		BN_free(sp->opdata_rsa_n_num);
-		sp->opdata_rsa_n_num = NULL;
-		}
-	if (sp->opdata_rsa_e_num != NULL)
-		{
-		BN_free(sp->opdata_rsa_e_num);
-		sp->opdata_rsa_e_num = NULL;
-		}
-	if (sp->opdata_rsa_d_num != NULL)
-		{
-		BN_free(sp->opdata_rsa_d_num);
-		sp->opdata_rsa_d_num = NULL;
-		}
-	}
-
-/* Destroy RSA public key from single session. */
-int
-pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
-	{
-	int ret = 0;
-
-	if (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE)
-		{
-		TRY_OBJ_DESTROY(sp, sp->opdata_rsa_pub_key,
-		    ret, uselock, OP_RSA);
-		sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
-		sp->opdata_rsa_pub = NULL;
-		destroy_all_rsa_params(sp);
-		}
-
-	return (ret);
-	}
-
-/* Destroy RSA private key from single session. */
-int
-pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
-	{
-	int ret = 0;
-
-	if (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE)
-		{
-		TRY_OBJ_DESTROY(sp, sp->opdata_rsa_priv_key,
-		    ret, uselock, OP_RSA);
-		sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
-		sp->opdata_rsa_priv = NULL;
-		destroy_all_rsa_params(sp);
-		}
-
-	return (ret);
-	}
-
-/*
- * Destroy RSA key object wrapper. If session is NULL, try to destroy all
- * objects in the free list.
- */
-int
-pk11_destroy_rsa_key_objects(PK11_SESSION *session)
-	{
-	int ret = 1;
-	PK11_SESSION *sp = NULL;
-	PK11_SESSION *local_free_session;
-	CK_BBOOL uselock = CK_TRUE;
-
-	if (session != NULL)
-		local_free_session = session;
-	else
-		{
-		(void) pthread_mutex_lock(session_cache[OP_RSA].lock);
-		local_free_session = session_cache[OP_RSA].head;
-		uselock = CK_FALSE;
-		}
-
-	/*
-	 * go through the list of sessions and delete key objects
-	 */
-	while ((sp = local_free_session) != NULL)
-		{
-		local_free_session = sp->next;
-
-		/*
-		 * Do not terminate list traversal if one of the
-		 * destroy operations fails.
-		 */
-		if (pk11_destroy_rsa_object_pub(sp, uselock) == 0)
-			{
-			ret = 0;
-			continue;
-			}
-		if (pk11_destroy_rsa_object_priv(sp, uselock) == 0)
-			{
-			ret = 0;
-			continue;
-			}
-		}
-
-	if (session == NULL)
-		(void) pthread_mutex_unlock(session_cache[OP_RSA].lock);
-
-	return (ret);
-	}
-#endif	/* OPENSSL_NO_RSA */
-
-#ifndef OPENSSL_NO_DSA
-/* Destroy DSA public key from single session. */
-int
-pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
-	{
-	int ret = 0;
-
-	if (sp->opdata_dsa_pub_key != CK_INVALID_HANDLE)
-		{
-		TRY_OBJ_DESTROY(sp, sp->opdata_dsa_pub_key,
-		    ret, uselock, OP_DSA);
-		sp->opdata_dsa_pub_key = CK_INVALID_HANDLE;
-		sp->opdata_dsa_pub = NULL;
-		if (sp->opdata_dsa_pub_num != NULL)
-			{
-			BN_free(sp->opdata_dsa_pub_num);
-			sp->opdata_dsa_pub_num = NULL;
-			}
-		}
-
-	return (ret);
-	}
-
-/* Destroy DSA private key from single session. */
-int
-pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
-	{
-	int ret = 0;
-
-	if (sp->opdata_dsa_priv_key != CK_INVALID_HANDLE)
-		{
-		TRY_OBJ_DESTROY(sp, sp->opdata_dsa_priv_key,
-		    ret, uselock, OP_DSA);
-		sp->opdata_dsa_priv_key = CK_INVALID_HANDLE;
-		sp->opdata_dsa_priv = NULL;
-		if (sp->opdata_dsa_priv_num != NULL)
-			{
-			BN_free(sp->opdata_dsa_priv_num);
-			sp->opdata_dsa_priv_num = NULL;
-			}
-		}
-
-	return (ret);
-	}
-
-/*
- * Destroy DSA key object wrapper. If session is NULL, try to destroy all
- * objects in the free list.
- */
-int
-pk11_destroy_dsa_key_objects(PK11_SESSION *session)
-	{
-	int ret = 1;
-	PK11_SESSION *sp = NULL;
-	PK11_SESSION *local_free_session;
-	CK_BBOOL uselock = CK_TRUE;
-
-	if (session != NULL)
-		local_free_session = session;
-	else
-		{
-		(void) pthread_mutex_lock(session_cache[OP_DSA].lock);
-		local_free_session = session_cache[OP_DSA].head;
-		uselock = CK_FALSE;
-		}
-
-	/*
-	 * go through the list of sessions and delete key objects
-	 */
-	while ((sp = local_free_session) != NULL)
-		{
-		local_free_session = sp->next;
-
-		/*
-		 * Do not terminate list traversal if one of the
-		 * destroy operations fails.
-		 */
-		if (pk11_destroy_dsa_object_pub(sp, uselock) == 0)
-			{
-			ret = 0;
-			continue;
-			}
-		if (pk11_destroy_dsa_object_priv(sp, uselock) == 0)
-			{
-			ret = 0;
-			continue;
-			}
-		}
-
-	if (session == NULL)
-		(void) pthread_mutex_unlock(session_cache[OP_DSA].lock);
-
-	return (ret);
-	}
-#endif	/* OPENSSL_NO_DSA */
-
-#ifndef OPENSSL_NO_DH
-/* Destroy DH key from single session. */
-int
-pk11_destroy_dh_object(PK11_SESSION *sp, CK_BBOOL uselock)
-	{
-	int ret = 0;
-
-	if (sp->opdata_dh_key != CK_INVALID_HANDLE)
-		{
-		TRY_OBJ_DESTROY(sp, sp->opdata_dh_key,
-		    ret, uselock, OP_DH);
-		sp->opdata_dh_key = CK_INVALID_HANDLE;
-		sp->opdata_dh = NULL;
-		if (sp->opdata_dh_priv_num != NULL)
-			{
-			BN_free(sp->opdata_dh_priv_num);
-			sp->opdata_dh_priv_num = NULL;
-			}
-		}
-
-	return (ret);
-	}
-
-/*
- * Destroy DH key object wrapper.
- *
- * arg0: pointer to PKCS#11 engine session structure
- *       if session is NULL, try to destroy all objects in the free list
- */
-int
-pk11_destroy_dh_key_objects(PK11_SESSION *session)
-	{
-	int ret = 1;
-	PK11_SESSION *sp = NULL;
-	PK11_SESSION *local_free_session;
-	CK_BBOOL uselock = CK_TRUE;
-
-	if (session != NULL)
-		local_free_session = session;
-	else
-		{
-		(void) pthread_mutex_lock(session_cache[OP_DH].lock);
-		local_free_session = session_cache[OP_DH].head;
-		uselock = CK_FALSE;
-		}
-
-	while ((sp = local_free_session) != NULL)
-		{
-		local_free_session = sp->next;
-
-		/*
-		 * Do not terminate list traversal if one of the
-		 * destroy operations fails.
-		 */
-		if (pk11_destroy_dh_object(sp, uselock) == 0)
-			{
-			ret = 0;
-			continue;
-			}
-		}
-	if (session == NULL)
-		(void) pthread_mutex_unlock(session_cache[OP_DH].lock);
-
-	return (ret);
-	}
-#endif	/* OPENSSL_NO_DH */
-
-static int
-pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
-    CK_BBOOL persistent)
-	{
-	CK_RV rv;
-
-	/*
-	 * We never try to destroy persistent objects which are the objects
-	 * stored in the keystore. Also, we always use read-only sessions so
-	 * C_DestroyObject() would be returning CKR_SESSION_READ_ONLY here.
-	 */
-	if (persistent == CK_TRUE)
-		return (1);
-
-	rv = pFuncList->C_DestroyObject(session, oh);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DESTROY_OBJECT, PK11_R_DESTROYOBJECT,
-		    rv);
-		return (0);
-		}
-
-	return (1);
-	}
-
-
-/* Symmetric ciphers and digests support functions */
-
-static int
-cipher_nid_to_pk11(int nid)
-	{
-	int i;
-
-	for (i = 0; i < PK11_CIPHER_MAX; i++)
-		if (ciphers[i].nid == nid)
-			return (ciphers[i].id);
-	return (-1);
-	}
-
-static int
-pk11_usable_ciphers(const int **nids)
-	{
-	if (cipher_count > 0)
-		*nids = cipher_nids;
-	else
-		*nids = NULL;
-	return (cipher_count);
-	}
-
-static int
-pk11_usable_digests(const int **nids)
-	{
-	if (digest_count > 0)
-		*nids = digest_nids;
-	else
-		*nids = NULL;
-	return (digest_count);
-	}
-
-/*
- * Init context for encryption or decryption using a symmetric key.
- */
-static int pk11_init_symmetric(EVP_CIPHER_CTX *ctx, PK11_CIPHER *pcipher,
-	PK11_SESSION *sp, CK_MECHANISM_PTR pmech)
-	{
-	CK_RV rv;
-	CK_AES_CTR_PARAMS ctr_params;
-
-	/*
-	 * We expect pmech->mechanism to be already set and
-	 * pParameter/ulParameterLen initialized to NULL/0 before
-	 * pk11_init_symmetric() is called.
-	 */
-	OPENSSL_assert(pmech->mechanism != NULL);
-	OPENSSL_assert(pmech->pParameter == NULL);
-	OPENSSL_assert(pmech->ulParameterLen == 0);
-
-	if (ctx->cipher->nid == NID_aes_128_ctr ||
-	    ctx->cipher->nid == NID_aes_192_ctr ||
-	    ctx->cipher->nid == NID_aes_256_ctr)
-		{
-		pmech->pParameter = (void *)(&ctr_params);
-		pmech->ulParameterLen = sizeof (ctr_params);
-		/*
-		 * For now, we are limited to the fixed length of the counter,
-		 * it covers the whole counter block. That's what RFC 4344
-		 * needs. For more information on internal structure of the
-		 * counter block, see RFC 3686. If needed in the future, we can
-		 * add code so that the counter length can be set via
-		 * ENGINE_ctrl() function.
-		 */
-		ctr_params.ulCounterBits = AES_BLOCK_SIZE * 8;
-		OPENSSL_assert(pcipher->iv_len == AES_BLOCK_SIZE);
-		(void) memcpy(ctr_params.cb, ctx->iv, AES_BLOCK_SIZE);
-		}
-	else
-		{
-		if (pcipher->iv_len > 0)
-			{
-			pmech->pParameter = (void *)ctx->iv;
-			pmech->ulParameterLen = pcipher->iv_len;
-			}
-		}
-
-	/* if we get here, the encryption needs to be reinitialized */
-	if (ctx->encrypt)
-		rv = pFuncList->C_EncryptInit(sp->session, pmech,
-			sp->opdata_cipher_key);
-	else
-		rv = pFuncList->C_DecryptInit(sp->session, pmech,
-			sp->opdata_cipher_key);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_CIPHER_INIT, ctx->encrypt ?
-		    PK11_R_ENCRYPTINIT : PK11_R_DECRYPTINIT, rv);
-		pk11_return_session(sp, OP_CIPHER);
-		return (0);
-		}
-
-	return (1);
-	}
-
-/* ARGSUSED */
-static int
-pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-    const unsigned char *iv, int enc)
-	{
-	CK_MECHANISM mech;
-	int index;
-	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
-	PK11_SESSION *sp;
-	PK11_CIPHER *p_ciph_table_row;
-
-	state->sp = NULL;
-
-	index = cipher_nid_to_pk11(ctx->cipher->nid);
-	if (index < 0 || index >= PK11_CIPHER_MAX)
-		return (0);
-
-	p_ciph_table_row = &ciphers[index];
-	/*
-	 * iv_len in the ctx->cipher structure is the maximum IV length for the
-	 * current cipher and it must be less or equal to the IV length in our
-	 * ciphers table. The key length must be in the allowed interval. From
-	 * all cipher modes that the PKCS#11 engine supports only RC4 allows a
-	 * key length to be in some range, all other NIDs have a precise key
-	 * length. Every application can define its own EVP functions so this
-	 * code serves as a sanity check.
-	 *
-	 * Note that the reason why the IV length in ctx->cipher might be
-	 * greater than the actual length is that OpenSSL uses BLOCK_CIPHER_defs
-	 * macro to define functions that return EVP structures for all DES
-	 * modes. So, even ECB modes get 8 byte IV.
-	 */
-	if (ctx->cipher->iv_len < p_ciph_table_row->iv_len ||
-	    ctx->key_len < p_ciph_table_row->min_key_len ||
-	    ctx->key_len > p_ciph_table_row->max_key_len) {
-		PK11err(PK11_F_CIPHER_INIT, PK11_R_KEY_OR_IV_LEN_PROBLEM);
-		return (0);
-	}
-
-	if ((sp = pk11_get_session(OP_CIPHER)) == NULL)
-		return (0);
-
-	/* if applicable, the mechanism parameter is used for IV */
-	mech.mechanism = p_ciph_table_row->mech_type;
-	mech.pParameter = NULL;
-	mech.ulParameterLen = 0;
-
-	/* The key object is destroyed here if it is not the current key. */
-	(void) check_new_cipher_key(sp, key, ctx->key_len);
-
-	/*
-	 * If the key is the same and the encryption is also the same, then
-	 * just reuse it. However, we must not forget to reinitialize the
-	 * context that was finalized in pk11_cipher_cleanup().
-	 */
-	if (sp->opdata_cipher_key != CK_INVALID_HANDLE &&
-	    sp->opdata_encrypt == ctx->encrypt)
-		{
-		state->sp = sp;
-		if (pk11_init_symmetric(ctx, p_ciph_table_row, sp, &mech) == 0)
-			return (0);
-
-		return (1);
-		}
-
-	/*
-	 * Check if the key has been invalidated. If so, a new key object
-	 * needs to be created.
-	 */
-	if (sp->opdata_cipher_key == CK_INVALID_HANDLE)
-		{
-		sp->opdata_cipher_key = pk11_get_cipher_key(
-			ctx, key, p_ciph_table_row->key_type, sp);
-		}
-
-	if (sp->opdata_encrypt != ctx->encrypt && sp->opdata_encrypt != -1)
-		{
-		/*
-		 * The previous encryption/decryption is different. Need to
-		 * terminate the previous * active encryption/decryption here.
-		 */
-		if (!pk11_cipher_final(sp))
-			{
-			pk11_return_session(sp, OP_CIPHER);
-			return (0);
-			}
-		}
-
-	if (sp->opdata_cipher_key == CK_INVALID_HANDLE)
-		{
-		pk11_return_session(sp, OP_CIPHER);
-		return (0);
-		}
-
-	/* now initialize the context with a new key */
-	if (pk11_init_symmetric(ctx, p_ciph_table_row, sp, &mech) == 0)
-		return (0);
-
-	sp->opdata_encrypt = ctx->encrypt;
-	state->sp = sp;
-
-	return (1);
-	}
-
-/*
- * When reusing the same key in an encryption/decryption session for a
- * decryption/encryption session, we need to close the active session
- * and recreate a new one. Note that the key is in the global session so
- * that it needs not be recreated.
- *
- * It is more appropriate to use C_En/DecryptFinish here. At the time of this
- * development, these two functions in the PKCS#11 libraries used return
- * unexpected errors when passing in 0 length output. It may be a good
- * idea to try them again if performance is a problem here and fix
- * C_En/DecryptFinial if there are bugs there causing the problem.
- */
-static int
-pk11_cipher_final(PK11_SESSION *sp)
-	{
-	CK_RV rv;
-
-	rv = pFuncList->C_CloseSession(sp->session);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_CIPHER_FINAL, PK11_R_CLOSESESSION, rv);
-		return (0);
-		}
-
-	rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
-		NULL_PTR, NULL_PTR, &sp->session);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_CIPHER_FINAL, PK11_R_OPENSESSION, rv);
-		return (0);
-		}
-
-	return (1);
-	}
-
-/*
- * An engine interface function. The calling function allocates sufficient
- * memory for the output buffer "out" to hold the results.
- */
-static int
-pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-	const unsigned char *in, size_t inl)
-	{
-	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
-	PK11_SESSION *sp;
-	CK_RV rv;
-	unsigned long outl = inl;
-
-	if (state == NULL || state->sp == NULL)
-		return (0);
-
-	sp = (PK11_SESSION *) state->sp;
-
-	if (!inl)
-		return (1);
-
-	/* RC4 is the only stream cipher we support */
-	if (ctx->cipher->nid != NID_rc4 && (inl % ctx->cipher->block_size) != 0)
-		return (0);
-
-	if (ctx->encrypt)
-		{
-		rv = pFuncList->C_EncryptUpdate(sp->session,
-			(unsigned char *)in, inl, out, &outl);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_CIPHER_DO_CIPHER,
-			    PK11_R_ENCRYPTUPDATE, rv);
-			return (0);
-			}
-		}
-	else
-		{
-		rv = pFuncList->C_DecryptUpdate(sp->session,
-			(unsigned char *)in, inl, out, &outl);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_CIPHER_DO_CIPHER,
-			    PK11_R_DECRYPTUPDATE, rv);
-			return (0);
-			}
-		}
-
-	/*
-	 * For DES_CBC, DES3_CBC, AES_CBC, and RC4, the output size is always
-	 * the same size of input.
-	 * The application has guaranteed to call the block ciphers with
-	 * correctly aligned buffers.
-	 */
-	if (inl != outl)
-		return (0);
-
-	return (1);
-	}
-
-/*
- * Return the session to the pool. Calling C_EncryptFinal() and C_DecryptFinal()
- * here is the right thing because in EVP_DecryptFinal_ex(), engine's
- * do_cipher() is not even called, and in EVP_EncryptFinal_ex() it is called but
- * the engine can't find out that it's the finalizing call. We wouldn't
- * necessarily have to finalize the context here since reinitializing it with
- * C_(Encrypt|Decrypt)Init() should be fine but for the sake of correctness,
- * let's do it. Some implementations might leak memory if the previously used
- * context is initialized without finalizing it first.
- */
-static int
-pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx)
-	{
-	CK_RV rv;
-	CK_ULONG len = EVP_MAX_BLOCK_LENGTH;
-	CK_BYTE buf[EVP_MAX_BLOCK_LENGTH];
-	PK11_CIPHER_STATE *state = ctx->cipher_data;
-
-	if (state != NULL && state->sp != NULL)
-		{
-		/*
-		 * We are not interested in the data here, we just need to get
-		 * rid of the context.
-		 */
-		if (ctx->encrypt)
-			rv = pFuncList->C_EncryptFinal(
-			    state->sp->session, buf, &len);
-		else
-			rv = pFuncList->C_DecryptFinal(
-			    state->sp->session, buf, &len);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_CIPHER_CLEANUP, ctx->encrypt ?
-			    PK11_R_ENCRYPTFINAL : PK11_R_DECRYPTFINAL, rv);
-			pk11_return_session(state->sp, OP_CIPHER);
-			return (0);
-			}
-
-		pk11_return_session(state->sp, OP_CIPHER);
-		state->sp = NULL;
-		}
-
-	return (1);
-	}
-
-/*
- * Registered by the ENGINE when used to find out how to deal with
- * a particular NID in the ENGINE. This says what we'll do at the
- * top level - note, that list is restricted by what we answer with
- */
-/* ARGSUSED */
-static int
-pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
-	const int **nids, int nid)
-	{
-	if (!cipher)
-		return (pk11_usable_ciphers(nids));
-
-	switch (nid)
-		{
-		case NID_des_ede3_cbc:
-			*cipher = &pk11_3des_cbc;
-			break;
-		case NID_des_cbc:
-			*cipher = &pk11_des_cbc;
-			break;
-		case NID_des_ede3_ecb:
-			*cipher = &pk11_3des_ecb;
-			break;
-		case NID_des_ecb:
-			*cipher = &pk11_des_ecb;
-			break;
-		case NID_aes_128_cbc:
-			*cipher = &pk11_aes_128_cbc;
-			break;
-		case NID_aes_192_cbc:
-			*cipher = &pk11_aes_192_cbc;
-			break;
-		case NID_aes_256_cbc:
-			*cipher = &pk11_aes_256_cbc;
-			break;
-		case NID_aes_128_ecb:
-			*cipher = &pk11_aes_128_ecb;
-			break;
-		case NID_aes_192_ecb:
-			*cipher = &pk11_aes_192_ecb;
-			break;
-		case NID_aes_256_ecb:
-			*cipher = &pk11_aes_256_ecb;
-			break;
-		case NID_aes_128_ctr:
-			*cipher = &pk11_aes_128_ctr;
-			break;
-		case NID_aes_192_ctr:
-			*cipher = &pk11_aes_192_ctr;
-			break;
-		case NID_aes_256_ctr:
-			*cipher = &pk11_aes_256_ctr;
-			break;
-		case NID_bf_cbc:
-			*cipher = &pk11_bf_cbc;
-			break;
-		case NID_rc4:
-			*cipher = &pk11_rc4;
-			break;
-		default:
-			*cipher = NULL;
-			break;
-		}
-	return (*cipher != NULL);
-	}
-
-/* ARGSUSED */
-static int
-pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
-	const int **nids, int nid)
-	{
-	if (!digest)
-		return (pk11_usable_digests(nids));
-
-	switch (nid)
-		{
-		case NID_md5:
-			*digest = &pk11_md5;
-			break;
-		/*
-		 * A special case. For "openssl dgst -dss1 -engine pkcs11 ...",
-		 * OpenSSL calls EVP_get_digestbyname() on "dss1" which ends up
-		 * calling pk11_engine_digests() for NID_dsa. Internally, if an
-		 * engine is not used, OpenSSL uses SHA1_Init() as expected for
-		 * DSA. So, we must return pk11_sha1() for NID_dsa as well. Note
-		 * that this must have changed between 0.9.8 and 1.0.0 since we
-		 * did not have the problem with the 0.9.8 version.
-		 */
-		case NID_sha1:
-		case NID_dsa:
-			*digest = &pk11_sha1;
-			break;
-		case NID_sha224:
-			*digest = &pk11_sha224;
-			break;
-		case NID_sha256:
-			*digest = &pk11_sha256;
-			break;
-		case NID_sha384:
-			*digest = &pk11_sha384;
-			break;
-		case NID_sha512:
-			*digest = &pk11_sha512;
-			break;
-		default:
-			*digest = NULL;
-			break;
-		}
-	return (*digest != NULL);
-	}
-
-
-/* Create a secret key object in a PKCS#11 session */
-static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
-	const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp)
-	{
-	CK_RV rv;
-	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-	CK_OBJECT_CLASS obj_key = CKO_SECRET_KEY;
-	CK_ULONG ul_key_attr_count = 6;
-
-	CK_ATTRIBUTE  a_key_template[] =
-		{
-		{CKA_CLASS, (void*) NULL, sizeof (CK_OBJECT_CLASS)},
-		{CKA_KEY_TYPE, (void*) NULL, sizeof (CK_KEY_TYPE)},
-		{CKA_TOKEN, &pk11_false, sizeof (pk11_false)},
-		{CKA_ENCRYPT, &pk11_true, sizeof (pk11_true)},
-		{CKA_DECRYPT, &pk11_true, sizeof (pk11_true)},
-		{CKA_VALUE, (void*) NULL, 0},
-		};
-
-	/*
-	 * Create secret key object in global_session. All other sessions
-	 * can use the key handles. Here is why:
-	 * OpenSSL will call EncryptInit and EncryptUpdate using a secret key.
-	 * It may then call DecryptInit and DecryptUpdate using the same key.
-	 * To use the same key object, we need to call EncryptFinal with
-	 * a 0 length message. Currently, this does not work for 3DES
-	 * mechanism. To get around this problem, we close the session and
-	 * then create a new session to use the same key object. When a session
-	 * is closed, all the object handles will be invalid. Thus, create key
-	 * objects in a global session, an individual session may be closed to
-	 * terminate the active operation.
-	 */
-	CK_SESSION_HANDLE session = global_session;
-	a_key_template[0].pValue = &obj_key;
-	a_key_template[1].pValue = &key_type;
-	a_key_template[5].pValue = (void *) key;
-	a_key_template[5].ulValueLen = (unsigned long) ctx->key_len;
-
-	rv = pFuncList->C_CreateObject(session,
-		a_key_template, ul_key_attr_count, &h_key);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_CIPHER_KEY, PK11_R_CREATEOBJECT,
-		    rv);
-		goto err;
-		}
-
-	/*
-	 * Save the key information used in this session.
-	 * The max can be saved is PK11_KEY_LEN_MAX.
-	 */
-	sp->opdata_key_len = ctx->key_len > PK11_KEY_LEN_MAX ?
-		PK11_KEY_LEN_MAX : ctx->key_len;
-	(void) memcpy(sp->opdata_key, key, sp->opdata_key_len);
-err:
-
-	return (h_key);
-	}
-
-static int
-md_nid_to_pk11(int nid)
-	{
-	int i;
-
-	for (i = 0; i < PK11_DIGEST_MAX; i++)
-		if (digests[i].nid == nid)
-			return (digests[i].id);
-	return (-1);
-	}
-
-static int
-pk11_digest_init(EVP_MD_CTX *ctx)
-	{
-	CK_RV rv;
-	CK_MECHANISM mech;
-	int index;
-	PK11_SESSION *sp;
-	PK11_DIGEST *pdp;
-	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
-
-	state->sp = NULL;
-
-	index = md_nid_to_pk11(ctx->digest->type);
-	if (index < 0 || index >= PK11_DIGEST_MAX)
-		return (0);
-
-	pdp = &digests[index];
-	if ((sp = pk11_get_session(OP_DIGEST)) == NULL)
-		return (0);
-
-	/* at present, no parameter is needed for supported digests */
-	mech.mechanism = pdp->mech_type;
-	mech.pParameter = NULL;
-	mech.ulParameterLen = 0;
-
-	rv = pFuncList->C_DigestInit(sp->session, &mech);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DIGEST_INIT, PK11_R_DIGESTINIT, rv);
-		pk11_return_session(sp, OP_DIGEST);
-		return (0);
-		}
-
-	state->sp = sp;
-
-	return (1);
-	}
-
-static int
-pk11_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
-	{
-	CK_RV rv;
-	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
-
-	/* 0 length message will cause a failure in C_DigestFinal */
-	if (count == 0)
-		return (1);
-
-	if (state == NULL || state->sp == NULL)
-		return (0);
-
-	rv = pFuncList->C_DigestUpdate(state->sp->session, (CK_BYTE *) data,
-		count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DIGEST_UPDATE, PK11_R_DIGESTUPDATE, rv);
-		pk11_return_session(state->sp, OP_DIGEST);
-		state->sp = NULL;
-		return (0);
-		}
-
-	return (1);
-	}
-
-static int
-pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
-	{
-	CK_RV rv;
-	unsigned long len;
-	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
-	len = ctx->digest->md_size;
-
-	if (state == NULL || state->sp == NULL)
-		return (0);
-
-	rv = pFuncList->C_DigestFinal(state->sp->session, md, &len);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DIGEST_FINAL, PK11_R_DIGESTFINAL, rv);
-		pk11_return_session(state->sp, OP_DIGEST);
-		state->sp = NULL;
-		return (0);
-		}
-
-	if (ctx->digest->md_size != len)
-		return (0);
-
-	/*
-	 * Final is called and digest is returned, so return the session
-	 * to the pool
-	 */
-	pk11_return_session(state->sp, OP_DIGEST);
-	state->sp = NULL;
-
-	return (1);
-	}
-
-static int
-pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
-	{
-	CK_RV rv;
-	int ret = 0;
-	PK11_CIPHER_STATE *state, *state_to;
-	CK_BYTE_PTR pstate = NULL;
-	CK_ULONG ul_state_len;
-
-	if (from->md_data == NULL || to->digest->ctx_size == 0)
-		return (1);
-
-	/* The copy-from state */
-	state = (PK11_CIPHER_STATE *) from->md_data;
-	if (state->sp == NULL)
-		goto err;
-
-	/* Initialize the copy-to state */
-	if (!pk11_digest_init(to))
-		goto err;
-	state_to = (PK11_CIPHER_STATE *) to->md_data;
-
-	/* Get the size of the operation state of the copy-from session */
-	rv = pFuncList->C_GetOperationState(state->sp->session, NULL,
-		&ul_state_len);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE,
-		    rv);
-		goto err;
-		}
-	if (ul_state_len == 0)
-		{
-		goto err;
-		}
-
-	pstate = OPENSSL_malloc(ul_state_len);
-	if (pstate == NULL)
-		{
-		PK11err(PK11_F_DIGEST_COPY, PK11_R_MALLOC_FAILURE);
-		goto err;
-		}
-
-	/* Get the operation state of the copy-from session */
-	rv = pFuncList->C_GetOperationState(state->sp->session, pstate,
-		&ul_state_len);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE,
-		    rv);
-		goto err;
-		}
-
-	/* Set the operation state of the copy-to session */
-	rv = pFuncList->C_SetOperationState(state_to->sp->session, pstate,
-		ul_state_len, 0, 0);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DIGEST_COPY,
-		    PK11_R_SET_OPERATION_STATE, rv);
-		goto err;
-		}
-
-	ret = 1;
-err:
-	if (pstate != NULL)
-		OPENSSL_free(pstate);
-
-	return (ret);
-	}
-
-/* Return any pending session state to the pool */
-static int
-pk11_digest_cleanup(EVP_MD_CTX *ctx)
-	{
-	PK11_CIPHER_STATE *state = ctx->md_data;
-	unsigned char buf[EVP_MAX_MD_SIZE];
-
-	if (state != NULL && state->sp != NULL)
-		{
-		/*
-		 * If state->sp is not NULL then pk11_digest_final() has not
-		 * been called yet. We must call it now to free any memory
-		 * that might have been allocated in the token when
-		 * pk11_digest_init() was called. pk11_digest_final()
-		 * will return the session to the cache.
-		 */
-		if (!pk11_digest_final(ctx, buf))
-			return (0);
-		}
-
-	return (1);
-	}
-
-/*
- * Check if the new key is the same as the key object in the session. If the key
- * is the same, no need to create a new key object. Otherwise, the old key
- * object needs to be destroyed and a new one will be created. Return 1 for
- * cache hit, 0 for cache miss. Note that we must check the key length first
- * otherwise we could end up reusing a different, longer key with the same
- * prefix.
- */
-static int check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key,
-	int key_len)
-	{
-	if (sp->opdata_key_len != key_len ||
-	    memcmp(sp->opdata_key, key, key_len) != 0)
-		{
-		(void) pk11_destroy_cipher_key_objects(sp);
-		return (0);
-		}
-	return (1);
-	}
-
-/* Destroy one or more secret key objects. */
-static int pk11_destroy_cipher_key_objects(PK11_SESSION *session)
-	{
-	int ret = 0;
-	PK11_SESSION *sp = NULL;
-	PK11_SESSION *local_free_session;
-
-	if (session != NULL)
-		local_free_session = session;
-	else
-		{
-		(void) pthread_mutex_lock(session_cache[OP_CIPHER].lock);
-		local_free_session = session_cache[OP_CIPHER].head;
-		}
-
-	while ((sp = local_free_session) != NULL)
-		{
-		local_free_session = sp->next;
-
-		if (sp->opdata_cipher_key != CK_INVALID_HANDLE)
-			{
-			/*
-			 * The secret key object is created in the
-			 * global_session. See pk11_get_cipher_key().
-			 */
-			if (pk11_destroy_object(global_session,
-				sp->opdata_cipher_key, CK_FALSE) == 0)
-				goto err;
-			sp->opdata_cipher_key = CK_INVALID_HANDLE;
-			}
-		}
-	ret = 1;
-err:
-
-	if (session == NULL)
-		(void) pthread_mutex_unlock(session_cache[OP_CIPHER].lock);
-
-	return (ret);
-	}
-
-
-/*
- * Public key mechanisms optionally supported
- *
- * CKM_RSA_X_509
- * CKM_RSA_PKCS
- * CKM_DSA
- *
- * The first slot that supports at least one of those mechanisms is chosen as a
- * public key slot.
- *
- * Symmetric ciphers optionally supported
- *
- * CKM_DES3_CBC
- * CKM_DES_CBC
- * CKM_AES_CBC
- * CKM_DES3_ECB
- * CKM_DES_ECB
- * CKM_AES_ECB
- * CKM_AES_CTR
- * CKM_RC4
- * CKM_BLOWFISH_CBC
- *
- * Digests optionally supported
- *
- * CKM_MD5
- * CKM_SHA_1
- * CKM_SHA224
- * CKM_SHA256
- * CKM_SHA384
- * CKM_SHA512
- *
- * The output of this function is a set of global variables indicating which
- * mechanisms from RSA, DSA, DH and RAND are present, and also two arrays of
- * mechanisms, one for symmetric ciphers and one for digests. Also, 3 global
- * variables carry information about which slot was chosen for (a) public key
- * mechanisms, (b) random operations, and (c) symmetric ciphers and digests.
- */
-static int
-pk11_choose_slots(int *any_slot_found)
-	{
-	CK_SLOT_ID_PTR pSlotList = NULL_PTR;
-	CK_ULONG ulSlotCount = 0;
-	CK_MECHANISM_INFO mech_info;
-	CK_TOKEN_INFO token_info;
-	int i;
-	CK_RV rv;
-	CK_SLOT_ID best_slot_sofar;
-	CK_BBOOL found_candidate_slot = CK_FALSE;
-	int slot_n_cipher = 0;
-	int slot_n_digest = 0;
-	CK_SLOT_ID current_slot = 0;
-	int current_slot_n_cipher = 0;
-	int current_slot_n_digest = 0;
-
-	int local_cipher_nids[PK11_CIPHER_MAX];
-	int local_digest_nids[PK11_DIGEST_MAX];
-
-	/* let's initialize the output parameter */
-	if (any_slot_found != NULL)
-		*any_slot_found = 0;
-
-	/* Get slot list for memory allocation */
-	rv = pFuncList->C_GetSlotList(CK_FALSE, NULL_PTR, &ulSlotCount);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
-		return (0);
-		}
-
-	/* it's not an error if we didn't find any providers */
-	if (ulSlotCount == 0)
-		{
-		DEBUG_SLOT_SEL("%s: no crypto providers found\n", PK11_DBG);
-		return (1);
-		}
-
-	pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
-
-	if (pSlotList == NULL)
-		{
-		PK11err(PK11_F_CHOOSE_SLOT, PK11_R_MALLOC_FAILURE);
-		return (0);
-		}
-
-	/* Get the slot list for processing */
-	rv = pFuncList->C_GetSlotList(CK_FALSE, pSlotList, &ulSlotCount);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
-		OPENSSL_free(pSlotList);
-		return (0);
-		}
-
-	DEBUG_SLOT_SEL("%s: provider: %s\n", PK11_DBG, def_PK11_LIBNAME);
-	DEBUG_SLOT_SEL("%s: number of slots: %d\n", PK11_DBG, ulSlotCount);
-
-	DEBUG_SLOT_SEL("%s: == checking rand slots ==\n", PK11_DBG);
-	for (i = 0; i < ulSlotCount; i++)
-		{
-		current_slot = pSlotList[i];
-
-		DEBUG_SLOT_SEL("%s: checking slot: %d\n", PK11_DBG, i);
-		/* Check if slot has random support. */
-		rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
-		if (rv != CKR_OK)
-			continue;
-
-		DEBUG_SLOT_SEL("%s: token label: %.32s\n", PK11_DBG,
-		    token_info.label);
-
-		if (token_info.flags & CKF_RNG)
-			{
-			DEBUG_SLOT_SEL(
-			    "%s: this token has CKF_RNG flag\n", PK11_DBG);
-			pk11_have_random = CK_TRUE;
-			rand_SLOTID = current_slot;
-			break;
-			}
-		}
-
-	DEBUG_SLOT_SEL("%s: == checking pubkey slots ==\n", PK11_DBG);
-
-	pubkey_SLOTID = pSlotList[0];
-	for (i = 0; i < ulSlotCount; i++)
-		{
-		CK_BBOOL slot_has_rsa = CK_FALSE;
-		CK_BBOOL slot_has_dsa = CK_FALSE;
-		CK_BBOOL slot_has_dh = CK_FALSE;
-		current_slot = pSlotList[i];
-
-		DEBUG_SLOT_SEL("%s: checking slot: %d\n", PK11_DBG, i);
-		rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
-		if (rv != CKR_OK)
-			continue;
-
-		DEBUG_SLOT_SEL("%s: token label: %.32s\n", PK11_DBG,
-		    token_info.label);
-
-#ifndef OPENSSL_NO_RSA
-		/*
-		 * Check if this slot is capable of signing and
-		 * verifying with CKM_RSA_PKCS.
-		 */
-		rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS,
-			&mech_info);
-
-		if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
-				(mech_info.flags & CKF_VERIFY)))
-			{
-			/*
-			 * Check if this slot is capable of encryption,
-			 * decryption, sign, and verify with CKM_RSA_X_509.
-			 */
-			rv = pFuncList->C_GetMechanismInfo(current_slot,
-			    CKM_RSA_X_509, &mech_info);
-
-			if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
-			    (mech_info.flags & CKF_VERIFY) &&
-			    (mech_info.flags & CKF_ENCRYPT) &&
-			    (mech_info.flags & CKF_VERIFY_RECOVER) &&
-			    (mech_info.flags & CKF_DECRYPT)))
-				{
-				slot_has_rsa = CK_TRUE;
-				}
-			}
-#endif	/* OPENSSL_NO_RSA */
-
-#ifndef OPENSSL_NO_DSA
-		/*
-		 * Check if this slot is capable of signing and
-		 * verifying with CKM_DSA.
-		 */
-		rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_DSA,
-			&mech_info);
-		if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
-		    (mech_info.flags & CKF_VERIFY)))
-			{
-			slot_has_dsa = CK_TRUE;
-			}
-
-#endif	/* OPENSSL_NO_DSA */
-
-#ifndef OPENSSL_NO_DH
-		/*
-		 * Check if this slot is capable of DH key generataion and
-		 * derivation.
-		 */
-		rv = pFuncList->C_GetMechanismInfo(current_slot,
-		    CKM_DH_PKCS_KEY_PAIR_GEN, &mech_info);
-
-		if (rv == CKR_OK && (mech_info.flags & CKF_GENERATE_KEY_PAIR))
-			{
-			rv = pFuncList->C_GetMechanismInfo(current_slot,
-				CKM_DH_PKCS_DERIVE, &mech_info);
-			if (rv == CKR_OK && (mech_info.flags & CKF_DERIVE))
-				{
-				slot_has_dh = CK_TRUE;
-				}
-			}
-#endif	/* OPENSSL_NO_DH */
-
-		if (!found_candidate_slot &&
-		    (slot_has_rsa || slot_has_dsa || slot_has_dh))
-			{
-			DEBUG_SLOT_SEL(
-			    "%s: potential slot: %d\n", PK11_DBG, current_slot);
-			best_slot_sofar = current_slot;
-			pk11_have_rsa = slot_has_rsa;
-			pk11_have_dsa = slot_has_dsa;
-			pk11_have_dh = slot_has_dh;
-			found_candidate_slot = CK_TRUE;
-			/*
-			 * Cache the flags for later use. We might need those if
-			 * RSA keys by reference feature is used.
-			 */
-			pubkey_token_flags = token_info.flags;
-			DEBUG_SLOT_SEL(
-			    "%s: setting found_candidate_slot to CK_TRUE\n",
-			    PK11_DBG);
-			DEBUG_SLOT_SEL("%s: best slot so far: %d\n", PK11_DBG,
-			    best_slot_sofar);
-			DEBUG_SLOT_SEL("%s: pubkey flags changed to "
-			    "%lu.\n", PK11_DBG, pubkey_token_flags);
-			}
-		else
-			{
-			DEBUG_SLOT_SEL("%s: no rsa/dsa/dh\n", PK11_DBG);
-			}
-		} /* for */
-
-	if (found_candidate_slot == CK_TRUE)
-		{
-		pubkey_SLOTID = best_slot_sofar;
-		}
-
-	found_candidate_slot = CK_FALSE;
-	best_slot_sofar = 0;
-
-	DEBUG_SLOT_SEL("%s: == checking cipher/digest ==\n", PK11_DBG);
-
-	SLOTID = pSlotList[0];
-	for (i = 0; i < ulSlotCount; i++)
-		{
-		DEBUG_SLOT_SEL("%s: checking slot: %d\n", PK11_DBG, i);
-
-		current_slot = pSlotList[i];
-		current_slot_n_cipher = 0;
-		current_slot_n_digest = 0;
-		(void) memset(local_cipher_nids, 0, sizeof (local_cipher_nids));
-		(void) memset(local_digest_nids, 0, sizeof (local_digest_nids));
-
-		pk11_find_symmetric_ciphers(pFuncList, current_slot,
-		    &current_slot_n_cipher, local_cipher_nids);
-
-		pk11_find_digests(pFuncList, current_slot,
-		    &current_slot_n_digest, local_digest_nids);
-
-		DEBUG_SLOT_SEL("%s: current_slot_n_cipher %d\n", PK11_DBG,
-			current_slot_n_cipher);
-		DEBUG_SLOT_SEL("%s: current_slot_n_digest %d\n", PK11_DBG,
-			current_slot_n_digest);
-		DEBUG_SLOT_SEL("%s: best cipher/digest slot so far: %d\n",
-			PK11_DBG, best_slot_sofar);
-
-		/*
-		 * If the current slot supports more ciphers/digests than
-		 * the previous best one we change the current best to this one,
-		 * otherwise leave it where it is.
-		 */
-		if ((current_slot_n_cipher + current_slot_n_digest) >
-		    (slot_n_cipher + slot_n_digest))
-			{
-			DEBUG_SLOT_SEL("%s: changing best slot to %d\n",
-				PK11_DBG, current_slot);
-			best_slot_sofar = SLOTID = current_slot;
-			cipher_count = slot_n_cipher = current_slot_n_cipher;
-			digest_count = slot_n_digest = current_slot_n_digest;
-			(void) memcpy(cipher_nids, local_cipher_nids,
-			    sizeof (local_cipher_nids));
-			(void) memcpy(digest_nids, local_digest_nids,
-			    sizeof (local_digest_nids));
-			}
-		}
-
-	DEBUG_SLOT_SEL("%s: chosen pubkey slot: %d\n", PK11_DBG, pubkey_SLOTID);
-	DEBUG_SLOT_SEL("%s: chosen rand slot: %d\n", PK11_DBG, rand_SLOTID);
-	DEBUG_SLOT_SEL("%s: chosen cipher/digest slot: %d\n", PK11_DBG, SLOTID);
-	DEBUG_SLOT_SEL("%s: pk11_have_rsa %d\n", PK11_DBG, pk11_have_rsa);
-	DEBUG_SLOT_SEL("%s: pk11_have_dsa %d\n", PK11_DBG, pk11_have_dsa);
-	DEBUG_SLOT_SEL("%s: pk11_have_dh %d\n", PK11_DBG, pk11_have_dh);
-	DEBUG_SLOT_SEL("%s: pk11_have_random %d\n", PK11_DBG, pk11_have_random);
-	DEBUG_SLOT_SEL("%s: cipher_count %d\n", PK11_DBG, cipher_count);
-	DEBUG_SLOT_SEL("%s: digest_count %d\n", PK11_DBG, digest_count);
-
-	if (pSlotList != NULL)
-		OPENSSL_free(pSlotList);
-
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-	OPENSSL_free(hw_cnids);
-	OPENSSL_free(hw_dnids);
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-
-	if (any_slot_found != NULL)
-		*any_slot_found = 1;
-	return (1);
-	}
-
-static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR pflist,
-    int slot_id, int *current_slot_n_cipher, int *local_cipher_nids,
-    PK11_CIPHER *cipher)
-	{
-	CK_MECHANISM_INFO mech_info;
-	CK_RV rv;
-
-	DEBUG_SLOT_SEL("%s: checking mech: %x", PK11_DBG, cipher->mech_type);
-	rv = pflist->C_GetMechanismInfo(slot_id, cipher->mech_type, &mech_info);
-
-	if (rv != CKR_OK)
-		{
-		DEBUG_SLOT_SEL(" not found\n");
-		return;
-		}
-
-	if ((mech_info.flags & CKF_ENCRYPT) &&
-	    (mech_info.flags & CKF_DECRYPT))
-		{
-		if (mech_info.ulMinKeySize > cipher->min_key_len ||
-		    mech_info.ulMaxKeySize < cipher->max_key_len)
-			{
-			DEBUG_SLOT_SEL(" engine key size range <%i-%i> does not"
-			    " match mech range <%lu-%lu>\n",
-			    cipher->min_key_len, cipher->max_key_len,
-			    mech_info.ulMinKeySize, mech_info.ulMaxKeySize);
-			return;
-			}
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-		if (nid_in_table(cipher->nid, hw_cnids))
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-			{
-			DEBUG_SLOT_SEL(" usable\n");
-			local_cipher_nids[(*current_slot_n_cipher)++] =
-			    cipher->nid;
-			}
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-		else
-			{
-			DEBUG_SLOT_SEL(
-			    " rejected, software implementation only\n");
-			}
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-		}
-	else
-		{
-		DEBUG_SLOT_SEL(" unusable\n");
-		}
-
-	return;
-	}
-
-static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
-    int *current_slot_n_digest, int *local_digest_nids, PK11_DIGEST *digest)
-	{
-	CK_MECHANISM_INFO mech_info;
-	CK_RV rv;
-
-	DEBUG_SLOT_SEL("%s: checking mech: %x", PK11_DBG, digest->mech_type);
-	rv = pflist->C_GetMechanismInfo(slot_id, digest->mech_type, &mech_info);
-
-	if (rv != CKR_OK)
-		{
-		DEBUG_SLOT_SEL(" not found\n");
-		return;
-		}
-
-	if (mech_info.flags & CKF_DIGEST)
-		{
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-		if (nid_in_table(digest->nid, hw_dnids))
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-			{
-			DEBUG_SLOT_SEL(" usable\n");
-			local_digest_nids[(*current_slot_n_digest)++] =
-			    digest->nid;
-			}
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-		else
-			{
-			DEBUG_SLOT_SEL(
-			    " rejected, software implementation only\n");
-			}
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-		}
-	else
-		{
-		DEBUG_SLOT_SEL(" unusable\n");
-		}
-
-	return;
-	}
-
-/* Find what symmetric ciphers this slot supports. */
-static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
-    CK_SLOT_ID current_slot, int *current_slot_n_cipher, int *local_cipher_nids)
-	{
-	int i;
-
-	for (i = 0; i < PK11_CIPHER_MAX; ++i)
-		{
-		pk11_get_symmetric_cipher(pflist, current_slot,
-		    current_slot_n_cipher, local_cipher_nids, &ciphers[i]);
-		}
-	}
-
-/* Find what digest algorithms this slot supports. */
-static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
-    CK_SLOT_ID current_slot, int *current_slot_n_digest, int *local_digest_nids)
-	{
-	int i;
-
-	for (i = 0; i < PK11_DIGEST_MAX; ++i)
-		{
-		pk11_get_digest(pflist, current_slot, current_slot_n_digest,
-		    local_digest_nids, &digests[i]);
-		}
-	}
-
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-/*
- * It would be great if we could use pkcs11_kernel directly since this library
- * offers hardware slots only. That's the easiest way to achieve the situation
- * where we use the hardware accelerators when present and OpenSSL native code
- * otherwise. That presumes the fact that OpenSSL native code is faster than the
- * code in the soft token. It's a logical assumption - Crypto Framework has some
- * inherent overhead so going there for the software implementation of a
- * mechanism should be logically slower in contrast to the OpenSSL native code,
- * presuming that both implementations are of similar speed. For example, the
- * soft token for AES is roughly three times slower than OpenSSL for 64 byte
- * blocks and still 20% slower for 8KB blocks. So, if we want to ship products
- * that use the PKCS#11 engine by default, we must somehow avoid that regression
- * on machines without hardware acceleration. That's why switching to the
- * pkcs11_kernel library seems like a very good idea.
- *
- * The problem is that OpenSSL built with SunStudio is roughly 2x slower for
- * asymmetric operations (RSA/DSA/DH) than the soft token built with the same
- * compiler. That means that if we switched to pkcs11_kernel from the libpkcs11
- * library, we would have had a performance regression on machines without
- * hardware acceleration for asymmetric operations for all applications that use
- * the PKCS#11 engine. There is one such application - Apache web server since
- * it's shipped configured to use the PKCS#11 engine by default. Having said
- * that, we can't switch to the pkcs11_kernel library now and have to come with
- * a solution that, on non-accelerated machines, uses the OpenSSL native code
- * for all symmetric ciphers and digests while it uses the soft token for
- * asymmetric operations.
- *
- * This is the idea: dlopen() pkcs11_kernel directly and find out what
- * mechanisms are there. We don't care about duplications (more slots can
- * support the same mechanism), we just want to know what mechanisms can be
- * possibly supported in hardware on that particular machine. As said before,
- * pkcs11_kernel will show you hardware providers only.
- *
- * Then, we rely on the fact that since we use libpkcs11 library we will find
- * the metaslot. When we go through the metaslot's mechanisms for symmetric
- * ciphers and digests, we check that any found mechanism is in the table
- * created using the pkcs11_kernel library. So, as a result we have two arrays
- * of mechanisms that were advertised as supported in hardware which was the
- * goal of that whole exercise. Thus, we can use libpkcs11 but avoid soft token
- * code for symmetric ciphers and digests. See pk11_choose_slots() for more
- * information.
- *
- * This is Solaris specific code, if SOLARIS_HW_SLOT_SELECTION is not defined
- * the code won't be used.
- */
-#if defined(__sparcv9) || defined(__x86_64) || defined(__amd64)
-static const char pkcs11_kernel[] = "/usr/lib/security/64/pkcs11_kernel.so.1";
-#else
-static const char pkcs11_kernel[] = "/usr/lib/security/pkcs11_kernel.so.1";
-#endif
-
-/*
- * Check hardware capabilities of the machines. The output are two lists,
- * hw_cnids and hw_dnids, that contain hardware mechanisms found in all hardware
- * providers together. They are not sorted and may contain duplicate mechanisms.
- */
-static int check_hw_mechanisms(void)
-	{
-	int i;
-	CK_RV rv;
-	void *handle;
-	CK_C_GetFunctionList p;
-	CK_TOKEN_INFO token_info;
-	CK_ULONG ulSlotCount = 0;
-	int n_cipher = 0, n_digest = 0;
-	CK_FUNCTION_LIST_PTR pflist = NULL;
-	CK_SLOT_ID_PTR pSlotList = NULL_PTR;
-	int *tmp_hw_cnids = NULL, *tmp_hw_dnids = NULL;
-	int hw_ctable_size, hw_dtable_size;
-
-	DEBUG_SLOT_SEL("%s: SOLARIS_HW_SLOT_SELECTION code running\n",
-	    PK11_DBG);
-	/*
-	 * Use RTLD_GROUP to limit the pkcs11_kernel provider to its own
-	 * symbols, which prevents it from mistakenly accessing C_* functions
-	 * from the top-level PKCS#11 library.
-	 */
-	if ((handle = dlopen(pkcs11_kernel, RTLD_LAZY | RTLD_GROUP)) == NULL)
-		{
-		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
-		goto err;
-		}
-
-	if ((p = (CK_C_GetFunctionList)dlsym(handle,
-	    PK11_GET_FUNCTION_LIST)) == NULL)
-		{
-		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
-		goto err;
-		}
-
-	/* get the full function list from the loaded library */
-	if (p(&pflist) != CKR_OK)
-		{
-		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
-		goto err;
-		}
-
-	rv = pflist->C_Initialize(NULL_PTR);
-	if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
-		{
-		PK11err_add_data(PK11_F_CHECK_HW_MECHANISMS,
-		    PK11_R_INITIALIZE, rv);
-		goto err;
-		}
-
-	if (pflist->C_GetSlotList(0, NULL_PTR, &ulSlotCount) != CKR_OK)
-		{
-		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_GETSLOTLIST);
-		goto err;
-		}
-
-	/* no slots, set the hw mechanism tables as empty */
-	if (ulSlotCount == 0)
-		{
-		DEBUG_SLOT_SEL("%s: no hardware mechanisms found\n", PK11_DBG);
-		hw_cnids = OPENSSL_malloc(sizeof (int));
-		hw_dnids = OPENSSL_malloc(sizeof (int));
-		if (hw_cnids == NULL || hw_dnids == NULL)
-			{
-			PK11err(PK11_F_CHECK_HW_MECHANISMS,
-			    PK11_R_MALLOC_FAILURE);
-			return (0);
-			}
-		/* this means empty tables */
-		hw_cnids[0] = NID_undef;
-		hw_dnids[0] = NID_undef;
-		return (1);
-		}
-
-	pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
-	if (pSlotList == NULL)
-		{
-		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_MALLOC_FAILURE);
-		goto err;
-		}
-
-	/* Get the slot list for processing */
-	if (pflist->C_GetSlotList(0, pSlotList, &ulSlotCount) != CKR_OK)
-		{
-		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_GETSLOTLIST);
-		goto err;
-		}
-
-	/*
-	 * We don't care about duplicate mechanisms in multiple slots and also
-	 * reserve one slot for the terminal NID_undef which we use to stop the
-	 * search.
-	 */
-	hw_ctable_size = ulSlotCount * PK11_CIPHER_MAX + 1;
-	hw_dtable_size = ulSlotCount * PK11_DIGEST_MAX + 1;
-	tmp_hw_cnids = OPENSSL_malloc(hw_ctable_size * sizeof (int));
-	tmp_hw_dnids = OPENSSL_malloc(hw_dtable_size * sizeof (int));
-	if (tmp_hw_cnids == NULL || tmp_hw_dnids == NULL)
-		{
-		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_MALLOC_FAILURE);
-		goto err;
-		}
-
-	/*
-	 * Do not use memset since we should not rely on the fact that NID_undef
-	 * is zero now.
-	 */
-	for (i = 0; i < hw_ctable_size; ++i)
-		tmp_hw_cnids[i] = NID_undef;
-	for (i = 0; i < hw_dtable_size; ++i)
-		tmp_hw_dnids[i] = NID_undef;
-
-	DEBUG_SLOT_SEL("%s: provider: %s\n", PK11_DBG, pkcs11_kernel);
-	DEBUG_SLOT_SEL("%s: found %d hardware slots\n", PK11_DBG, ulSlotCount);
-	DEBUG_SLOT_SEL("%s: now looking for mechs supported in hw\n",
-	    PK11_DBG);
-
-	for (i = 0; i < ulSlotCount; i++)
-		{
-		if (pflist->C_GetTokenInfo(pSlotList[i], &token_info) != CKR_OK)
-			continue;
-
-		DEBUG_SLOT_SEL("%s: token label: %.32s\n", PK11_DBG,
-		    token_info.label);
-
-		/*
-		 * We are filling the hw mech tables here. Global tables are
-		 * still NULL so all mechanisms are put into tmp tables.
-		 */
-		pk11_find_symmetric_ciphers(pflist, pSlotList[i],
-		    &n_cipher, tmp_hw_cnids);
-		pk11_find_digests(pflist, pSlotList[i],
-		    &n_digest, tmp_hw_dnids);
-		}
-
-	/*
-	 * Since we are part of a library (libcrypto.so), calling this function
-	 * may have side-effects. Also, C_Finalize() is triggered by
-	 * dlclose(3C).
-	 */
-#if 0
-	pflist->C_Finalize(NULL);
-#endif
-	OPENSSL_free(pSlotList);
-	(void) dlclose(handle);
-	hw_cnids = tmp_hw_cnids;
-	hw_dnids = tmp_hw_dnids;
-
-	DEBUG_SLOT_SEL("%s: hw mechs check complete\n", PK11_DBG);
-	return (1);
-
-err:
-	if (pSlotList != NULL)
-		OPENSSL_free(pSlotList);
-	if (tmp_hw_cnids != NULL)
-		OPENSSL_free(tmp_hw_cnids);
-	if (tmp_hw_dnids != NULL)
-		OPENSSL_free(tmp_hw_dnids);
-
-	return (0);
-	}
-
-/*
- * Check presence of a NID in the table of NIDs unless the mechanism is
- * supported directly in a CPU instruction set. The table may be NULL (i.e.,
- */
-static int nid_in_table(int nid, int *nid_table)
-	{
-	int i = 0;
-
-	/*
-	 * Special case first. NULL means that we are initializing a new table.
-	 */
-	if (nid_table == NULL)
-		return (1);
-
-	/*
-	 * the table is never full, there is always at least one
-	 * NID_undef.
-	 */
-	while (nid_table[i] != NID_undef)
-		{
-		if (nid_table[i++] == nid)
-			{
-			DEBUG_SLOT_SEL(" (NID %d in hw table, idx %d)", nid, i);
-			return (1);
-			}
-		}
-
-	return (0);
-	}
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-
-#endif	/* OPENSSL_NO_HW_PK11 */
-#endif	/* OPENSSL_NO_HW */
--- a/components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11.h	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,259 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- *
- */
-
-/* crypto/engine/e_pk11.h */
-/*
- * This product includes software developed by the OpenSSL Project for
- * use in the OpenSSL Toolkit (http://www.openssl.org/).
- *
- * This project also referenced hw_pkcs11-0.9.7b.patch written by
- * Afchine Madjlessi.
- */
-/*
- * ====================================================================
- * 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
- *    [email protected].
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * ([email protected]).  This product includes software written by Tim
- * Hudson ([email protected]).
- *
- */
-
-#ifndef	E_PK11_H
-#define	E_PK11_H
-
-#include "e_pk11_err.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-/* max byte length of a symmetric key we support */
-#define	PK11_KEY_LEN_MAX			32
-
-/*
- * This structure encapsulates all reusable information for a PKCS#11
- * session. A list of these objects is created on behalf of the
- * calling application using an on-demand method. Each operation
- * type (see PK11_OPTYPE below) has its own per-process list.
- * Each of the lists is basically a cache for faster PKCS#11 object
- * access to avoid expensive C_Find{,Init,Final}Object() calls.
- *
- * When a new request comes in, an object will be taken from the list
- * (if there is one) or a new one is created to handle the request
- * (if the list is empty). See pk11_get_session() on how it is done.
- */
-typedef struct PK11_st_SESSION
-	{
-	struct PK11_st_SESSION	*next;
-	CK_SESSION_HANDLE	session;	/* PK11 session handle */
-	pid_t			pid;		/* Current process ID */
-	CK_BBOOL		persistent;	/* is that a keystore object? */
-	union
-		{
-#ifndef OPENSSL_NO_RSA
-		struct
-			{
-			CK_OBJECT_HANDLE	rsa_pub_key; /* pub handle */
-			CK_OBJECT_HANDLE	rsa_priv_key; /* priv handle */
-			RSA			*rsa_pub; /* pub key addr */
-			BIGNUM			*rsa_n_num; /* pub modulus */
-			BIGNUM			*rsa_e_num; /* pub exponent */
-			RSA			*rsa_priv; /* priv key addr */
-			BIGNUM			*rsa_d_num; /* priv exponent */
-			} u_RSA;
-#endif /* OPENSSL_NO_RSA */
-#ifndef OPENSSL_NO_DSA
-		struct
-			{
-			CK_OBJECT_HANDLE	dsa_pub_key; /* pub handle */
-			CK_OBJECT_HANDLE	dsa_priv_key; /* priv handle */
-			DSA			*dsa_pub; /* pub key addr */
-			BIGNUM			*dsa_pub_num; /* pub key */
-			DSA			*dsa_priv; /* priv key addr */
-			BIGNUM			*dsa_priv_num; /* priv key */
-			} u_DSA;
-#endif /* OPENSSL_NO_DSA */
-#ifndef OPENSSL_NO_DH
-		struct
-			{
-			CK_OBJECT_HANDLE	dh_key; /* key handle */
-			DH			*dh; /* dh key addr */
-			BIGNUM			*dh_priv_num; /* priv dh key */
-			} u_DH;
-#endif /* OPENSSL_NO_DH */
-		struct
-			{
-			CK_OBJECT_HANDLE	cipher_key; /* key handle */
-			unsigned char		key[PK11_KEY_LEN_MAX];
-			int			key_len; /* priv key len */
-			int			encrypt; /* 1/0 enc/decr */
-			} u_cipher;
-		} opdata_u;
-	} PK11_SESSION;
-
-#define	opdata_rsa_pub_key	opdata_u.u_RSA.rsa_pub_key
-#define	opdata_rsa_priv_key	opdata_u.u_RSA.rsa_priv_key
-#define	opdata_rsa_pub		opdata_u.u_RSA.rsa_pub
-#define	opdata_rsa_priv		opdata_u.u_RSA.rsa_priv
-#define	opdata_rsa_n_num	opdata_u.u_RSA.rsa_n_num
-#define	opdata_rsa_e_num	opdata_u.u_RSA.rsa_e_num
-#define	opdata_rsa_d_num	opdata_u.u_RSA.rsa_d_num
-#define	opdata_dsa_pub_key	opdata_u.u_DSA.dsa_pub_key
-#define	opdata_dsa_priv_key	opdata_u.u_DSA.dsa_priv_key
-#define	opdata_dsa_pub		opdata_u.u_DSA.dsa_pub
-#define	opdata_dsa_pub_num	opdata_u.u_DSA.dsa_pub_num
-#define	opdata_dsa_priv		opdata_u.u_DSA.dsa_priv
-#define	opdata_dsa_priv_num	opdata_u.u_DSA.dsa_priv_num
-#define	opdata_dh_key		opdata_u.u_DH.dh_key
-#define	opdata_dh		opdata_u.u_DH.dh
-#define	opdata_dh_priv_num	opdata_u.u_DH.dh_priv_num
-#define	opdata_cipher_key	opdata_u.u_cipher.cipher_key
-#define	opdata_key		opdata_u.u_cipher.key
-#define	opdata_key_len		opdata_u.u_cipher.key_len
-#define	opdata_encrypt		opdata_u.u_cipher.encrypt
-
-/*
- * We have 3 different groups of operation types:
- *   1) asymmetric operations
- *   2) random operations
- *   3) symmetric and digest operations
- *
- * This division into groups stems from the fact that it's common that hardware
- * providers may support operations from one group only. For example, hardware
- * providers on UltraSPARC T2, n2rng(7d), ncp(7d), and n2cp(7d), each support
- * only a single group of operations.
- *
- * For every group a different slot can be chosen. That means that we must have
- * at least 3 different lists of cached PKCS#11 sessions since sessions from
- * different groups may be initialized in different slots.
- *
- * To provide locking granularity in multithreaded environment, the groups are
- * further split into types with each type having a separate session cache.
- */
-typedef enum PK11_OPTYPE_ENUM
-	{
-	OP_RAND,
-	OP_RSA,
-	OP_DSA,
-	OP_DH,
-	OP_CIPHER,
-	OP_DIGEST,
-	OP_MAX
-	} PK11_OPTYPE;
-
-/*
- * This structure contains the heads of the lists forming the object caches
- * and locks associated with the lists.
- */
-typedef struct PK11_st_CACHE
-	{
-	PK11_SESSION *head;
-	pthread_mutex_t *lock;
-	} PK11_CACHE;
-
-/* structure for tracking handles of asymmetric key objects */
-typedef struct PK11_active_st
-	{
-	CK_OBJECT_HANDLE h;
-	unsigned int refcnt;
-	struct PK11_active_st *prev;
-	struct PK11_active_st *next;
-	} PK11_active;
-
-extern pthread_mutex_t *find_lock[];
-extern PK11_active *active_list[];
-/*
- * These variables are specific for the RSA keys by reference code. See
- * e_pk11_pub.c for explanation.
- */
-extern char *passphrasedialog;
-extern CK_FLAGS pubkey_token_flags;
-
-#define	LOCK_OBJSTORE(alg_type)	\
-	(void) pthread_mutex_lock(find_lock[alg_type])
-#define	UNLOCK_OBJSTORE(alg_type)	\
-	(void) pthread_mutex_unlock(find_lock[alg_type])
-
-extern PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
-extern void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
-
-#ifndef OPENSSL_NO_RSA
-extern int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
-extern int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
-extern int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
-extern EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *pubkey_file,
-	UI_METHOD *ui_method, void *callback_data);
-extern EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
-	UI_METHOD *ui_method, void *callback_data);
-extern RSA_METHOD *PK11_RSA(void);
-#endif /* OPENSSL_NO_RSA */
-#ifndef OPENSSL_NO_DSA
-extern int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
-extern int pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
-extern int pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
-extern DSA_METHOD *PK11_DSA(void);
-#endif /* OPENSSL_NO_DSA */
-#ifndef OPENSSL_NO_DH
-extern int pk11_destroy_dh_key_objects(PK11_SESSION *session);
-extern int pk11_destroy_dh_object(PK11_SESSION *sp, CK_BBOOL uselock);
-extern DH_METHOD *PK11_DH(void);
-#endif /* OPENSSL_NO_DH */
-
-extern int pk11_engine_pkey_methods(ENGINE *e, EVP_PKEY_METHOD **pmeth,
-    const int **nids, int nid);
-
-extern CK_FUNCTION_LIST_PTR pFuncList;
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif /* E_PK11_H */
--- a/components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_err.c	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,307 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- *
- */
-
-/* crypto/engine/e_pk11_err.c */
-/*
- * This product includes software developed by the OpenSSL Project for
- * use in the OpenSSL Toolkit (http://www.openssl.org/).
- *
- * This project also referenced hw_pkcs11-0.9.7b.patch written by
- * Afchine Madjlessi.
- */
-/*
- * ====================================================================
- * 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
- *    [email protected].
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * ([email protected]).  This product includes software written by Tim
- * Hudson ([email protected]).
- *
- */
-
-#include <stdio.h>
-#include <openssl/err.h>
-#include "e_pk11_err.h"
-
-/* BEGIN ERROR CODES */
-#ifndef OPENSSL_NO_ERR
-static ERR_STRING_DATA pk11_str_functs[]=
-{
-{ ERR_PACK(0, PK11_F_INIT, 0),			"PK11_INIT"},
-{ ERR_PACK(0, PK11_F_FINISH, 0),		"PK11_FINISH"},
-{ ERR_PACK(0, PK11_F_DESTROY, 0),		"PK11_DESTROY"},
-{ ERR_PACK(0, PK11_F_CTRL, 0),			"PK11_CTRL"},
-{ ERR_PACK(0, PK11_F_RSA_INIT, 0),		"PK11_RSA_INIT"},
-{ ERR_PACK(0, PK11_F_RSA_FINISH, 0),		"PK11_RSA_FINISH"},
-{ ERR_PACK(0, PK11_F_GET_PUB_RSA_KEY, 0),	"PK11_GET_PUB_RSA_KEY"},
-{ ERR_PACK(0, PK11_F_GET_PRIV_RSA_KEY, 0),	"PK11_GET_PRIV_RSA_KEY"},
-{ ERR_PACK(0, PK11_F_RSA_GEN_KEY, 0),		"PK11_RSA_GEN_KEY"},
-{ ERR_PACK(0, PK11_F_RSA_PUB_ENC, 0),		"PK11_RSA_PUB_ENC"},
-{ ERR_PACK(0, PK11_F_RSA_PRIV_ENC, 0),		"PK11_RSA_PRIV_ENC"},
-{ ERR_PACK(0, PK11_F_RSA_PUB_DEC, 0),		"PK11_RSA_PUB_DEC"},
-{ ERR_PACK(0, PK11_F_RSA_PRIV_DEC, 0),		"PK11_RSA_PRIV_DEC"},
-{ ERR_PACK(0, PK11_F_RSA_SIGN, 0),		"PK11_RSA_SIGN"},
-{ ERR_PACK(0, PK11_F_RSA_VERIFY, 0),		"PK11_RSA_VERIFY"},
-{ ERR_PACK(0, PK11_F_RAND_ADD, 0),		"PK11_RAND_ADD"},
-{ ERR_PACK(0, PK11_F_RAND_BYTES, 0),		"PK11_RAND_BYTES"},
-{ ERR_PACK(0, PK11_F_GET_SESSION, 0),		"PK11_GET_SESSION"},
-{ ERR_PACK(0, PK11_F_FREE_SESSION, 0),		"PK11_FREE_SESSION"},
-{ ERR_PACK(0, PK11_F_LOAD_PUBKEY, 0),		"PK11_LOAD_PUBKEY"},
-{ ERR_PACK(0, PK11_F_LOAD_PRIVKEY, 0),		"PK11_LOAD_PRIV_KEY"},
-{ ERR_PACK(0, PK11_F_RSA_PUB_ENC_LOW, 0),	"PK11_RSA_PUB_ENC_LOW"},
-{ ERR_PACK(0, PK11_F_RSA_PRIV_ENC_LOW, 0),	"PK11_RSA_PRIV_ENC_LOW"},
-{ ERR_PACK(0, PK11_F_RSA_PUB_DEC_LOW, 0),	"PK11_RSA_PUB_DEC_LOW"},
-{ ERR_PACK(0, PK11_F_RSA_PRIV_DEC_LOW, 0),	"PK11_RSA_PRIV_DEC_LOW"},
-{ ERR_PACK(0, PK11_F_DSA_SIGN, 0),		"PK11_DSA_SIGN"},
-{ ERR_PACK(0, PK11_F_DSA_VERIFY, 0),		"PK11_DSA_VERIFY"},
-{ ERR_PACK(0, PK11_F_DSA_INIT, 0),		"PK11_DSA_INIT"},
-{ ERR_PACK(0, PK11_F_DSA_FINISH, 0),		"PK11_DSA_FINISH"},
-{ ERR_PACK(0, PK11_F_GET_PUB_DSA_KEY, 0),	"PK11_GET_PUB_DSA_KEY"},
-{ ERR_PACK(0, PK11_F_GET_PRIV_DSA_KEY, 0),	"PK11_GET_PRIV_DSA_KEY"},
-{ ERR_PACK(0, PK11_F_DH_INIT, 0),		"PK11_DH_INIT"},
-{ ERR_PACK(0, PK11_F_DH_FINISH, 0),		"PK11_DH_FINISH"},
-{ ERR_PACK(0, PK11_F_MOD_EXP_DH, 0),		"PK11_MOD_EXP_DH"},
-{ ERR_PACK(0, PK11_F_GET_DH_KEY, 0),		"PK11_GET_DH_KEY"},
-{ ERR_PACK(0, PK11_F_FREE_ALL_SESSIONS, 0),	"PK11_FREE_ALL_SESSIONS"},
-{ ERR_PACK(0, PK11_F_SETUP_SESSION, 0),		"PK11_SETUP_SESSION"},
-{ ERR_PACK(0, PK11_F_DESTROY_OBJECT, 0),	"PK11_DESTROY_OBJECT"},
-{ ERR_PACK(0, PK11_F_CIPHER_INIT, 0),		"PK11_CIPHER_INIT"},
-{ ERR_PACK(0, PK11_F_CIPHER_DO_CIPHER, 0),	"PK11_CIPHER_DO_CIPHER"},
-{ ERR_PACK(0, PK11_F_GET_CIPHER_KEY, 0),	"PK11_GET_CIPHER_KEY"},
-{ ERR_PACK(0, PK11_F_DIGEST_INIT, 0),		"PK11_DIGEST_INIT"},
-{ ERR_PACK(0, PK11_F_DIGEST_UPDATE, 0),		"PK11_DIGEST_UPDATE"},
-{ ERR_PACK(0, PK11_F_DIGEST_FINAL, 0),		"PK11_DIGEST_FINAL"},
-{ ERR_PACK(0, PK11_F_CHOOSE_SLOT, 0),		"PK11_CHOOSE_SLOT"},
-{ ERR_PACK(0, PK11_F_CIPHER_FINAL, 0),		"PK11_CIPHER_FINAL"},
-{ ERR_PACK(0, PK11_F_LIBRARY_INIT, 0),		"PK11_LIBRARY_INIT"},
-{ ERR_PACK(0, PK11_F_LOAD, 0),			"ENGINE_LOAD_PK11"},
-{ ERR_PACK(0, PK11_F_DH_GEN_KEY, 0),		"PK11_DH_GEN_KEY"},
-{ ERR_PACK(0, PK11_F_DH_COMP_KEY, 0),		"PK11_DH_COMP_KEY"},
-{ ERR_PACK(0, PK11_F_DIGEST_COPY, 0),		"PK11_DIGEST_COPY"},
-{ ERR_PACK(0, PK11_F_CIPHER_CLEANUP, 0),	"PK11_CIPHER_CLEANUP"},
-{ ERR_PACK(0, PK11_F_ACTIVE_ADD, 0),		"PK11_ACTIVE_ADD"},
-{ ERR_PACK(0, PK11_F_ACTIVE_DELETE, 0),		"PK11_ACTIVE_DELETE"},
-{ ERR_PACK(0, PK11_F_CHECK_HW_MECHANISMS, 0),	"PK11_CHECK_HW_MECHANISMS"},
-{ ERR_PACK(0, PK11_F_INIT_SYMMETRIC, 0),	"PK11_INIT_SYMMETRIC"},
-{ ERR_PACK(0, PK11_F_ADD_AES_CTR_NIDS, 0),	"PK11_ADD_AES_CTR_NIDS"},
-{ ERR_PACK(0, PK11_F_INIT_ALL_LOCKS, 0),	"PK11_INIT_ALL_LOCKS"},
-{ ERR_PACK(0, PK11_F_RETURN_SESSION, 0),	"PK11_RETURN_SESSION"},
-{ ERR_PACK(0, PK11_F_GET_PIN, 0),		"PK11_GET_PIN"},
-{ ERR_PACK(0, PK11_F_FIND_ONE_OBJECT, 0),	"PK11_FIND_ONE_OBJECT"},
-{ ERR_PACK(0, PK11_F_CHECK_TOKEN_ATTRS, 0),	"PK11_CHECK_TOKEN_ATTRS"},
-{ ERR_PACK(0, PK11_F_CACHE_PIN, 0),		"PK11_CACHE_PIN"},
-{ ERR_PACK(0, PK11_F_MLOCK_PIN_IN_MEMORY, 0),	"PK11_MLOCK_PIN_IN_MEMORY"},
-{ ERR_PACK(0, PK11_F_TOKEN_LOGIN, 0),		"PK11_TOKEN_LOGIN"},
-{ ERR_PACK(0, PK11_F_TOKEN_RELOGIN, 0),		"PK11_TOKEN_RELOGIN"},
-{ ERR_PACK(0, PK11_F_RUN_ASKPASS, 0),		"PK11_F_RUN_ASKPASS"},
-{ 0, NULL}
-};
-
-static ERR_STRING_DATA pk11_str_reasons[]=
-{
-{ PK11_R_ALREADY_LOADED,		"PKCS#11 DSO already loaded"},
-{ PK11_R_DSO_FAILURE,			"unable to load PKCS#11 DSO"},
-{ PK11_R_NOT_LOADED,			"PKCS#11 DSO not loaded"},
-{ PK11_R_PASSED_NULL_PARAMETER,		"null parameter passed"},
-{ PK11_R_COMMAND_NOT_IMPLEMENTED,	"command not implemented"},
-{ PK11_R_INITIALIZE,			"C_Initialize failed"},
-{ PK11_R_FINALIZE,			"C_Finalize failed"},
-{ PK11_R_GETINFO,			"C_GetInfo faile"},
-{ PK11_R_GETSLOTLIST,			"C_GetSlotList failed"},
-{ PK11_R_NO_MODULUS_OR_NO_EXPONENT,	"no modulus or no exponent"},
-{ PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID,	"attr sensitive or invalid"},
-{ PK11_R_GETATTRIBUTVALUE,		"C_GetAttributeValue failed"},
-{ PK11_R_NO_MODULUS,			"no modulus"},
-{ PK11_R_NO_EXPONENT,			"no exponent"},
-{ PK11_R_FINDOBJECTSINIT,		"C_FindObjectsInit failed"},
-{ PK11_R_FINDOBJECTS,			"C_FindObjects failed"},
-{ PK11_R_FINDOBJECTSFINAL,		"C_FindObjectsFinal failed"},
-{ PK11_R_CREATEOBJECT,			"C_CreateObject failed"},
-{ PK11_R_DESTROYOBJECT,			"C_DestroyObject failed"},
-{ PK11_R_OPENSESSION,			"C_OpenSession failed"},
-{ PK11_R_CLOSESESSION,			"C_CloseSession failed"},
-{ PK11_R_ENCRYPTINIT,			"C_EncryptInit failed"},
-{ PK11_R_ENCRYPT,			"C_Encrypt failed"},
-{ PK11_R_SIGNINIT,			"C_SignInit failed"},
-{ PK11_R_SIGN,				"C_Sign failed"},
-{ PK11_R_DECRYPTINIT,			"C_DecryptInit failed"},
-{ PK11_R_DECRYPT,			"C_Decrypt failed"},
-{ PK11_R_VERIFYINIT,			"C_VerifyRecover failed"},
-{ PK11_R_VERIFY,			"C_Verify failed"},
-{ PK11_R_VERIFYRECOVERINIT,		"C_VerifyRecoverInit failed"},
-{ PK11_R_VERIFYRECOVER,			"C_VerifyRecover failed"},
-{ PK11_R_GEN_KEY,			"C_GenerateKeyPair failed"},
-{ PK11_R_SEEDRANDOM,			"C_SeedRandom failed"},
-{ PK11_R_GENERATERANDOM,		"C_GenerateRandom failed"},
-{ PK11_R_INVALID_MESSAGE_LENGTH,	"invalid message length"},
-{ PK11_R_UNKNOWN_ALGORITHM_TYPE,	"unknown algorithm type"},
-{ PK11_R_UNKNOWN_ASN1_OBJECT_ID,	"unknown asn1 onject id"},
-{ PK11_R_UNKNOWN_PADDING_TYPE,		"unknown padding type"},
-{ PK11_R_PADDING_CHECK_FAILED,		"padding check failed"},
-{ PK11_R_DIGEST_TOO_BIG,		"digest too big"},
-{ PK11_R_MALLOC_FAILURE,		"malloc failure"},
-{ PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED,	"ctl command not implemented"},
-{ PK11_R_DATA_GREATER_THAN_MOD_LEN,	"data is bigger than mod"},
-{ PK11_R_DATA_TOO_LARGE_FOR_MODULUS,	"data is too larger for mod"},
-{ PK11_R_MISSING_KEY_COMPONENT,		"a dsa component is missing"},
-{ PK11_R_INVALID_SIGNATURE_LENGTH,	"invalid signature length"},
-{ PK11_R_INVALID_DSA_SIGNATURE_R,	"missing r in dsa verify"},
-{ PK11_R_INVALID_DSA_SIGNATURE_S,	"missing s in dsa verify"},
-{ PK11_R_INCONSISTENT_KEY,		"inconsistent key type"},
-{ PK11_R_ENCRYPTUPDATE,			"C_EncryptUpdate failed"},
-{ PK11_R_DECRYPTUPDATE,			"C_DecryptUpdate failed"},
-{ PK11_R_DIGESTINIT,			"C_DigestInit failed"},
-{ PK11_R_DIGESTUPDATE,			"C_DigestUpdate failed"},
-{ PK11_R_DIGESTFINAL,			"C_DigestFinal failed"},
-{ PK11_R_ENCRYPTFINAL,			"C_EncryptFinal failed"},
-{ PK11_R_DECRYPTFINAL,			"C_DecryptFinal failed"},
-{ PK11_R_NO_PRNG_SUPPORT,		"Slot does not support PRNG"},
-{ PK11_R_GETTOKENINFO,			"C_GetTokenInfo failed"},
-{ PK11_R_DERIVEKEY,			"C_DeriveKey failed"},
-{ PK11_R_GET_OPERATION_STATE,		"C_GetOperationState failed"},
-{ PK11_R_SET_OPERATION_STATE,		"C_SetOperationState failed"},
-{ PK11_R_INVALID_HANDLE,		"invalid PKCS#11 object handle"},
-{ PK11_R_KEY_OR_IV_LEN_PROBLEM,		"IV or key length incorrect"},
-{ PK11_R_INVALID_OPERATION_TYPE,	"invalid operation type"},
-{ PK11_R_ADD_NID_FAILED,		"failed to add NID" },
-{ PK11_R_ATFORK_FAILED,			"atfork failed" },
-{ PK11_R_TOKEN_LOGIN_FAILED,		"C_Login failed on token" },
-{ PK11_R_MORE_THAN_ONE_OBJECT_FOUND,	"more than one object found" },
-{ PK11_R_INVALID_PKCS11_URI,		"pkcs11 URI provided is invalid" },
-{ PK11_R_COULD_NOT_READ_PIN,		"could not read PIN from terminal" },
-{ PK11_R_PIN_NOT_READ_FROM_COMMAND,	"PIN not read from external command" },
-{ PK11_R_COULD_NOT_OPEN_COMMAND,	"could not popen dialog command" },
-{ PK11_R_PIPE_FAILED,			"pipe failed" },
-{ PK11_R_BAD_PASSPHRASE_SPEC,		"bad passphrasedialog specification" },
-{ PK11_R_TOKEN_NOT_INITIALIZED,		"token not initialized" },
-{ PK11_R_TOKEN_PIN_NOT_SET,		"token PIN required but not set" },
-{ PK11_R_TOKEN_PIN_NOT_PROVIDED,	"token PIN required but not provided" },
-{ PK11_R_MISSING_OBJECT_LABEL,		"missing mandatory 'object' keyword" },
-{ PK11_R_TOKEN_ATTRS_DO_NOT_MATCH,	"token attrs provided do not match" },
-{ PK11_R_PRIV_KEY_NOT_FOUND,		"private key not found in keystore" },
-{ PK11_R_NO_OBJECT_FOUND,		"specified object not found" },
-{ PK11_R_PIN_CACHING_POLICY_INVALID,	"PIN set but caching policy invalid" },
-{ PK11_R_SYSCONF_FAILED,		"sysconf failed" },
-{ PK11_R_MMAP_FAILED,			"mmap failed" },
-{ PK11_R_PRIV_PROC_LOCK_MEMORY_MISSING,	"PROC_LOCK_MEMORY privilege missing" },
-{ PK11_R_MLOCK_FAILED,			"mlock failed" },
-{ PK11_R_FORK_FAILED,			"fork failed" },
-{ 0,	NULL}
-};
-#endif	/* OPENSSL_NO_ERR */
-
-static int pk11_lib_error_code = 0;
-static int pk11_error_init = 1;
-
-#ifdef PK11_ENGINE_LIB_NAME
-static ERR_STRING_DATA pk11_engine_lib_name[] =
-{
-{0, PK11_ENGINE_LIB_NAME},
-{0, NULL}
-};
-#endif
-
-static void
-ERR_load_pk11_strings(void)
-	{
-	if (pk11_lib_error_code == 0)
-		pk11_lib_error_code = ERR_get_next_error_library();
-
-	if (pk11_error_init)
-		{
-		pk11_error_init = 0;
-#ifndef OPENSSL_NO_ERR
-		ERR_load_strings(pk11_lib_error_code, pk11_str_functs);
-		ERR_load_strings(pk11_lib_error_code, pk11_str_reasons);
-#endif
-
-#ifdef PK11_ENGINE_LIB_NAME
-		pk11_engine_lib_name->error =
-		    ERR_PACK(pk11_lib_error_code, 0, 0);
-		ERR_load_strings(0, pk11_engine_lib_name);
-#endif
-		}
-}
-
-static void
-ERR_unload_pk11_strings(void)
-	{
-	if (pk11_error_init == 0)
-		{
-#ifndef OPENSSL_NO_ERR
-		ERR_unload_strings(pk11_lib_error_code, pk11_str_functs);
-		ERR_unload_strings(pk11_lib_error_code, pk11_str_reasons);
-#endif
-
-#ifdef PK11_ENGINE_LIB_NAME
-		ERR_unload_strings(0, pk11_engine_lib_name);
-#endif
-
-		pk11_error_init = 1;
-		}
-}
-
-void
-ERR_pk11_error(int function, int reason, char *file, int line)
-{
-	if (pk11_lib_error_code == 0)
-		pk11_lib_error_code = ERR_get_next_error_library();
-	ERR_PUT_error(pk11_lib_error_code, function, reason, file, line);
-}
-
-void
-PK11err_add_data(int function, int reason, CK_RV rv)
-{
-	char tmp_buf[20];
-
-	PK11err(function, reason);
-	(void) snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-	ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-}
--- a/components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_err.h	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,236 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- *
- */
-
-/*
- * This product includes software developed by the OpenSSL Project for
- * use in the OpenSSL Toolkit (http://www.openssl.org/).
- *
- * This project also referenced hw_pkcs11-0.9.7b.patch written by
- * Afchine Madjlessi.
- */
-/*
- * ====================================================================
- * 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
- *    [email protected].
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * ([email protected]).  This product includes software written by Tim
- * Hudson ([email protected]).
- *
- */
-
-#ifndef	E_PK11_ERR_H
-#define	E_PK11_ERR_H
-
-void ERR_pk11_error(int function, int reason, char *file, int line);
-void PK11err_add_data(int function, int reason, CK_RV rv);
-#define	PK11err(f, r)	ERR_pk11_error((f), (r), __FILE__, __LINE__)
-
-/* Error codes for the PK11 functions. */
-
-/* Function codes. */
-
-#define	PK11_F_INIT 				100
-#define	PK11_F_FINISH				101
-#define	PK11_F_DESTROY 				102
-#define	PK11_F_CTRL 				103
-#define	PK11_F_RSA_INIT 			104
-#define	PK11_F_RSA_FINISH 			105
-#define	PK11_F_GET_PUB_RSA_KEY 			106
-#define	PK11_F_GET_PRIV_RSA_KEY 		107
-#define	PK11_F_RSA_GEN_KEY 			108
-#define	PK11_F_RSA_PUB_ENC 			109
-#define	PK11_F_RSA_PRIV_ENC 			110
-#define	PK11_F_RSA_PUB_DEC 			111
-#define	PK11_F_RSA_PRIV_DEC 			112
-#define	PK11_F_RSA_SIGN 			113
-#define	PK11_F_RSA_VERIFY 			114
-#define	PK11_F_RAND_ADD 			115
-#define	PK11_F_RAND_BYTES 			116
-#define	PK11_F_GET_SESSION 			117
-#define	PK11_F_FREE_SESSION 			118
-#define	PK11_F_LOAD_PUBKEY 			119
-#define	PK11_F_LOAD_PRIVKEY 			120
-#define	PK11_F_RSA_PUB_ENC_LOW 			121
-#define	PK11_F_RSA_PRIV_ENC_LOW 		122
-#define	PK11_F_RSA_PUB_DEC_LOW 			123
-#define	PK11_F_RSA_PRIV_DEC_LOW 		124
-#define	PK11_F_DSA_SIGN				125
-#define	PK11_F_DSA_VERIFY			126
-#define	PK11_F_DSA_INIT				127
-#define	PK11_F_DSA_FINISH			128
-#define	PK11_F_GET_PUB_DSA_KEY			129
-#define	PK11_F_GET_PRIV_DSA_KEY 		130
-#define	PK11_F_DH_INIT 				131
-#define	PK11_F_DH_FINISH 			132
-#define	PK11_F_MOD_EXP_DH 			133
-#define	PK11_F_GET_DH_KEY 			134
-#define	PK11_F_FREE_ALL_SESSIONS		135
-#define	PK11_F_SETUP_SESSION			136
-#define	PK11_F_DESTROY_OBJECT			137
-#define	PK11_F_CIPHER_INIT			138
-#define	PK11_F_CIPHER_DO_CIPHER			139
-#define	PK11_F_GET_CIPHER_KEY			140
-#define	PK11_F_DIGEST_INIT			141
-#define	PK11_F_DIGEST_UPDATE			142
-#define	PK11_F_DIGEST_FINAL			143
-#define	PK11_F_CHOOSE_SLOT			144
-#define	PK11_F_CIPHER_FINAL			145
-#define	PK11_F_LIBRARY_INIT 			146
-#define	PK11_F_LOAD 				147
-#define	PK11_F_DH_GEN_KEY			148
-#define	PK11_F_DH_COMP_KEY 			149
-#define	PK11_F_DIGEST_COPY 			150
-#define	PK11_F_CIPHER_CLEANUP			151
-#define	PK11_F_ACTIVE_ADD			152
-#define	PK11_F_ACTIVE_DELETE			153
-#define	PK11_F_CHECK_HW_MECHANISMS		154
-#define	PK11_F_INIT_SYMMETRIC			155
-#define	PK11_F_ADD_AES_CTR_NIDS			156
-#define	PK11_F_INIT_ALL_LOCKS			157
-#define	PK11_F_RETURN_SESSION			158
-#define	PK11_F_GET_PIN				159
-#define	PK11_F_FIND_ONE_OBJECT 			160
-#define	PK11_F_CHECK_TOKEN_ATTRS 		161
-#define	PK11_F_CACHE_PIN			162
-#define	PK11_F_MLOCK_PIN_IN_MEMORY		163
-#define	PK11_F_TOKEN_LOGIN 			164
-#define	PK11_F_TOKEN_RELOGIN 			165
-#define	PK11_F_RUN_ASKPASS 			166
-
-/* Reason codes. */
-#define	PK11_R_ALREADY_LOADED 			100
-#define	PK11_R_DSO_FAILURE 			101
-#define	PK11_R_NOT_LOADED 			102
-#define	PK11_R_PASSED_NULL_PARAMETER 		103
-#define	PK11_R_COMMAND_NOT_IMPLEMENTED 		104
-#define	PK11_R_INITIALIZE 			105
-#define	PK11_R_FINALIZE 			106
-#define	PK11_R_GETINFO 				107
-#define	PK11_R_GETSLOTLIST 			108
-#define	PK11_R_NO_MODULUS_OR_NO_EXPONENT 	109
-#define	PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID 	110
-#define	PK11_R_GETATTRIBUTVALUE 		111
-#define	PK11_R_NO_MODULUS 			112
-#define	PK11_R_NO_EXPONENT 			113
-#define	PK11_R_FINDOBJECTSINIT 			114
-#define	PK11_R_FINDOBJECTS 			115
-#define	PK11_R_FINDOBJECTSFINAL 		116
-#define	PK11_R_CREATEOBJECT 			118
-#define	PK11_R_DESTROYOBJECT 			119
-#define	PK11_R_OPENSESSION 			120
-#define	PK11_R_CLOSESESSION 			121
-#define	PK11_R_ENCRYPTINIT 			122
-#define	PK11_R_ENCRYPT 				123
-#define	PK11_R_SIGNINIT 			124
-#define	PK11_R_SIGN 				125
-#define	PK11_R_DECRYPTINIT 			126
-#define	PK11_R_DECRYPT 				127
-#define	PK11_R_VERIFYINIT 			128
-#define	PK11_R_VERIFY 				129
-#define	PK11_R_VERIFYRECOVERINIT 		130
-#define	PK11_R_VERIFYRECOVER 			131
-#define	PK11_R_GEN_KEY 				132
-#define	PK11_R_SEEDRANDOM 			133
-#define	PK11_R_GENERATERANDOM 			134
-#define	PK11_R_INVALID_MESSAGE_LENGTH 		135
-#define	PK11_R_UNKNOWN_ALGORITHM_TYPE 		136
-#define	PK11_R_UNKNOWN_ASN1_OBJECT_ID 		137
-#define	PK11_R_UNKNOWN_PADDING_TYPE 		138
-#define	PK11_R_PADDING_CHECK_FAILED 		139
-#define	PK11_R_DIGEST_TOO_BIG 			140
-#define	PK11_R_MALLOC_FAILURE 			141
-#define	PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED 	142
-#define	PK11_R_DATA_GREATER_THAN_MOD_LEN 	143
-#define	PK11_R_DATA_TOO_LARGE_FOR_MODULUS 	144
-#define	PK11_R_MISSING_KEY_COMPONENT		145
-#define	PK11_R_INVALID_SIGNATURE_LENGTH		146
-#define	PK11_R_INVALID_DSA_SIGNATURE_R		147
-#define	PK11_R_INVALID_DSA_SIGNATURE_S		148
-#define	PK11_R_INCONSISTENT_KEY			149
-#define	PK11_R_ENCRYPTUPDATE			150
-#define	PK11_R_DECRYPTUPDATE			151
-#define	PK11_R_DIGESTINIT			152
-#define	PK11_R_DIGESTUPDATE			153
-#define	PK11_R_DIGESTFINAL			154
-#define	PK11_R_ENCRYPTFINAL			155
-#define	PK11_R_DECRYPTFINAL			156
-#define	PK11_R_NO_PRNG_SUPPORT			157
-#define	PK11_R_GETTOKENINFO			158
-#define	PK11_R_DERIVEKEY			159
-#define	PK11_R_GET_OPERATION_STATE		160
-#define	PK11_R_SET_OPERATION_STATE		161
-#define	PK11_R_INVALID_HANDLE			162
-#define	PK11_R_KEY_OR_IV_LEN_PROBLEM		163
-#define	PK11_R_INVALID_OPERATION_TYPE		164
-#define	PK11_R_ADD_NID_FAILED			165
-#define	PK11_R_ATFORK_FAILED			166
-#define	PK11_R_TOKEN_LOGIN_FAILED		167
-#define	PK11_R_MORE_THAN_ONE_OBJECT_FOUND	168
-#define	PK11_R_INVALID_PKCS11_URI		169
-#define	PK11_R_COULD_NOT_READ_PIN		170
-#define	PK11_R_COULD_NOT_OPEN_COMMAND		171
-#define	PK11_R_PIPE_FAILED			172
-#define	PK11_R_PIN_NOT_READ_FROM_COMMAND	173
-#define	PK11_R_BAD_PASSPHRASE_SPEC		174
-#define	PK11_R_TOKEN_NOT_INITIALIZED		175
-#define	PK11_R_TOKEN_PIN_NOT_SET		176
-#define	PK11_R_TOKEN_PIN_NOT_PROVIDED		177
-#define	PK11_R_MISSING_OBJECT_LABEL		178
-#define	PK11_R_TOKEN_ATTRS_DO_NOT_MATCH		179
-#define	PK11_R_PRIV_KEY_NOT_FOUND		180
-#define	PK11_R_NO_OBJECT_FOUND			181
-#define	PK11_R_PIN_CACHING_POLICY_INVALID	182
-#define	PK11_R_SYSCONF_FAILED			183
-#define	PK11_R_MMAP_FAILED			183
-#define	PK11_R_PRIV_PROC_LOCK_MEMORY_MISSING	184
-#define	PK11_R_MLOCK_FAILED			185
-#define	PK11_R_FORK_FAILED			186
-
-#endif /* E_PK11_ERR_H */
--- a/components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_pub.c	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3274 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- *
- */
-
-/* crypto/engine/e_pk11_pub.c */
-/*
- * This product includes software developed by the OpenSSL Project for
- * use in the OpenSSL Toolkit (http://www.openssl.org/).
- *
- * This project also referenced hw_pkcs11-0.9.7b.patch written by
- * Afchine Madjlessi.
- */
-/*
- * ====================================================================
- * 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
- *    [email protected].
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * ([email protected]).  This product includes software written by Tim
- * Hudson ([email protected]).
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <strings.h>
-
-#include <openssl/e_os2.h>
-#include <openssl/crypto.h>
-#include <openssl/engine.h>
-#include <openssl/dso.h>
-#include <openssl/err.h>
-#include <openssl/bn.h>
-#include <openssl/pem.h>
-#ifndef OPENSSL_NO_RSA
-#include <openssl/rsa.h>
-#endif /* OPENSSL_NO_RSA */
-#ifndef OPENSSL_NO_DSA
-#include <openssl/dsa.h>
-#endif /* OPENSSL_NO_DSA */
-#ifndef OPENSSL_NO_DH
-#include <openssl/dh.h>
-#endif /* OPENSSL_NO_DH */
-#include <openssl/rand.h>
-#include <openssl/objects.h>
-#include <openssl/x509.h>
-#include <pthread.h>
-#include <libgen.h>
-
-#ifndef OPENSSL_NO_HW
-#ifndef OPENSSL_NO_HW_PK11
-
-#include <security/cryptoki.h>
-#include <security/pkcs11.h>
-#include "e_pk11.h"
-#include "e_pk11_uri.h"
-
-static CK_BBOOL pk11_login_done = CK_FALSE;
-extern CK_SLOT_ID pubkey_SLOTID;
-
-/*
- * During the reinitialization after a detected fork we will try to login to the
- * token using the passphrasedialog keyword that we inherit from the parent.
- */
-char *passphrasedialog;
-
-#ifndef OPENSSL_NO_RSA
-/* RSA stuff */
-static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa, int padding);
-static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa, int padding);
-static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa, int padding);
-static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa, int padding);
-static int pk11_RSA_init(RSA *rsa);
-static int pk11_RSA_finish(RSA *rsa);
-static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
-	unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
-static int pk11_RSA_verify(int dtype, const unsigned char *m,
-	unsigned int m_len, const unsigned char *sigbuf, unsigned int siglen,
-	const RSA *rsa);
-EVP_PKEY *pk11_load_privkey(ENGINE*, const char *privkey_id,
-	UI_METHOD *ui_method, void *callback_data);
-EVP_PKEY *pk11_load_pubkey(ENGINE*, const char *pubkey_id,
-	UI_METHOD *ui_method, void *callback_data);
-
-static int pk11_RSA_public_encrypt_low(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa);
-static int pk11_RSA_private_encrypt_low(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa);
-static int pk11_RSA_public_decrypt_low(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa);
-static int pk11_RSA_private_decrypt_low(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa);
-
-static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA* rsa, PK11_SESSION *sp);
-static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa, PK11_SESSION *sp);
-
-static int pk11_check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa);
-static int pk11_check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa);
-#endif
-
-/* DSA stuff */
-#ifndef OPENSSL_NO_DSA
-static int pk11_DSA_init(DSA *dsa);
-static int pk11_DSA_finish(DSA *dsa);
-static DSA_SIG *pk11_dsa_do_sign(const unsigned char *dgst, int dlen,
-	DSA *dsa);
-static int pk11_dsa_do_verify(const unsigned char *dgst, int dgst_len,
-	DSA_SIG *sig, DSA *dsa);
-
-static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa, DSA **key_ptr,
-	BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session);
-static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa, DSA **key_ptr,
-	BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session);
-
-static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa);
-static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa);
-#endif
-
-/* DH stuff */
-#ifndef OPENSSL_NO_DH
-static int pk11_DH_init(DH *dh);
-static int pk11_DH_finish(DH *dh);
-static int pk11_DH_generate_key(DH *dh);
-static int pk11_DH_compute_key(unsigned char *key,
-	const BIGNUM *pub_key, DH *dh);
-
-static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh, DH **key_ptr,
-	BIGNUM **priv_key, CK_SESSION_HANDLE session);
-
-static int check_new_dh_key(PK11_SESSION *sp, DH *dh);
-#endif
-
-static int find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
-	CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey);
-static int init_template_value(BIGNUM *bn, CK_VOID_PTR *pValue,
-	CK_ULONG *ulValueLen);
-static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn);
-
-static int pk11_pkey_meth_nids[] = {NID_dsa};
-
-/* Read mode string to be used for fopen() */
-#if SOLARIS_OPENSSL
-static char *read_mode_flags = "rF";
-#else
-static char *read_mode_flags = "r";
-#endif
-
-/*
- * Increment existing or create a new reference for an asymmetric key PKCS#11
- * object handle in the active object list. If the operation fails, unlock (if
- * locked), set error variable and jump to the specified label. We use this list
- * so that we can track how many references to the PKCS#11 objects are used from
- * all our sessions structures. If we are replacing an object reference in the
- * session structure and the ref count for the reference being replaced gets to
- * 0 we know that we can safely free the object itself via C_ObjectDestroy().
- * See also TRY_OBJ_DESTROY.
- */
-#define	KEY_HANDLE_REFHOLD(key_handle, alg_type, unlock, var, label)	\
-	{								\
-	if (pk11_active_add(key_handle, alg_type) < 0)			\
-		{							\
-		var = CK_TRUE;						\
-		if (unlock)						\
-			UNLOCK_OBJSTORE(alg_type);			\
-		goto label;						\
-		}							\
-	}
-
-/*
- * Find active list entry according to object handle and return pointer to the
- * entry otherwise return NULL.
- *
- * This function presumes it is called with lock protecting the active list
- * held.
- */
-static PK11_active *pk11_active_find(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
-	{
-	PK11_active *entry;
-
-	for (entry = active_list[type]; entry != NULL; entry = entry->next)
-		if (entry->h == h)
-			return (entry);
-
-	return (NULL);
-	}
-
-/*
- * Search for an entry in the active list using PKCS#11 object handle as a
- * search key and return refcnt of the found/created entry or -1 in case of
- * failure.
- *
- * This function presumes it is called with lock protecting the active list
- * held.
- */
-int
-pk11_active_add(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
-	{
-	PK11_active *entry = NULL;
-
-	if (h == CK_INVALID_HANDLE)
-		{
-		PK11err(PK11_F_ACTIVE_ADD, PK11_R_INVALID_HANDLE);
-		return (-1);
-		}
-
-	/* search for entry in the active list */
-	if ((entry = pk11_active_find(h, type)) != NULL)
-		entry->refcnt++;
-	else
-		{
-		/* not found, create new entry and add it to the list */
-		entry = OPENSSL_malloc(sizeof (PK11_active));
-		if (entry == NULL)
-			{
-			PK11err(PK11_F_ACTIVE_ADD, PK11_R_MALLOC_FAILURE);
-			return (-1);
-			}
-		entry->h = h;
-		entry->refcnt = 1;
-		entry->prev = NULL;
-		entry->next = NULL;
-		/* connect the newly created entry to the list */
-		if (active_list[type] == NULL)
-			active_list[type] = entry;
-		else /* make the entry first in the list */
-			{
-			entry->next = active_list[type];
-			active_list[type]->prev = entry;
-			active_list[type] = entry;
-			}
-		}
-
-	return (entry->refcnt);
-	}
-
-/*
- * Remove active list entry from the list and free it.
- *
- * This function presumes it is called with lock protecting the active list
- * held.
- */
-void
-pk11_active_remove(PK11_active *entry, PK11_OPTYPE type)
-	{
-	PK11_active *prev_entry;
-
-	/* remove the entry from the list and free it */
-	if ((prev_entry = entry->prev) != NULL)
-		{
-		prev_entry->next = entry->next;
-		if (entry->next != NULL)
-			entry->next->prev = prev_entry;
-		}
-	else
-		{
-		active_list[type] = entry->next;
-		/* we were the first but not the only one */
-		if (entry->next != NULL)
-			entry->next->prev = NULL;
-		}
-
-	/* sanitization */
-	entry->h = CK_INVALID_HANDLE;
-	entry->prev = NULL;
-	entry->next = NULL;
-	OPENSSL_free(entry);
-	}
-
-/* Free all entries from the active list. */
-void
-pk11_free_active_list(PK11_OPTYPE type)
-	{
-	PK11_active *entry;
-
-	/* only for asymmetric types since only they have C_Find* locks. */
-	switch (type)
-		{
-		case OP_RSA:
-		case OP_DSA:
-		case OP_DH:
-			break;
-		default:
-			return;
-		}
-
-	/* see find_lock array definition for more info on object locking */
-	LOCK_OBJSTORE(type);
-	while ((entry = active_list[type]) != NULL)
-		pk11_active_remove(entry, type);
-	UNLOCK_OBJSTORE(type);
-	}
-
-/*
- * Search for active list entry associated with given PKCS#11 object handle,
- * decrement its refcnt and if it drops to 0, disconnect the entry and free it.
- *
- * Return 1 if the PKCS#11 object associated with the entry has no references,
- * return 0 if there is at least one reference, -1 on error.
- *
- * This function presumes it is called with lock protecting the active list
- * held.
- */
-int
-pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
-	{
-	PK11_active *entry = NULL;
-
-	if ((entry = pk11_active_find(h, type)) == NULL)
-		{
-		PK11err(PK11_F_ACTIVE_DELETE, PK11_R_INVALID_HANDLE);
-		return (-1);
-		}
-
-	OPENSSL_assert(entry->refcnt > 0);
-	entry->refcnt--;
-	if (entry->refcnt == 0)
-		{
-		pk11_active_remove(entry, type);
-		return (1);
-		}
-
-	return (0);
-	}
-
-#ifndef OPENSSL_NO_RSA
-/* Our internal RSA_METHOD that we provide pointers to */
-static RSA_METHOD pk11_rsa =
-	{
-	"PKCS#11 RSA method",
-	pk11_RSA_public_encrypt,		/* rsa_pub_encrypt */
-	pk11_RSA_public_decrypt,		/* rsa_pub_decrypt */
-	pk11_RSA_private_encrypt,		/* rsa_priv_encrypt */
-	pk11_RSA_private_decrypt,		/* rsa_priv_decrypt */
-	NULL,					/* rsa_mod_exp */
-	NULL,					/* bn_mod_exp */
-	pk11_RSA_init,				/* init */
-	pk11_RSA_finish,			/* finish */
-	RSA_FLAG_SIGN_VER,			/* flags */
-	NULL,					/* app_data */
-	pk11_RSA_sign,				/* rsa_sign */
-	pk11_RSA_verify,			/* rsa_verify */
-	/* Internal rsa_keygen will be used if this is NULL. */
-	NULL					/* rsa_keygen */
-	};
-
-RSA_METHOD *
-PK11_RSA(void)
-	{
-	return (&pk11_rsa);
-	}
-#endif
-
-#ifndef OPENSSL_NO_DSA
-/* Our internal DSA_METHOD that we provide pointers to */
-static DSA_METHOD pk11_dsa =
-	{
-	"PKCS#11 DSA method",
-	pk11_dsa_do_sign, 	/* dsa_do_sign */
-	NULL, 			/* dsa_sign_setup */
-	pk11_dsa_do_verify, 	/* dsa_do_verify */
-	NULL,			/* dsa_mod_exp */
-	NULL, 			/* bn_mod_exp */
-	pk11_DSA_init, 		/* init */
-	pk11_DSA_finish, 	/* finish */
-	0, 			/* flags */
-	NULL 			/* app_data */
-	};
-
-DSA_METHOD *
-PK11_DSA(void)
-	{
-	return (&pk11_dsa);
-	}
-#endif
-
-#ifndef OPENSSL_NO_DH
-/*
- * PKCS #11 V2.20, section 11.2 specifies that the number of bytes needed for
- * output buffer may somewhat exceed the precise number of bytes needed, but
- * should not exceed it by a large amount. That may be caused, for example, by
- * rounding it up to multiple of X in the underlying bignum library. 8 should be
- * enough.
- */
-#define	DH_BUF_RESERVE	8
-
-/* Our internal DH_METHOD that we provide pointers to */
-static DH_METHOD pk11_dh =
-	{
-	"PKCS#11 DH method",
-	pk11_DH_generate_key,	/* generate_key */
-	pk11_DH_compute_key,	/* compute_key */
-	NULL,			/* bn_mod_exp */
-	pk11_DH_init,		/* init */
-	pk11_DH_finish,		/* finish */
-	0,			/* flags */
-	NULL,			/* app_data */
-	NULL			/* generate_params */
-	};
-
-DH_METHOD *
-PK11_DH(void)
-	{
-	return (&pk11_dh);
-	}
-#endif
-
-/* Size of an SSL signature: MD5+SHA1 */
-#define	SSL_SIG_LENGTH		36
-
-/* Lengths of DSA data and signature */
-#define	DSA_DATA_LEN		20
-#define	DSA_SIGNATURE_LEN	40
-
-#ifndef OPENSSL_NO_RSA
-/*
- * Similar to OpenSSL to take advantage of the paddings. The goal is to
- * support all paddings in this engine although PK11 library does not
- * support all the paddings used in OpenSSL.
- * The input errors should have been checked in the padding functions.
- */
-static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
-		unsigned char *to, RSA *rsa, int padding)
-	{
-	int i, num = 0, r = -1;
-	unsigned char *buf = NULL;
-
-	num = BN_num_bytes(rsa->n);
-	if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
-		{
-		PK11err(PK11_F_RSA_PUB_ENC, PK11_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:
-		PK11err(PK11_F_RSA_PUB_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
-		goto err;
-		}
-	if (i <= 0) goto err;
-
-	/* PK11 functions are called here */
-	r = pk11_RSA_public_encrypt_low(num, buf, to, rsa);
-err:
-	if (buf != NULL)
-		{
-		OPENSSL_cleanse(buf, num);
-		OPENSSL_free(buf);
-		}
-	return (r);
-	}
-
-
-/*
- * Similar to Openssl to take advantage of the paddings. The input errors
- * should be caught in the padding functions
- */
-static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa, int padding)
-	{
-	int i, num = 0, r = -1;
-	unsigned char *buf = NULL;
-
-	num = BN_num_bytes(rsa->n);
-	if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
-		{
-		PK11err(PK11_F_RSA_PRIV_ENC, PK11_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_NO_PADDING:
-		i = RSA_padding_add_none(buf, num, from, flen);
-		break;
-	case RSA_SSLV23_PADDING:
-	default:
-		PK11err(PK11_F_RSA_PRIV_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
-		goto err;
-		}
-	if (i <= 0) goto err;
-
-	/* PK11 functions are called here */
-	r = pk11_RSA_private_encrypt_low(num, buf, to, rsa);
-err:
-	if (buf != NULL)
-		{
-		OPENSSL_cleanse(buf, num);
-		OPENSSL_free(buf);
-		}
-	return (r);
-	}
-
-/* Similar to OpenSSL code. Input errors are also checked here */
-static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa, int padding)
-	{
-	BIGNUM f;
-	int j, num = 0, r = -1;
-	unsigned char *p;
-	unsigned char *buf = NULL;
-
-	BN_init(&f);
-
-	num = BN_num_bytes(rsa->n);
-
-	if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
-		{
-		PK11err(PK11_F_RSA_PRIV_DEC, PK11_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)
-		{
-		PK11err(PK11_F_RSA_PRIV_DEC,
-			PK11_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)
-		{
-		PK11err(PK11_F_RSA_PRIV_DEC,
-			PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
-		goto err;
-		}
-
-	/* PK11 functions are called here */
-	r = pk11_RSA_private_decrypt_low(flen, from, buf, rsa);
-
-	/*
-	 * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
-	 * Needs to skip these 0's paddings here.
-	 */
-	for (j = 0; j < r; j++)
-		if (buf[j] != 0)
-			break;
-
-	p = buf + j;
-	j = r - j;  /* j is only used with no-padding mode */
-
-	switch (padding)
-		{
-	case RSA_PKCS1_PADDING:
-		r = RSA_padding_check_PKCS1_type_2(to, num, p, j, num);
-		break;
-#ifndef OPENSSL_NO_SHA
-	case RSA_PKCS1_OAEP_PADDING:
-		r = RSA_padding_check_PKCS1_OAEP(to, num, p, j, num, NULL, 0);
-		break;
-#endif
-	case RSA_SSLV23_PADDING:
-		r = RSA_padding_check_SSLv23(to, num, p, j, num);
-		break;
-	case RSA_NO_PADDING:
-		r = RSA_padding_check_none(to, num, p, j, num);
-		break;
-	default:
-		PK11err(PK11_F_RSA_PRIV_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
-		goto err;
-		}
-	if (r < 0)
-		PK11err(PK11_F_RSA_PRIV_DEC, PK11_R_PADDING_CHECK_FAILED);
-
-err:
-	BN_clear_free(&f);
-	if (buf != NULL)
-		{
-		OPENSSL_cleanse(buf, num);
-		OPENSSL_free(buf);
-		}
-	return (r);
-	}
-
-/* Similar to OpenSSL code. Input errors are also checked here */
-static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa, int padding)
-	{
-	BIGNUM f;
-	int i, num = 0, r = -1;
-	unsigned char *p;
-	unsigned char *buf = NULL;
-
-	BN_init(&f);
-	num = BN_num_bytes(rsa->n);
-	buf = (unsigned char *)OPENSSL_malloc(num);
-	if (buf == NULL)
-		{
-		PK11err(PK11_F_RSA_PUB_DEC, PK11_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)
-		{
-		PK11err(PK11_F_RSA_PUB_DEC, PK11_R_DATA_GREATER_THAN_MOD_LEN);
-		goto err;
-		}
-
-	if (BN_bin2bn(from, flen, &f) == NULL)
-		goto err;
-
-	if (BN_ucmp(&f, rsa->n) >= 0)
-		{
-		PK11err(PK11_F_RSA_PUB_DEC,
-			PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
-		goto err;
-		}
-
-	/* PK11 functions are called here */
-	r = pk11_RSA_public_decrypt_low(flen, from, buf, rsa);
-
-	/*
-	 * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
-	 * Needs to skip these 0's here
-	 */
-	for (i = 0; i < r; i++)
-		if (buf[i] != 0)
-			break;
-
-	p = buf + i;
-	i = r - i;  /* i is only used with no-padding mode */
-
-	switch (padding)
-		{
-	case RSA_PKCS1_PADDING:
-		r = RSA_padding_check_PKCS1_type_1(to, num, p, i, num);
-		break;
-	case RSA_NO_PADDING:
-		r = RSA_padding_check_none(to, num, p, i, num);
-		break;
-	default:
-		PK11err(PK11_F_RSA_PUB_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
-		goto err;
-		}
-	if (r < 0)
-		PK11err(PK11_F_RSA_PUB_DEC, PK11_R_PADDING_CHECK_FAILED);
-
-err:
-	BN_clear_free(&f);
-	if (buf != NULL)
-		{
-		OPENSSL_cleanse(buf, num);
-		OPENSSL_free(buf);
-		}
-	return (r);
-	}
-
-/*
- * This function implements RSA public encryption using C_EncryptInit and
- * C_Encrypt pk11 interfaces. Note that the CKM_RSA_X_509 is used here.
- * The calling function allocated sufficient memory in "to" to store results.
- */
-static int pk11_RSA_public_encrypt_low(int flen,
-	const unsigned char *from, unsigned char *to, RSA *rsa)
-	{
-	CK_ULONG bytes_encrypted = flen;
-	int retval = -1;
-	CK_RV rv;
-	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
-	CK_MECHANISM *p_mech = &mech_rsa;
-	CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
-	PK11_SESSION *sp;
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		return (-1);
-
-	(void) pk11_check_new_rsa_key_pub(sp, rsa);
-
-	h_pub_key = sp->opdata_rsa_pub_key;
-	if (h_pub_key == CK_INVALID_HANDLE)
-		h_pub_key = sp->opdata_rsa_pub_key =
-			pk11_get_public_rsa_key(rsa, sp);
-
-	if (h_pub_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_EncryptInit(sp->session, p_mech,
-			h_pub_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
-			    PK11_R_ENCRYPTINIT, rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-
-		rv = pFuncList->C_Encrypt(sp->session,
-			(unsigned char *)from, flen, to, &bytes_encrypted);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
-			    PK11_R_ENCRYPT, rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-		retval = bytes_encrypted;
-		}
-
-	pk11_return_session(sp, OP_RSA);
-	return (retval);
-	}
-
-
-/*
- * This function implements RSA private encryption using C_SignInit and
- * C_Sign pk11 APIs. Note that CKM_RSA_X_509 is used here.
- * The calling function allocated sufficient memory in "to" to store results.
- */
-static int pk11_RSA_private_encrypt_low(int flen,
-	const unsigned char *from, unsigned char *to, RSA *rsa)
-	{
-	CK_ULONG ul_sig_len = flen;
-	int retval = -1;
-	CK_RV rv;
-	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
-	CK_MECHANISM *p_mech = &mech_rsa;
-	CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
-	PK11_SESSION *sp;
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		return (-1);
-
-	(void) pk11_check_new_rsa_key_priv(sp, rsa);
-
-	h_priv_key = sp->opdata_rsa_priv_key;
-	if (h_priv_key == CK_INVALID_HANDLE)
-		h_priv_key = sp->opdata_rsa_priv_key =
-			pk11_get_private_rsa_key(rsa, sp);
-
-	if (h_priv_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_SignInit(sp->session, p_mech,
-			h_priv_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW,
-			    PK11_R_SIGNINIT, rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-
-		rv = pFuncList->C_Sign(sp->session,
-			(unsigned char *)from, flen, to, &ul_sig_len);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW, PK11_R_SIGN,
-			    rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-
-		retval = ul_sig_len;
-		}
-
-	pk11_return_session(sp, OP_RSA);
-	return (retval);
-	}
-
-
-/*
- * This function implements RSA private decryption using C_DecryptInit and
- * C_Decrypt pk11 APIs. Note that CKM_RSA_X_509 mechanism is used here.
- * The calling function allocated sufficient memory in "to" to store results.
- */
-static int pk11_RSA_private_decrypt_low(int flen,
-	const unsigned char *from, unsigned char *to, RSA *rsa)
-	{
-	CK_ULONG bytes_decrypted = flen;
-	int retval = -1;
-	CK_RV rv;
-	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
-	CK_MECHANISM *p_mech = &mech_rsa;
-	CK_OBJECT_HANDLE h_priv_key;
-	PK11_SESSION *sp;
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		return (-1);
-
-	(void) pk11_check_new_rsa_key_priv(sp, rsa);
-
-	h_priv_key = sp->opdata_rsa_priv_key;
-	if (h_priv_key == CK_INVALID_HANDLE)
-		h_priv_key = sp->opdata_rsa_priv_key =
-			pk11_get_private_rsa_key(rsa, sp);
-
-	if (h_priv_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_DecryptInit(sp->session, p_mech,
-			h_priv_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
-				PK11_R_DECRYPTINIT, rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-
-		rv = pFuncList->C_Decrypt(sp->session,
-			(unsigned char *)from, flen, to, &bytes_decrypted);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
-			    PK11_R_DECRYPT, rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-		retval = bytes_decrypted;
-		}
-
-	pk11_return_session(sp, OP_RSA);
-	return (retval);
-	}
-
-
-/*
- * This function implements RSA public decryption using C_VerifyRecoverInit
- * and C_VerifyRecover pk11 APIs. Note that CKM_RSA_X_509 is used here.
- * The calling function allocated sufficient memory in "to" to store results.
- */
-static int pk11_RSA_public_decrypt_low(int flen,
-	const unsigned char *from, unsigned char *to, RSA *rsa)
-	{
-	CK_ULONG bytes_decrypted = flen;
-	int retval = -1;
-	CK_RV rv;
-	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
-	CK_MECHANISM *p_mech = &mech_rsa;
-	CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
-	PK11_SESSION *sp;
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		return (-1);
-
-	(void) pk11_check_new_rsa_key_pub(sp, rsa);
-
-	h_pub_key = sp->opdata_rsa_pub_key;
-	if (h_pub_key == CK_INVALID_HANDLE)
-		h_pub_key = sp->opdata_rsa_pub_key =
-			pk11_get_public_rsa_key(rsa, sp);
-
-	if (h_pub_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_VerifyRecoverInit(sp->session,
-			p_mech, h_pub_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
-				PK11_R_VERIFYRECOVERINIT, rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-
-		rv = pFuncList->C_VerifyRecover(sp->session,
-			(unsigned char *)from, flen, to, &bytes_decrypted);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
-			    PK11_R_VERIFYRECOVER, rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-		retval = bytes_decrypted;
-		}
-
-	pk11_return_session(sp, OP_RSA);
-	return (retval);
-	}
-
-static int pk11_RSA_init(RSA *rsa)
-	{
-	/*
-	 * This flag in the RSA_METHOD enables the new rsa_sign,
-	 * rsa_verify functions. See rsa.h for details.
-	 */
-	rsa->flags |= RSA_FLAG_SIGN_VER;
-
-	return (1);
-	}
-
-static int pk11_RSA_finish(RSA *rsa)
-	{
-	/*
-	 * Since we are overloading OpenSSL's native RSA_eay_finish() we need
-	 * to do the same as in the original function, i.e. to free bignum
-	 * structures.
-	 */
-	if (rsa->_method_mod_n != NULL)
-		BN_MONT_CTX_free(rsa->_method_mod_n);
-	if (rsa->_method_mod_p != NULL)
-		BN_MONT_CTX_free(rsa->_method_mod_p);
-	if (rsa->_method_mod_q != NULL)
-		BN_MONT_CTX_free(rsa->_method_mod_q);
-
-	return (1);
-	}
-
-/*
- * Standard engine interface function. Majority codes here are from
- * rsa/rsa_sign.c. We replaced the decrypt function call by C_Sign of PKCS#11.
- * See more details in rsa/rsa_sign.c
- */
-static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
-	unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
-	{
-	X509_SIG sig;
-	ASN1_TYPE parameter;
-	int i, j;
-	unsigned char *p, *s = NULL;
-	X509_ALGOR algor;
-	ASN1_OCTET_STRING digest;
-	CK_RV rv;
-	CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
-	CK_MECHANISM *p_mech = &mech_rsa;
-	CK_OBJECT_HANDLE h_priv_key;
-	PK11_SESSION *sp = NULL;
-	int ret = 0;
-	unsigned long ulsiglen;
-
-	/* Encode the digest */
-	/* Special case: SSL signature, just check the length */
-	if (type == NID_md5_sha1)
-		{
-		if (m_len != SSL_SIG_LENGTH)
-			{
-			PK11err(PK11_F_RSA_SIGN,
-				PK11_R_INVALID_MESSAGE_LENGTH);
-			goto err;
-			}
-		i = SSL_SIG_LENGTH;
-		s = (unsigned char *)m;
-		}
-	else
-		{
-		sig.algor = &algor;
-		sig.algor->algorithm = OBJ_nid2obj(type);
-		if (sig.algor->algorithm == NULL)
-			{
-			PK11err(PK11_F_RSA_SIGN,
-				PK11_R_UNKNOWN_ALGORITHM_TYPE);
-			goto err;
-			}
-		if (sig.algor->algorithm->length == 0)
-			{
-			PK11err(PK11_F_RSA_SIGN,
-				PK11_R_UNKNOWN_ASN1_OBJECT_ID);
-			goto err;
-			}
-		parameter.type = V_ASN1_NULL;
-		parameter.value.ptr = NULL;
-		sig.algor->parameter = &parameter;
-
-		sig.digest = &digest;
-		sig.digest->data = (unsigned char *)m;
-		sig.digest->length = m_len;
-
-		i = i2d_X509_SIG(&sig, NULL);
-		}
-
-	j = RSA_size(rsa);
-	if ((i - RSA_PKCS1_PADDING) > j)
-		{
-		PK11err(PK11_F_RSA_SIGN, PK11_R_DIGEST_TOO_BIG);
-		goto err;
-		}
-
-	if (type != NID_md5_sha1)
-		{
-		s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
-		if (s == NULL)
-			{
-			PK11err(PK11_F_RSA_SIGN, PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-		p = s;
-		(void) i2d_X509_SIG(&sig, &p);
-		}
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		goto err;
-
-	(void) pk11_check_new_rsa_key_priv(sp, rsa);
-
-	h_priv_key = sp->opdata_rsa_priv_key;
-	if (h_priv_key == CK_INVALID_HANDLE)
-		h_priv_key = sp->opdata_rsa_priv_key =
-			pk11_get_private_rsa_key((RSA *)rsa, sp);
-
-	if (h_priv_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGNINIT, rv);
-			goto err;
-			}
-
-		ulsiglen = j;
-		rv = pFuncList->C_Sign(sp->session, s, i, sigret,
-			(CK_ULONG_PTR) &ulsiglen);
-		*siglen = ulsiglen;
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGN, rv);
-			goto err;
-			}
-		ret = 1;
-		}
-
-err:
-	if (type != NID_md5_sha1)
-		{
-		(void) memset(s, 0, (unsigned int)(j + 1));
-		OPENSSL_free(s);
-		}
-
-	pk11_return_session(sp, OP_RSA);
-	return (ret);
-	}
-
-static int pk11_RSA_verify(int type, const unsigned char *m,
-	unsigned int m_len, const unsigned char *sigbuf, unsigned int siglen,
-	const RSA *rsa)
-	{
-	X509_SIG sig;
-	ASN1_TYPE parameter;
-	int i, j;
-	unsigned char *p, *s = NULL;
-	X509_ALGOR algor;
-	ASN1_OCTET_STRING digest;
-	CK_RV rv;
-	CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
-	CK_MECHANISM *p_mech = &mech_rsa;
-	CK_OBJECT_HANDLE h_pub_key;
-	PK11_SESSION *sp = NULL;
-	int ret = 0;
-
-	/* Encode the digest	*/
-	/* Special case: SSL signature, just check the length */
-	if (type == NID_md5_sha1)
-		{
-		if (m_len != SSL_SIG_LENGTH)
-			{
-			PK11err(PK11_F_RSA_VERIFY,
-				PK11_R_INVALID_MESSAGE_LENGTH);
-			goto err;
-			}
-		i = SSL_SIG_LENGTH;
-		s = (unsigned char *)m;
-		}
-	else
-		{
-		sig.algor = &algor;
-		sig.algor->algorithm = OBJ_nid2obj(type);
-		if (sig.algor->algorithm == NULL)
-			{
-			PK11err(PK11_F_RSA_VERIFY,
-				PK11_R_UNKNOWN_ALGORITHM_TYPE);
-			goto err;
-			}
-		if (sig.algor->algorithm->length == 0)
-			{
-			PK11err(PK11_F_RSA_VERIFY,
-				PK11_R_UNKNOWN_ASN1_OBJECT_ID);
-			goto err;
-			}
-		parameter.type = V_ASN1_NULL;
-		parameter.value.ptr = NULL;
-		sig.algor->parameter = &parameter;
-		sig.digest = &digest;
-		sig.digest->data = (unsigned char *)m;
-		sig.digest->length = m_len;
-		i = i2d_X509_SIG(&sig, NULL);
-		}
-
-	j = RSA_size(rsa);
-	if ((i - RSA_PKCS1_PADDING) > j)
-		{
-		PK11err(PK11_F_RSA_VERIFY, PK11_R_DIGEST_TOO_BIG);
-		goto err;
-		}
-
-	if (type != NID_md5_sha1)
-		{
-		s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
-		if (s == NULL)
-			{
-			PK11err(PK11_F_RSA_VERIFY, PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-		p = s;
-		(void) i2d_X509_SIG(&sig, &p);
-		}
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		goto err;
-
-	(void) pk11_check_new_rsa_key_pub(sp, rsa);
-
-	h_pub_key = sp->opdata_rsa_pub_key;
-	if (h_pub_key == CK_INVALID_HANDLE)
-		h_pub_key = sp->opdata_rsa_pub_key =
-			pk11_get_public_rsa_key((RSA *)rsa, sp);
-
-	if (h_pub_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_VerifyInit(sp->session, p_mech,
-			h_pub_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFYINIT,
-			    rv);
-			goto err;
-			}
-		rv = pFuncList->C_Verify(sp->session, s, i,
-			(CK_BYTE_PTR)sigbuf, (CK_ULONG)siglen);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFY, rv);
-			goto err;
-			}
-		ret = 1;
-		}
-
-err:
-	if (type != NID_md5_sha1)
-		{
-		(void) memset(s, 0, (unsigned int)siglen);
-		OPENSSL_free(s);
-		}
-
-	pk11_return_session(sp, OP_RSA);
-	return (ret);
-	}
-
-#define	MAXATTR	1024
-/*
- * Load RSA private key from a file or get its PKCS#11 handle if stored in the
- * PKCS#11 token.
- */
-/* ARGSUSED */
-EVP_PKEY *pk11_load_privkey(ENGINE* e, const char *privkey_id,
-	UI_METHOD *ui_method, void *callback_data)
-	{
-	EVP_PKEY *pkey = NULL;
-	FILE *privkey;
-	CK_OBJECT_HANDLE  h_priv_key = CK_INVALID_HANDLE;
-	RSA *rsa = NULL;
-	PK11_SESSION *sp;
-	/* Anything else below is needed for the key by reference extension. */
-	const char *file;
-	int ret;
-	pkcs11_uri uri_struct;
-	CK_RV rv;
-	CK_BBOOL is_token = CK_TRUE;
-	CK_BBOOL rollback = CK_FALSE;
-	CK_BYTE attr_data[8][MAXATTR];
-	CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
-	CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;	/* key in keystore */
-
-	/* We look for private keys only. */
-	CK_ATTRIBUTE search_templ[] =
-		{
-		{CKA_TOKEN, &is_token, sizeof (is_token)},
-		{CKA_CLASS, &key_class, sizeof (key_class)},
-		{CKA_LABEL, NULL, 0}
-		};
-
-	/*
-	 * These public attributes are needed to initialize the OpenSSL RSA
-	 * structure with something we can use to look up the key. Note that we
-	 * never ask for private components.
-	 */
-	CK_ATTRIBUTE get_templ[] =
-		{
-		{CKA_MODULUS, (void *)attr_data[0], MAXATTR},		/* n */
-		{CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},	/* e */
-		};
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		return (NULL);
-
-	/*
-	 * The next function will decide whether we are going to access keys in
-	 * the token or read them from plain files. It all depends on what is in
-	 * the 'privkey_id' parameter.
-	 */
-	ret = pk11_process_pkcs11_uri(privkey_id, &uri_struct, &file);
-
-	if (ret == 0)
-		goto err;
-
-	/* We will try to access a key from a PKCS#11 token. */
-	if (ret == 1)
-		{
-		if (pk11_check_token_attrs(&uri_struct) == 0)
-			goto err;
-
-		search_templ[2].pValue = uri_struct.object;
-		search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
-
-		if (pk11_token_login(sp->session, &pk11_login_done,
-		    &uri_struct, CK_TRUE) == 0)
-			goto err;
-
-		/*
-		 * Now let's try to find the key in the token. It is a failure
-		 * if we can't find it.
-		 */
-		if (find_one_object(OP_RSA, sp->session, search_templ, 3,
-		    &ks_key) == 0)
-			goto err;
-
-		/*
-		 * Free the structure now. Note that we use uri_struct's field
-		 * directly in the template so we cannot free it until the find
-		 * is done.
-		 */
-		pk11_free_pkcs11_uri(&uri_struct, 0);
-
-		/*
-		 * We might have a cache hit which we could confirm according to
-		 * the 'n'/'e' params, RSA public pointer as NULL, and non-NULL
-		 * RSA private pointer. However, it is easier just to recreate
-		 * everything. We expect the keys to be loaded once and used
-		 * many times. We do not check the return value because even in
-		 * case of failure the sp structure will have both key pointer
-		 * and object handle cleaned and pk11_destroy_object() reports
-		 * the failure to the OpenSSL error message buffer.
-		 */
-		(void) pk11_destroy_rsa_object_priv(sp, CK_TRUE);
-
-		sp->opdata_rsa_priv_key = ks_key;
-		/* This object shall not be deleted on a cache miss. */
-		sp->persistent = CK_TRUE;
-
-		if ((rsa = sp->opdata_rsa_priv = RSA_new_method(e)) == NULL)
-			goto err;
-
-		if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
-		    get_templ, 2)) != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_LOAD_PRIVKEY,
-			    PK11_R_GETATTRIBUTVALUE, rv);
-			goto err;
-			}
-
-		/*
-		 * Cache the RSA private structure pointer. We do not use it now
-		 * for key-by-ref keys but let's do it for consistency reasons.
-		 */
-		sp->opdata_rsa_priv = rsa;
-
-		/*
-		 * We do not use pk11_get_private_rsa_key() here so we must take
-		 * care of handle management ourselves.
-		 */
-		KEY_HANDLE_REFHOLD(ks_key, OP_RSA, CK_FALSE, rollback, err);
-
-		/*
-		 * Those are the sensitive components we do not want to export
-		 * from the token at all: rsa->(d|p|q|dmp1|dmq1|iqmp).
-		 */
-		attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
-		attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
-		/*
-		 * Must have 'n'/'e' components in the session structure as
-		 * well. They serve as a public look-up key for the private key
-		 * in the keystore.
-		 */
-		attr_to_BN(&get_templ[0], attr_data[0], &sp->opdata_rsa_n_num);
-		attr_to_BN(&get_templ[1], attr_data[1], &sp->opdata_rsa_e_num);
-
-		if ((pkey = EVP_PKEY_new()) == NULL)
-			goto err;
-
-		if (EVP_PKEY_set1_RSA(pkey, rsa) == 0)
-			goto err;
-		}
-	else
-		if ((privkey = fopen(file, read_mode_flags)) != NULL)
-			{
-			pkey = PEM_read_PrivateKey(privkey, NULL, NULL, NULL);
-			(void) fclose(privkey);
-			if (pkey != NULL)
-				{
-				rsa = EVP_PKEY_get1_RSA(pkey);
-				if (rsa != NULL)
-					{
-					(void) pk11_check_new_rsa_key_priv(sp,
-					    rsa);
-
-					h_priv_key = sp->opdata_rsa_priv_key =
-					    pk11_get_private_rsa_key(rsa, sp);
-					if (h_priv_key == CK_INVALID_HANDLE)
-						goto err;
-					}
-				else
-					goto err;
-				}
-			}
-
-	pk11_return_session(sp, OP_RSA);
-	return (pkey);
-err:
-	if (rsa != NULL)
-		RSA_free(rsa);
-	if (pkey != NULL)
-		{
-		EVP_PKEY_free(pkey);
-		pkey = NULL;
-		}
-	return (pkey);
-	}
-
-/* Load RSA public key from a file or load it from the PKCS#11 token. */
-/* ARGSUSED */
-EVP_PKEY *pk11_load_pubkey(ENGINE* e, const char *pubkey_id,
-	UI_METHOD *ui_method, void *callback_data)
-	{
-	EVP_PKEY *pkey = NULL;
-	FILE *pubkey;
-	CK_OBJECT_HANDLE  h_pub_key = CK_INVALID_HANDLE;
-	RSA *rsa = NULL;
-	PK11_SESSION *sp;
-	/* everything else below needed for key by reference extension */
-	int ret;
-	const char *file;
-	pkcs11_uri uri_struct;
-	CK_RV rv;
-	CK_BBOOL is_token = CK_TRUE;
-	CK_BYTE attr_data[2][MAXATTR];
-	CK_OBJECT_CLASS key_class = CKO_PUBLIC_KEY;
-	CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;	/* key in keystore */
-
-	CK_ATTRIBUTE search_templ[] =
-		{
-		{CKA_TOKEN, &is_token, sizeof (is_token)},
-		{CKA_CLASS, &key_class, sizeof (key_class)},
-		{CKA_LABEL, NULL, 0}
-		};
-
-	/*
-	 * These public attributes are needed to initialize OpenSSL RSA
-	 * structure with something we can use to look up the key.
-	 */
-	CK_ATTRIBUTE get_templ[] =
-		{
-		{CKA_MODULUS, (void *)attr_data[0], MAXATTR},		/* n */
-		{CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},	/* e */
-		};
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		return (NULL);
-
-	ret = pk11_process_pkcs11_uri(pubkey_id, &uri_struct, &file);
-
-	if (ret == 0)
-		goto err;
-
-	if (ret == 1)
-		{
-		if (pk11_check_token_attrs(&uri_struct) == 0)
-			goto err;
-
-		search_templ[2].pValue = uri_struct.object;
-		search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
-
-		if (pk11_token_login(sp->session, &pk11_login_done,
-		    &uri_struct, CK_FALSE) == 0)
-			goto err;
-
-		if (find_one_object(OP_RSA, sp->session, search_templ, 3,
-		    &ks_key) == 0)
-			{
-			goto err;
-			}
-
-		/*
-		 * Free the structure now. Note that we use uri_struct's field
-		 * directly in the template so we can't free until find is done.
-		 */
-		pk11_free_pkcs11_uri(&uri_struct, 0);
-		/*
-		 * We load a new public key so we will create a new RSA
-		 * structure. No cache hit is possible.
-		 */
-		(void) pk11_destroy_rsa_object_pub(sp, CK_TRUE);
-		sp->opdata_rsa_pub_key = ks_key;
-
-		if ((rsa = sp->opdata_rsa_pub = RSA_new_method(e)) == NULL)
-			goto err;
-
-		if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
-		    get_templ, 2)) != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_LOAD_PUBKEY,
-			    PK11_R_GETATTRIBUTVALUE, rv);
-			goto err;
-			}
-
-		/*
-		 * Cache the RSA public structure pointer.
-		 */
-		sp->opdata_rsa_pub = rsa;
-
-		/*
-		 * These are the sensitive components we do not want to export
-		 * from the token at all: rsa->(d|p|q|dmp1|dmq1|iqmp).
-		 */
-		attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
-		attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
-
-		if ((pkey = EVP_PKEY_new()) == NULL)
-			goto err;
-
-		if (EVP_PKEY_set1_RSA(pkey, rsa) == 0)
-			goto err;
-
-		/*
-		 * Create a session object from it so that when calling
-		 * pk11_get_public_rsa_key() the next time, we can find it. The
-		 * reason why we do that is that we cannot tell from the RSA
-		 * structure (OpenSSL RSA structure does not have any room for
-		 * additional data used by the engine, for example) if it bears
-		 * a public key stored in the keystore or not so it's better if
-		 * we always have a session key. Note that this is different
-		 * from what we do for the private keystore objects but in that
-		 * case, we can tell from the RSA structure that the keystore
-		 * object is in play - the 'd' component is NULL in that case.
-		 */
-		h_pub_key = sp->opdata_rsa_pub_key =
-		    pk11_get_public_rsa_key(rsa, sp);
-		if (h_pub_key == CK_INVALID_HANDLE)
-			goto err;
-		}
-	else
-		if ((pubkey = fopen(file, read_mode_flags)) != NULL)
-			{
-			pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL);
-			(void) fclose(pubkey);
-			if (pkey != NULL)
-				{
-				rsa = EVP_PKEY_get1_RSA(pkey);
-				if (rsa != NULL)
-					{
-					/*
-					 * This will always destroy the RSA
-					 * object since we have a new RSA
-					 * structure here.
-					 */
-					(void) pk11_check_new_rsa_key_pub(sp,
-					    rsa);
-
-					h_pub_key = sp->opdata_rsa_pub_key =
-					    pk11_get_public_rsa_key(rsa, sp);
-					if (h_pub_key == CK_INVALID_HANDLE)
-						{
-						EVP_PKEY_free(pkey);
-						pkey = NULL;
-						}
-					}
-				else
-					{
-					EVP_PKEY_free(pkey);
-					pkey = NULL;
-					}
-				}
-			}
-
-	pk11_return_session(sp, OP_RSA);
-	return (pkey);
-err:
-	if (rsa != NULL)
-		RSA_free(rsa);
-	if (pkey != NULL)
-		{
-		EVP_PKEY_free(pkey);
-		pkey = NULL;
-		}
-	return (pkey);
-	}
-
-/*
- * Get a public key object in a session from a given rsa structure. If the
- * PKCS#11 session object already exists it is found, reused, and
- * the counter in the active object list incremented. If not found, a new
- * session object is created and put also onto the active object list.
- *
- * We use the session field from sp, and we cache rsa->(n|e) in
- * opdata_rsa_(n|e|d)_num, respectively.
- */
-static CK_OBJECT_HANDLE
-pk11_get_public_rsa_key(RSA* rsa, PK11_SESSION *sp)
-	{
-	CK_RV rv;
-	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-	CK_ULONG found;
-	CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
-	CK_KEY_TYPE k_type = CKK_RSA;
-	CK_ULONG ul_key_attr_count = 7;
-	CK_BBOOL rollback = CK_FALSE;
-
-	CK_ATTRIBUTE  a_key_template[] =
-		{
-		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
-		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
-		{CKA_TOKEN, &pk11_false, sizeof (pk11_false)},
-		{CKA_ENCRYPT, &pk11_true, sizeof (pk11_true)},
-		{CKA_VERIFY_RECOVER, &pk11_true, sizeof (pk11_true)},
-		{CKA_MODULUS, (void *)NULL, 0},
-		{CKA_PUBLIC_EXPONENT, (void *)NULL, 0}
-		};
-
-	int i;
-
-	a_key_template[0].pValue = &o_key;
-	a_key_template[1].pValue = &k_type;
-
-	a_key_template[5].ulValueLen = BN_num_bytes(rsa->n);
-	a_key_template[5].pValue = (CK_VOID_PTR)OPENSSL_malloc(
-		(size_t)a_key_template[5].ulValueLen);
-	if (a_key_template[5].pValue == NULL)
-		{
-		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	BN_bn2bin(rsa->n, a_key_template[5].pValue);
-
-	a_key_template[6].ulValueLen = BN_num_bytes(rsa->e);
-	a_key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
-		(size_t)a_key_template[6].ulValueLen);
-	if (a_key_template[6].pValue == NULL)
-		{
-		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	BN_bn2bin(rsa->e, a_key_template[6].pValue);
-
-	/* see find_lock array definition for more info on object locking */
-	LOCK_OBJSTORE(OP_RSA);
-
-	rv = pFuncList->C_FindObjectsInit(sp->session, a_key_template,
-		ul_key_attr_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
-		    PK11_R_FINDOBJECTSINIT, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjects(sp->session, &h_key, 1, &found);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
-		    PK11_R_FINDOBJECTS, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjectsFinal(sp->session);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
-		    PK11_R_FINDOBJECTSFINAL, rv);
-		goto err;
-		}
-
-	if (found == 0)
-		{
-		rv = pFuncList->C_CreateObject(sp->session,
-			a_key_template, ul_key_attr_count, &h_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
-			    PK11_R_CREATEOBJECT, rv);
-			goto err;
-			}
-		}
-
-	if ((sp->opdata_rsa_n_num = BN_dup(rsa->n)) == NULL)
-		{
-		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
-		rollback = CK_TRUE;
-		goto err;
-		}
-
-	if ((sp->opdata_rsa_e_num = BN_dup(rsa->e)) == NULL)
-		{
-		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
-		BN_free(sp->opdata_rsa_n_num);
-		sp->opdata_rsa_n_num = NULL;
-		rollback = CK_TRUE;
-		goto err;
-		}
-
-	/* LINTED: E_CONSTANT_CONDITION */
-	KEY_HANDLE_REFHOLD(h_key, OP_RSA, CK_FALSE, rollback, err);
-	sp->opdata_rsa_pub = rsa;
-
-err:
-	if (rollback)
-		{
-		/*
-		 * We do not care about the return value from C_DestroyObject()
-		 * since we are doing rollback.
-		 */
-		if (found == 0)
-			(void) pFuncList->C_DestroyObject(sp->session, h_key);
-		h_key = CK_INVALID_HANDLE;
-		}
-
-	UNLOCK_OBJSTORE(OP_RSA);
-
-malloc_err:
-	for (i = 5; i <= 6; i++)
-		{
-		if (a_key_template[i].pValue != NULL)
-			{
-			OPENSSL_free(a_key_template[i].pValue);
-			a_key_template[i].pValue = NULL;
-			}
-		}
-
-	return (h_key);
-	}
-
-/*
- * Function similar to pk11_get_public_rsa_key(). In addition to 'n' and 'e'
- * components, it also caches 'd' if present. Note that if RSA keys by reference
- * are used, 'd' is never extracted from the token in which case it would be
- * NULL here.
- */
-static CK_OBJECT_HANDLE
-pk11_get_private_rsa_key(RSA* rsa, PK11_SESSION *sp)
-	{
-	CK_RV rv;
-	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-	int i;
-	CK_ULONG found;
-	CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
-	CK_KEY_TYPE k_type = CKK_RSA;
-	CK_ULONG ul_key_attr_count = 14;
-	CK_BBOOL rollback = CK_FALSE;
-
-	/*
-	 * Both CKA_TOKEN and CKA_SENSITIVE have to be CK_FALSE for session keys
-	 */
-	CK_ATTRIBUTE  a_key_template[] =
-		{
-		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
-		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
-		{CKA_TOKEN, &pk11_false, sizeof (pk11_false)},
-		{CKA_SENSITIVE, &pk11_false, sizeof (pk11_false)},
-		{CKA_DECRYPT, &pk11_true, sizeof (pk11_true)},
-		{CKA_SIGN, &pk11_true, sizeof (pk11_true)},
-		{CKA_MODULUS, (void *)NULL, 0},
-		{CKA_PUBLIC_EXPONENT, (void *)NULL, 0},
-		{CKA_PRIVATE_EXPONENT, (void *)NULL, 0},
-		{CKA_PRIME_1, (void *)NULL, 0},
-		{CKA_PRIME_2, (void *)NULL, 0},
-		{CKA_EXPONENT_1, (void *)NULL, 0},
-		{CKA_EXPONENT_2, (void *)NULL, 0},
-		{CKA_COEFFICIENT, (void *)NULL, 0},
-		};
-
-	a_key_template[0].pValue = &o_key;
-	a_key_template[1].pValue = &k_type;
-
-	/* Put the private key components into the template */
-	if (init_template_value(rsa->n, &a_key_template[6].pValue,
-		&a_key_template[6].ulValueLen) == 0 ||
-	    init_template_value(rsa->e, &a_key_template[7].pValue,
-		&a_key_template[7].ulValueLen) == 0 ||
-	    init_template_value(rsa->d, &a_key_template[8].pValue,
-		&a_key_template[8].ulValueLen) == 0 ||
-	    init_template_value(rsa->p, &a_key_template[9].pValue,
-		&a_key_template[9].ulValueLen) == 0 ||
-	    init_template_value(rsa->q, &a_key_template[10].pValue,
-		&a_key_template[10].ulValueLen) == 0 ||
-	    init_template_value(rsa->dmp1, &a_key_template[11].pValue,
-		&a_key_template[11].ulValueLen) == 0 ||
-	    init_template_value(rsa->dmq1, &a_key_template[12].pValue,
-		&a_key_template[12].ulValueLen) == 0 ||
-	    init_template_value(rsa->iqmp, &a_key_template[13].pValue,
-		&a_key_template[13].ulValueLen) == 0)
-		{
-		PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	/* see find_lock array definition for more info on object locking */
-	LOCK_OBJSTORE(OP_RSA);
-
-	/*
-	 * We are getting the private key but the private 'd' component is NULL.
-	 * That means this is key by reference RSA key. In that case, we can
-	 * use only public components for searching for the private key handle.
-	 */
-	if (rsa->d == NULL)
-		{
-		ul_key_attr_count = 8;
-		/*
-		 * We will perform the search in the token, not in the existing
-		 * session keys.
-		 */
-		a_key_template[2].pValue = &pk11_true;
-		}
-
-	rv = pFuncList->C_FindObjectsInit(sp->session, a_key_template,
-		ul_key_attr_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
-		    PK11_R_FINDOBJECTSINIT, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjects(sp->session, &h_key, 1, &found);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
-		    PK11_R_FINDOBJECTS, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjectsFinal(sp->session);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
-		    PK11_R_FINDOBJECTSFINAL, rv);
-		goto err;
-		}
-
-	if (found == 0)
-		{
-		/*
-		 * We have an RSA structure with 'n'/'e' components only so we
-		 * tried to find the private key in the keystore. If it was
-		 * really a token key we have a problem. Note that for other key
-		 * types we just create a new session key using the private
-		 * components from the RSA structure.
-		 */
-		if (rsa->d == NULL)
-			{
-			PK11err(PK11_F_GET_PRIV_RSA_KEY,
-			    PK11_R_PRIV_KEY_NOT_FOUND);
-			goto err;
-			}
-
-		rv = pFuncList->C_CreateObject(sp->session,
-			a_key_template, ul_key_attr_count, &h_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
-				PK11_R_CREATEOBJECT, rv);
-			goto err;
-			}
-		}
-
-	/*
-	 * When RSA keys by reference code is used, we never extract private
-	 * components from the keystore. In that case 'd' was set to NULL and we
-	 * expect the application to properly cope with that. It is documented
-	 * in openssl(5). In general, if keys by reference are used we expect it
-	 * to be used exclusively using the high level API and then there is no
-	 * problem. If the application expects the private components to be read
-	 * from the keystore then that is not a supported way of usage.
-	 */
-	if (rsa->d != NULL)
-		{
-		if ((sp->opdata_rsa_d_num = BN_dup(rsa->d)) == NULL)
-			{
-			PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
-			rollback = CK_TRUE;
-			goto err;
-			}
-		}
-	else
-		sp->opdata_rsa_d_num = NULL;
-
-	/*
-	 * For the key by reference code, we need public components as well
-	 * since 'd' component is always NULL. For that reason, we always cache
-	 * 'n'/'e' components as well.
-	 */
-	if ((sp->opdata_rsa_n_num = BN_dup(rsa->n)) == NULL)
-		{
-		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
-		sp->opdata_rsa_n_num = NULL;
-		rollback = CK_TRUE;
-		goto err;
-		}
-	if ((sp->opdata_rsa_e_num = BN_dup(rsa->e)) == NULL)
-		{
-		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
-		BN_free(sp->opdata_rsa_n_num);
-		sp->opdata_rsa_n_num = NULL;
-		rollback = CK_TRUE;
-		goto err;
-		}
-
-	/* LINTED: E_CONSTANT_CONDITION */
-	KEY_HANDLE_REFHOLD(h_key, OP_RSA, CK_FALSE, rollback, err);
-	sp->opdata_rsa_priv = rsa;
-
-err:
-	if (rollback)
-		{
-		/*
-		 * We do not care about the return value from C_DestroyObject()
-		 * since we are doing rollback.
-		 */
-		if (found == 0)
-			(void) pFuncList->C_DestroyObject(sp->session, h_key);
-		h_key = CK_INVALID_HANDLE;
-		}
-
-	UNLOCK_OBJSTORE(OP_RSA);
-
-malloc_err:
-	/*
-	 * 6 to 13 entries in the key template are key components.
-	 * They need to be freed upon exit or error.
-	 */
-	for (i = 6; i <= 13; i++)
-		{
-		if (a_key_template[i].pValue != NULL)
-			{
-			(void) memset(a_key_template[i].pValue, 0,
-				a_key_template[i].ulValueLen);
-			OPENSSL_free(a_key_template[i].pValue);
-			a_key_template[i].pValue = NULL;
-			}
-		}
-
-	return (h_key);
-	}
-
-/*
- * Check for cache miss. Objects are cleaned only if we have a full cache miss,
- * meaning that it's a different RSA key pair. Return 1 for cache hit, 0 for
- * cache miss.
- */
-static int
-pk11_check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa)
-	{
-	/*
-	 * Provide protection against RSA structure reuse by making the
-	 * check for cache hit stronger. Only public components of RSA
-	 * key matter here so it is sufficient to compare them with values
-	 * cached in PK11_SESSION structure.
-	 *
-	 * We must check the handle as well since with key by reference, public
-	 * components 'n'/'e' are cached in private keys as well. That means we
-	 * could have a cache hit in a private key when looking for a public
-	 * key. That would not work, you cannot have one PKCS#11 object for
-	 * both data signing and verifying.
-	 */
-	if (sp->opdata_rsa_pub == rsa &&
-	    BN_cmp(sp->opdata_rsa_n_num, rsa->n) == 0 &&
-	    BN_cmp(sp->opdata_rsa_e_num, rsa->e) == 0)
-		{
-		if (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE)
-			return (1);
-		else
-			/*
-			 * No public key object yet but we have the right RSA
-			 * structure with potentially existing private key
-			 * object. We can just create a public object and move
-			 * on with this session structure.
-			 */
-			return (0);
-		}
-
-	/*
-	 * A different RSA key pair was using this session structure previously
-	 * or it's an empty structure. Destroy what we can.
-	 */
-	(void) pk11_destroy_rsa_object_pub(sp, CK_TRUE);
-	(void) pk11_destroy_rsa_object_priv(sp, CK_TRUE);
-	return (0);
-	}
-
-/*
- * Check for cache miss. Objects are cleaned only if we have a full cache miss,
- * meaning that it's a different RSA key pair. Return 1 for cache hit, 0 for
- * cache miss.
- */
-static int
-pk11_check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa)
-	{
-	/*
-	 * Provide protection against RSA structure reuse by making the
-	 * check for cache hit stronger. Comparing public exponent of RSA
-	 * key with value cached in PK11_SESSION structure should
-	 * be sufficient. Note that we want to compare the public component
-	 * since with the keys by reference mechanism, private components are
-	 * not in the RSA structure. Also, see pk11_check_new_rsa_key_pub()
-	 * about why we compare the handle as well.
-	 */
-	if (sp->opdata_rsa_priv == rsa &&
-	    BN_cmp(sp->opdata_rsa_n_num, rsa->n) == 0 &&
-	    BN_cmp(sp->opdata_rsa_e_num, rsa->e) == 0)
-		{
-		if (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE)
-			return (1);
-		else
-			/*
-			 * No private key object yet but we have the right RSA
-			 * structure with potentially existing public key
-			 * object. We can just create a private object and move
-			 * on with this session structure.
-			 */
-			return (0);
-		}
-
-	/*
-	 * A different RSA key pair was using this session structure previously
-	 * or it's an empty structure. Destroy what we can.
-	 */
-	(void) pk11_destroy_rsa_object_priv(sp, CK_TRUE);
-	(void) pk11_destroy_rsa_object_pub(sp, CK_TRUE);
-	return (0);
-	}
-#endif
-
-#ifndef OPENSSL_NO_DSA
-/* The DSA function implementation */
-/* ARGSUSED */
-static int pk11_DSA_init(DSA *dsa)
-	{
-	return (1);
-	}
-
-/* ARGSUSED */
-static int pk11_DSA_finish(DSA *dsa)
-	{
-	return (1);
-	}
-
-
-static DSA_SIG *
-pk11_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
-	{
-	BIGNUM *r = NULL, *s = NULL;
-	int i;
-	DSA_SIG *dsa_sig = NULL;
-
-	CK_RV rv;
-	CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
-	CK_MECHANISM *p_mech = &Mechanism_dsa;
-	CK_OBJECT_HANDLE h_priv_key;
-
-	/*
-	 * The signature is the concatenation of r and s,
-	 * each is 20 bytes long
-	 */
-	unsigned char sigret[DSA_SIGNATURE_LEN];
-	unsigned long siglen = DSA_SIGNATURE_LEN;
-	unsigned int siglen2 = DSA_SIGNATURE_LEN / 2;
-
-	PK11_SESSION *sp = NULL;
-
-	if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
-		{
-		PK11err(PK11_F_DSA_SIGN, PK11_R_MISSING_KEY_COMPONENT);
-		goto ret;
-		}
-
-	i = BN_num_bytes(dsa->q); /* should be 20 */
-	if (dlen > i)
-		{
-		PK11err(PK11_F_DSA_SIGN, PK11_R_INVALID_SIGNATURE_LENGTH);
-		goto ret;
-		}
-
-	if ((sp = pk11_get_session(OP_DSA)) == NULL)
-		goto ret;
-
-	(void) check_new_dsa_key_priv(sp, dsa);
-
-	h_priv_key = sp->opdata_dsa_priv_key;
-	if (h_priv_key == CK_INVALID_HANDLE)
-		h_priv_key = sp->opdata_dsa_priv_key =
-			pk11_get_private_dsa_key((DSA *)dsa,
-			    &sp->opdata_dsa_priv,
-			    &sp->opdata_dsa_priv_num, sp->session);
-
-	if (h_priv_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGNINIT, rv);
-			goto ret;
-			}
-
-			(void) memset(sigret, 0, siglen);
-			rv = pFuncList->C_Sign(sp->session,
-			    (unsigned char *) dgst, dlen, sigret,
-			    (CK_ULONG_PTR) &siglen);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGN, rv);
-			goto ret;
-			}
-		}
-
-
-	if ((s = BN_new()) == NULL)
-		{
-		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
-		goto ret;
-		}
-
-	if ((r = BN_new()) == NULL)
-		{
-		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
-		goto ret;
-		}
-
-	if ((dsa_sig = DSA_SIG_new()) == NULL)
-		{
-		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
-		goto ret;
-		}
-
-	if (BN_bin2bn(sigret, siglen2, r) == NULL ||
-	    BN_bin2bn(&sigret[siglen2], siglen2, s) == NULL)
-		{
-		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
-		goto ret;
-		}
-
-	dsa_sig->r = r;
-	dsa_sig->s = s;
-
-ret:
-	if (dsa_sig == NULL)
-		{
-		if (r != NULL)
-			BN_free(r);
-		if (s != NULL)
-			BN_free(s);
-		}
-
-	pk11_return_session(sp, OP_DSA);
-	return (dsa_sig);
-	}
-
-static int
-pk11_dsa_do_verify(const unsigned char *dgst, int dlen, DSA_SIG *sig,
-	DSA *dsa)
-	{
-	int i;
-	CK_RV rv;
-	int retval = 0;
-	CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
-	CK_MECHANISM *p_mech = &Mechanism_dsa;
-	CK_OBJECT_HANDLE h_pub_key;
-
-	unsigned char sigbuf[DSA_SIGNATURE_LEN];
-	unsigned long siglen = DSA_SIGNATURE_LEN;
-	unsigned long siglen2 = DSA_SIGNATURE_LEN/2;
-
-	PK11_SESSION *sp = NULL;
-
-	if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0)
-		{
-		PK11err(PK11_F_DSA_VERIFY,
-			PK11_R_INVALID_DSA_SIGNATURE_R);
-		goto ret;
-		}
-
-	if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0)
-		{
-		PK11err(PK11_F_DSA_VERIFY,
-			PK11_R_INVALID_DSA_SIGNATURE_S);
-		goto ret;
-		}
-
-	i = BN_num_bytes(dsa->q); /* should be 20 */
-
-	if (dlen > i)
-		{
-		PK11err(PK11_F_DSA_VERIFY,
-			PK11_R_INVALID_SIGNATURE_LENGTH);
-		goto ret;
-		}
-
-	if ((sp = pk11_get_session(OP_DSA)) == NULL)
-		goto ret;
-
-	(void) check_new_dsa_key_pub(sp, dsa);
-
-	h_pub_key = sp->opdata_dsa_pub_key;
-	if (h_pub_key == CK_INVALID_HANDLE)
-		h_pub_key = sp->opdata_dsa_pub_key =
-			pk11_get_public_dsa_key((DSA *)dsa, &sp->opdata_dsa_pub,
-			    &sp->opdata_dsa_pub_num, sp->session);
-
-	if (h_pub_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_VerifyInit(sp->session, p_mech,
-			h_pub_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFYINIT,
-			    rv);
-			goto ret;
-			}
-
-		/*
-		 * The representation of each of the two big numbers could
-		 * be shorter than DSA_SIGNATURE_LEN/2 bytes so we need
-		 * to act accordingly and shift if necessary.
-		 */
-		(void) memset(sigbuf, 0, siglen);
-		BN_bn2bin(sig->r, sigbuf + siglen2 - BN_num_bytes(sig->r));
-		BN_bn2bin(sig->s, &sigbuf[siglen2] + siglen2 -
-		    BN_num_bytes(sig->s));
-
-		rv = pFuncList->C_Verify(sp->session,
-			(unsigned char *) dgst, dlen, sigbuf, (CK_ULONG)siglen);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFY, rv);
-			goto ret;
-			}
-		}
-
-	retval = 1;
-ret:
-
-	pk11_return_session(sp, OP_DSA);
-	return (retval);
-	}
-
-
-/*
- * Create a public key object in a session from a given dsa structure.
- * The *dsa_pub_num pointer is non-NULL for DSA public keys.
- */
-static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa,
-    DSA **key_ptr, BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session)
-	{
-	CK_RV rv;
-	CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
-	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-	CK_ULONG found;
-	CK_KEY_TYPE k_type = CKK_DSA;
-	CK_ULONG ul_key_attr_count = 8;
-	CK_BBOOL rollback = CK_FALSE;
-	int i;
-
-	CK_ATTRIBUTE  a_key_template[] =
-		{
-		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
-		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
-		{CKA_TOKEN, &pk11_false, sizeof (pk11_false)},
-		{CKA_VERIFY, &pk11_true, sizeof (pk11_true)},
-		{CKA_PRIME, (void *)NULL, 0},		/* p */
-		{CKA_SUBPRIME, (void *)NULL, 0},	/* q */
-		{CKA_BASE, (void *)NULL, 0},		/* g */
-		{CKA_VALUE, (void *)NULL, 0}		/* pub_key - y */
-		};
-
-	a_key_template[0].pValue = &o_key;
-	a_key_template[1].pValue = &k_type;
-
-	if (init_template_value(dsa->p, &a_key_template[4].pValue,
-		&a_key_template[4].ulValueLen) == 0 ||
-	    init_template_value(dsa->q, &a_key_template[5].pValue,
-		&a_key_template[5].ulValueLen) == 0 ||
-	    init_template_value(dsa->g, &a_key_template[6].pValue,
-		&a_key_template[6].ulValueLen) == 0 ||
-	    init_template_value(dsa->pub_key, &a_key_template[7].pValue,
-		&a_key_template[7].ulValueLen) == 0)
-		{
-		PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	/* see find_lock array definition for more info on object locking */
-	LOCK_OBJSTORE(OP_DSA);
-	rv = pFuncList->C_FindObjectsInit(session, a_key_template,
-		ul_key_attr_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
-		    PK11_R_FINDOBJECTSINIT, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
-		    PK11_R_FINDOBJECTS, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjectsFinal(session);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
-		    PK11_R_FINDOBJECTSFINAL, rv);
-		goto err;
-		}
-
-	if (found == 0)
-		{
-		rv = pFuncList->C_CreateObject(session,
-			a_key_template, ul_key_attr_count, &h_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
-			    PK11_R_CREATEOBJECT, rv);
-			goto err;
-			}
-		}
-
-	if (dsa_pub_num != NULL)
-		if ((*dsa_pub_num = BN_dup(dsa->pub_key)) == NULL)
-			{
-			PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
-			rollback = CK_TRUE;
-			goto err;
-			}
-
-	/* LINTED: E_CONSTANT_CONDITION */
-	KEY_HANDLE_REFHOLD(h_key, OP_DSA, CK_FALSE, rollback, err);
-	if (key_ptr != NULL)
-		*key_ptr = dsa;
-
-err:
-	if (rollback)
-		{
-		/*
-		 * We do not care about the return value from C_DestroyObject()
-		 * since we are doing rollback.
-		 */
-		if (found == 0)
-			(void) pFuncList->C_DestroyObject(session, h_key);
-		h_key = CK_INVALID_HANDLE;
-		}
-
-	UNLOCK_OBJSTORE(OP_DSA);
-
-malloc_err:
-	for (i = 4; i <= 7; i++)
-		{
-		if (a_key_template[i].pValue != NULL)
-			{
-			OPENSSL_free(a_key_template[i].pValue);
-			a_key_template[i].pValue = NULL;
-			}
-		}
-
-	return (h_key);
-	}
-
-/*
- * Create a private key object in the session from a given dsa structure
- * The *dsa_priv_num pointer is non-NULL for DSA private keys.
- */
-static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa,
-    DSA **key_ptr, BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session)
-	{
-	CK_RV rv;
-	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-	CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
-	int i;
-	CK_ULONG found;
-	CK_KEY_TYPE k_type = CKK_DSA;
-	CK_ULONG ul_key_attr_count = 9;
-	CK_BBOOL rollback = CK_FALSE;
-
-	/*
-	 * Both CKA_TOKEN and CKA_SENSITIVE have to be CK_FALSE for session keys
-	 */
-	CK_ATTRIBUTE  a_key_template[] =
-		{
-		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
-		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
-		{CKA_TOKEN, &pk11_false, sizeof (pk11_false)},
-		{CKA_SENSITIVE, &pk11_false, sizeof (pk11_false)},
-		{CKA_SIGN, &pk11_true, sizeof (pk11_true)},
-		{CKA_PRIME, (void *)NULL, 0},		/* p */
-		{CKA_SUBPRIME, (void *)NULL, 0},	/* q */
-		{CKA_BASE, (void *)NULL, 0},		/* g */
-		{CKA_VALUE, (void *)NULL, 0}		/* priv_key - x */
-		};
-
-	a_key_template[0].pValue = &o_key;
-	a_key_template[1].pValue = &k_type;
-
-	/* Put the private key components into the template */
-	if (init_template_value(dsa->p, &a_key_template[5].pValue,
-		&a_key_template[5].ulValueLen) == 0 ||
-	    init_template_value(dsa->q, &a_key_template[6].pValue,
-		&a_key_template[6].ulValueLen) == 0 ||
-	    init_template_value(dsa->g, &a_key_template[7].pValue,
-		&a_key_template[7].ulValueLen) == 0 ||
-	    init_template_value(dsa->priv_key, &a_key_template[8].pValue,
-		&a_key_template[8].ulValueLen) == 0)
-		{
-		PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	/* see find_lock array definition for more info on object locking */
-	LOCK_OBJSTORE(OP_DSA);
-	rv = pFuncList->C_FindObjectsInit(session, a_key_template,
-		ul_key_attr_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
-		    PK11_R_FINDOBJECTSINIT, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
-		    PK11_R_FINDOBJECTS, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjectsFinal(session);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
-		    PK11_R_FINDOBJECTSFINAL, rv);
-		goto err;
-		}
-
-	if (found == 0)
-		{
-		rv = pFuncList->C_CreateObject(session,
-			a_key_template, ul_key_attr_count, &h_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
-			    PK11_R_CREATEOBJECT, rv);
-			goto err;
-			}
-		}
-
-	if (dsa_priv_num != NULL)
-		if ((*dsa_priv_num = BN_dup(dsa->priv_key)) == NULL)
-			{
-			PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
-			rollback = CK_TRUE;
-			goto err;
-			}
-
-	/* LINTED: E_CONSTANT_CONDITION */
-	KEY_HANDLE_REFHOLD(h_key, OP_DSA, CK_FALSE, rollback, err);
-	if (key_ptr != NULL)
-		*key_ptr = dsa;
-
-err:
-	if (rollback)
-		{
-		/*
-		 * We do not care about the return value from C_DestroyObject()
-		 * since we are doing rollback.
-		 */
-		if (found == 0)
-			(void) pFuncList->C_DestroyObject(session, h_key);
-		h_key = CK_INVALID_HANDLE;
-		}
-
-	UNLOCK_OBJSTORE(OP_DSA);
-
-malloc_err:
-	/*
-	 * 5 to 8 entries in the key template are key components.
-	 * They need to be freed apon exit or error.
-	 */
-	for (i = 5; i <= 8; i++)
-		{
-		if (a_key_template[i].pValue != NULL)
-			{
-			(void) memset(a_key_template[i].pValue, 0,
-				a_key_template[i].ulValueLen);
-			OPENSSL_free(a_key_template[i].pValue);
-			a_key_template[i].pValue = NULL;
-			}
-		}
-
-	return (h_key);
-	}
-
-/*
- * Check for cache miss and clean the object pointer and handle
- * in such case. Return 1 for cache hit, 0 for cache miss.
- */
-static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa)
-	{
-	/*
-	 * Provide protection against DSA structure reuse by making the
-	 * check for cache hit stronger. Only public key component of DSA
-	 * key matters here so it is sufficient to compare it with value
-	 * cached in PK11_SESSION structure.
-	 */
-	if ((sp->opdata_dsa_pub != dsa) ||
-	    (BN_cmp(sp->opdata_dsa_pub_num, dsa->pub_key) != 0))
-		{
-		/*
-		 * We do not check the return value because even in case of
-		 * failure the sp structure will have both key pointer
-		 * and object handle cleaned and pk11_destroy_object()
-		 * reports the failure to the OpenSSL error message buffer.
-		 */
-		(void) pk11_destroy_dsa_object_pub(sp, CK_TRUE);
-		return (0);
-		}
-	return (1);
-	}
-
-/*
- * Check for cache miss and clean the object pointer and handle
- * in such case. Return 1 for cache hit, 0 for cache miss.
- */
-static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa)
-	{
-	/*
-	 * Provide protection against DSA structure reuse by making the
-	 * check for cache hit stronger. Only private key component of DSA
-	 * key matters here so it is sufficient to compare it with value
-	 * cached in PK11_SESSION structure.
-	 */
-	if ((sp->opdata_dsa_priv != dsa) ||
-	    (BN_cmp(sp->opdata_dsa_priv_num, dsa->priv_key) != 0))
-		{
-		/*
-		 * We do not check the return value because even in case of
-		 * failure the sp structure will have both key pointer
-		 * and object handle cleaned and pk11_destroy_object()
-		 * reports the failure to the OpenSSL error message buffer.
-		 */
-		(void) pk11_destroy_dsa_object_priv(sp, CK_TRUE);
-		return (0);
-		}
-	return (1);
-	}
-#endif
-
-
-#ifndef OPENSSL_NO_DH
-/* The DH function implementation */
-/* ARGSUSED */
-static int pk11_DH_init(DH *dh)
-	{
-	return (1);
-	}
-
-/* ARGSUSED */
-static int pk11_DH_finish(DH *dh)
-	{
-	return (1);
-	}
-
-/*
- * Generate DH key-pair.
- *
- * Warning: Unlike OpenSSL's DH_generate_key(3) we ignore dh->priv_key
- * and override it even if it is set. OpenSSL does not touch dh->priv_key
- * if set and just computes dh->pub_key. It looks like PKCS#11 standard
- * is not capable of providing this functionality. This could be a problem
- * for applications relying on OpenSSL's semantics.
- */
-static int pk11_DH_generate_key(DH *dh)
-	{
-	CK_ULONG i;
-	CK_RV rv, rv1;
-	int reuse_mem_len = 0, ret = 0;
-	PK11_SESSION *sp = NULL;
-	CK_BYTE_PTR reuse_mem;
-
-	CK_MECHANISM mechanism = {CKM_DH_PKCS_KEY_PAIR_GEN, NULL_PTR, 0};
-	CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
-	CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
-
-	CK_ULONG ul_pub_key_attr_count = 3;
-	CK_ATTRIBUTE pub_key_template[] =
-		{
-		{CKA_PRIVATE, &pk11_false, sizeof (pk11_false)},
-		{CKA_PRIME, (void *)NULL, 0},
-		{CKA_BASE, (void *)NULL, 0}
-		};
-
-	CK_ULONG ul_priv_key_attr_count = 3;
-	CK_ATTRIBUTE priv_key_template[] =
-		{
-		{CKA_PRIVATE, &pk11_false, sizeof (pk11_false)},
-		{CKA_SENSITIVE, &pk11_false, sizeof (pk11_false)},
-		{CKA_DERIVE, &pk11_true, sizeof (pk11_true)}
-		};
-
-	CK_ULONG pub_key_attr_result_count = 1;
-	CK_ATTRIBUTE pub_key_result[] =
-		{
-		{CKA_VALUE, (void *)NULL, 0}
-		};
-
-	CK_ULONG priv_key_attr_result_count = 1;
-	CK_ATTRIBUTE priv_key_result[] =
-		{
-		{CKA_VALUE, (void *)NULL, 0}
-		};
-
-	pub_key_template[1].ulValueLen = BN_num_bytes(dh->p);
-	if (pub_key_template[1].ulValueLen > 0)
-		{
-		/*
-		 * We must not increase ulValueLen by DH_BUF_RESERVE since that
-		 * could cause the same rounding problem. See definition of
-		 * DH_BUF_RESERVE above.
-		 */
-		pub_key_template[1].pValue =
-			OPENSSL_malloc(pub_key_template[1].ulValueLen +
-			DH_BUF_RESERVE);
-		if (pub_key_template[1].pValue == NULL)
-			{
-			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-
-		i = BN_bn2bin(dh->p, pub_key_template[1].pValue);
-		}
-	else
-		goto err;
-
-	pub_key_template[2].ulValueLen = BN_num_bytes(dh->g);
-	if (pub_key_template[2].ulValueLen > 0)
-		{
-		pub_key_template[2].pValue =
-			OPENSSL_malloc(pub_key_template[2].ulValueLen +
-			DH_BUF_RESERVE);
-		if (pub_key_template[2].pValue == NULL)
-			{
-			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-
-		i = BN_bn2bin(dh->g, pub_key_template[2].pValue);
-		}
-	else
-		goto err;
-
-	/*
-	 * Note: we are only using PK11_SESSION structure for getting
-	 *	 a session handle. The objects created in this function are
-	 *	 destroyed before return and thus not cached.
-	 */
-	if ((sp = pk11_get_session(OP_DH)) == NULL)
-		goto err;
-
-	rv = pFuncList->C_GenerateKeyPair(sp->session,
-	    &mechanism,
-	    pub_key_template,
-	    ul_pub_key_attr_count,
-	    priv_key_template,
-	    ul_priv_key_attr_count,
-	    &h_pub_key,
-	    &h_priv_key);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DH_GEN_KEY, PK11_R_GEN_KEY, rv);
-		goto err;
-		}
-
-	/*
-	 * Reuse the larger memory allocated. We know the larger memory
-	 * should be sufficient for reuse.
-	 */
-	if (pub_key_template[1].ulValueLen > pub_key_template[2].ulValueLen)
-		{
-		reuse_mem = pub_key_template[1].pValue;
-		reuse_mem_len = pub_key_template[1].ulValueLen + DH_BUF_RESERVE;
-		}
-	else
-		{
-		reuse_mem = pub_key_template[2].pValue;
-		reuse_mem_len = pub_key_template[2].ulValueLen + DH_BUF_RESERVE;
-		}
-
-	rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
-		pub_key_result, pub_key_attr_result_count);
-	rv1 = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
-		priv_key_result, priv_key_attr_result_count);
-
-	if (rv != CKR_OK || rv1 != CKR_OK)
-		{
-		rv = (rv != CKR_OK) ? rv : rv1;
-		PK11err_add_data(PK11_F_DH_GEN_KEY,
-		    PK11_R_GETATTRIBUTVALUE, rv);
-		goto err;
-		}
-
-	if (((CK_LONG) pub_key_result[0].ulValueLen) <= 0 ||
-		((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
-		{
-		PK11err(PK11_F_DH_GEN_KEY, PK11_R_GETATTRIBUTVALUE);
-		goto err;
-		}
-
-	/* Reuse the memory allocated */
-	pub_key_result[0].pValue = reuse_mem;
-	pub_key_result[0].ulValueLen = reuse_mem_len;
-
-	rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
-		pub_key_result, pub_key_attr_result_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DH_GEN_KEY,
-		    PK11_R_GETATTRIBUTVALUE, rv);
-		goto err;
-		}
-
-	if (pub_key_result[0].type == CKA_VALUE)
-		{
-		if (dh->pub_key == NULL)
-			if ((dh->pub_key = BN_new()) == NULL)
-				{
-				PK11err(PK11_F_DH_GEN_KEY,
-					PK11_R_MALLOC_FAILURE);
-				goto err;
-				}
-		dh->pub_key = BN_bin2bn(pub_key_result[0].pValue,
-			pub_key_result[0].ulValueLen, dh->pub_key);
-		if (dh->pub_key == NULL)
-			{
-			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-		}
-
-	/* Reuse the memory allocated */
-	priv_key_result[0].pValue = reuse_mem;
-	priv_key_result[0].ulValueLen = reuse_mem_len;
-
-	rv = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
-		priv_key_result, priv_key_attr_result_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DH_GEN_KEY,
-		    PK11_R_GETATTRIBUTVALUE, rv);
-		goto err;
-		}
-
-	if (priv_key_result[0].type == CKA_VALUE)
-		{
-		if (dh->priv_key == NULL)
-			if ((dh->priv_key = BN_new()) == NULL)
-				{
-				PK11err(PK11_F_DH_GEN_KEY,
-					PK11_R_MALLOC_FAILURE);
-				goto err;
-				}
-		dh->priv_key = BN_bin2bn(priv_key_result[0].pValue,
-			priv_key_result[0].ulValueLen, dh->priv_key);
-		if (dh->priv_key == NULL)
-			{
-			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-		}
-
-	ret = 1;
-
-err:
-
-	if (h_pub_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_DestroyObject(sp->session, h_pub_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_DH_GEN_KEY,
-			    PK11_R_DESTROYOBJECT, rv);
-			}
-		}
-
-	if (h_priv_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_DestroyObject(sp->session, h_priv_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_DH_GEN_KEY,
-			    PK11_R_DESTROYOBJECT, rv);
-			}
-		}
-
-	for (i = 1; i <= 2; i++)
-		{
-		if (pub_key_template[i].pValue != NULL)
-			{
-			OPENSSL_free(pub_key_template[i].pValue);
-			pub_key_template[i].pValue = NULL;
-			}
-		}
-
-	pk11_return_session(sp, OP_DH);
-	return (ret);
-	}
-
-static int pk11_DH_compute_key(unsigned char *key, const BIGNUM *pub_key,
-	DH *dh)
-	{
-	int i;
-	CK_MECHANISM mechanism = {CKM_DH_PKCS_DERIVE, NULL_PTR, 0};
-	CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
-	CK_KEY_TYPE key_type = CKK_GENERIC_SECRET;
-	CK_OBJECT_HANDLE h_derived_key = CK_INVALID_HANDLE;
-	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-
-	CK_ULONG ul_priv_key_attr_count = 2;
-	CK_ATTRIBUTE priv_key_template[] =
-		{
-		{CKA_CLASS, (void*) NULL, sizeof (key_class)},
-		{CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
-		};
-
-	CK_ULONG priv_key_attr_result_count = 1;
-	CK_ATTRIBUTE priv_key_result[] =
-		{
-		{CKA_VALUE, (void *)NULL, 0}
-		};
-
-	CK_RV rv;
-	int ret = -1;
-	PK11_SESSION *sp = NULL;
-
-	if (dh->priv_key == NULL)
-		goto err;
-
-	priv_key_template[0].pValue = &key_class;
-	priv_key_template[1].pValue = &key_type;
-
-	if ((sp = pk11_get_session(OP_DH)) == NULL)
-		goto err;
-
-	mechanism.ulParameterLen = BN_num_bytes(pub_key);
-	mechanism.pParameter = OPENSSL_malloc(mechanism.ulParameterLen);
-	if (mechanism.pParameter == NULL)
-		{
-		PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
-		goto err;
-		}
-	BN_bn2bin(pub_key, mechanism.pParameter);
-
-	(void) check_new_dh_key(sp, dh);
-
-	h_key = sp->opdata_dh_key;
-	if (h_key == CK_INVALID_HANDLE)
-		h_key = sp->opdata_dh_key =
-			pk11_get_dh_key((DH*) dh, &sp->opdata_dh,
-			    &sp->opdata_dh_priv_num, sp->session);
-
-	if (h_key == CK_INVALID_HANDLE)
-		{
-		PK11err(PK11_F_DH_COMP_KEY, PK11_R_CREATEOBJECT);
-		goto err;
-		}
-
-	rv = pFuncList->C_DeriveKey(sp->session,
-	    &mechanism,
-	    h_key,
-	    priv_key_template,
-	    ul_priv_key_attr_count,
-	    &h_derived_key);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_DERIVEKEY, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
-	    priv_key_result, priv_key_attr_result_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
-		    rv);
-		goto err;
-		}
-
-	if (((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
-		{
-		PK11err(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE);
-		goto err;
-		}
-	priv_key_result[0].pValue =
-		OPENSSL_malloc(priv_key_result[0].ulValueLen);
-	if (!priv_key_result[0].pValue)
-		{
-		PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
-		goto err;
-		}
-
-	rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
-		priv_key_result, priv_key_attr_result_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
-		    rv);
-		goto err;
-		}
-
-	/*
-	 * OpenSSL allocates the output buffer 'key' which is the same
-	 * length of the public key. It is long enough for the derived key
-	 */
-	if (priv_key_result[0].type == CKA_VALUE)
-		{
-		/*
-		 * CKM_DH_PKCS_DERIVE mechanism is not supposed to strip
-		 * leading zeros from a computed shared secret. However,
-		 * OpenSSL always did it so we must do the same here. The
-		 * vagueness of the spec regarding leading zero bytes was
-		 * finally cleared with TLS 1.1 (RFC 4346) saying that leading
-		 * zeros are stripped before the computed data is used as the
-		 * pre-master secret.
-		 */
-		for (i = 0; i < priv_key_result[0].ulValueLen; ++i)
-			{
-			if (((char *)priv_key_result[0].pValue)[i] != 0)
-				break;
-			}
-
-		(void) memcpy(key, ((char *)priv_key_result[0].pValue) + i,
-			priv_key_result[0].ulValueLen - i);
-		ret = priv_key_result[0].ulValueLen - i;
-		}
-
-err:
-
-	if (h_derived_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_DestroyObject(sp->session, h_derived_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_DH_COMP_KEY,
-			    PK11_R_DESTROYOBJECT, rv);
-			}
-		}
-	if (priv_key_result[0].pValue)
-		{
-		OPENSSL_free(priv_key_result[0].pValue);
-		priv_key_result[0].pValue = NULL;
-		}
-
-	if (mechanism.pParameter)
-		{
-		OPENSSL_free(mechanism.pParameter);
-		mechanism.pParameter = NULL;
-		}
-
-	pk11_return_session(sp, OP_DH);
-	return (ret);
-	}
-
-
-static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh,
-	DH **key_ptr, BIGNUM **dh_priv_num, CK_SESSION_HANDLE session)
-	{
-	CK_RV rv;
-	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-	CK_OBJECT_CLASS class = CKO_PRIVATE_KEY;
-	CK_KEY_TYPE key_type = CKK_DH;
-	CK_ULONG found;
-	CK_BBOOL rollback = CK_FALSE;
-	int i;
-
-	CK_ULONG ul_key_attr_count = 7;
-	CK_ATTRIBUTE key_template[] =
-		{
-		{CKA_CLASS, (void*) NULL, sizeof (class)},
-		{CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
-		{CKA_DERIVE, &pk11_true, sizeof (pk11_true)},
-		{CKA_PRIVATE, &pk11_false, sizeof (pk11_false)},
-		{CKA_PRIME, (void *) NULL, 0},
-		{CKA_BASE, (void *) NULL, 0},
-		{CKA_VALUE, (void *) NULL, 0},
-		};
-
-	key_template[0].pValue = &class;
-	key_template[1].pValue = &key_type;
-
-	key_template[4].ulValueLen = BN_num_bytes(dh->p);
-	key_template[4].pValue = (CK_VOID_PTR)OPENSSL_malloc(
-		(size_t)key_template[4].ulValueLen);
-	if (key_template[4].pValue == NULL)
-		{
-		PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	BN_bn2bin(dh->p, key_template[4].pValue);
-
-	key_template[5].ulValueLen = BN_num_bytes(dh->g);
-	key_template[5].pValue = (CK_VOID_PTR)OPENSSL_malloc(
-		(size_t)key_template[5].ulValueLen);
-	if (key_template[5].pValue == NULL)
-		{
-		PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	BN_bn2bin(dh->g, key_template[5].pValue);
-
-	key_template[6].ulValueLen = BN_num_bytes(dh->priv_key);
-	key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
-		(size_t)key_template[6].ulValueLen);
-	if (key_template[6].pValue == NULL)
-		{
-		PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	BN_bn2bin(dh->priv_key, key_template[6].pValue);
-
-	/* see find_lock array definition for more info on object locking */
-	LOCK_OBJSTORE(OP_DH);
-	rv = pFuncList->C_FindObjectsInit(session, key_template,
-		ul_key_attr_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSINIT, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTS, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjectsFinal(session);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSFINAL,
-		    rv);
-		goto err;
-		}
-
-	if (found == 0)
-		{
-		rv = pFuncList->C_CreateObject(session,
-			key_template, ul_key_attr_count, &h_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_CREATEOBJECT,
-			    rv);
-			goto err;
-			}
-		}
-
-	if (dh_priv_num != NULL)
-		if ((*dh_priv_num = BN_dup(dh->priv_key)) == NULL)
-			{
-			PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
-			rollback = CK_TRUE;
-			goto err;
-			}
-
-	/* LINTED: E_CONSTANT_CONDITION */
-	KEY_HANDLE_REFHOLD(h_key, OP_DH, CK_FALSE, rollback, err);
-	if (key_ptr != NULL)
-		*key_ptr = dh;
-
-err:
-	if (rollback)
-		{
-		/*
-		 * We do not care about the return value from C_DestroyObject()
-		 * since we are doing rollback.
-		 */
-		if (found == 0)
-			(void) pFuncList->C_DestroyObject(session, h_key);
-		h_key = CK_INVALID_HANDLE;
-		}
-
-	UNLOCK_OBJSTORE(OP_DH);
-
-malloc_err:
-	for (i = 4; i <= 6; i++)
-		{
-		if (key_template[i].pValue != NULL)
-			{
-			OPENSSL_free(key_template[i].pValue);
-			key_template[i].pValue = NULL;
-			}
-		}
-
-	return (h_key);
-	}
-
-/*
- * Check for cache miss and clean the object pointer and handle
- * in such case. Return 1 for cache hit, 0 for cache miss.
- *
- * Note: we rely on pk11_destroy_dh_key_objects() to set sp->opdata_dh
- *       to CK_INVALID_HANDLE even when it fails to destroy the object.
- */
-static int check_new_dh_key(PK11_SESSION *sp, DH *dh)
-	{
-	/*
-	 * Provide protection against DH structure reuse by making the
-	 * check for cache hit stronger. Private key component of DH key
-	 * is unique so it is sufficient to compare it with value cached
-	 * in PK11_SESSION structure.
-	 */
-	if ((sp->opdata_dh != dh) ||
-	    (BN_cmp(sp->opdata_dh_priv_num, dh->priv_key) != 0))
-		{
-		/*
-		 * We do not check the return value because even in case of
-		 * failure the sp structure will have both key pointer
-		 * and object handle cleaned and pk11_destroy_object()
-		 * reports the failure to the OpenSSL error message buffer.
-		 */
-		(void) pk11_destroy_dh_object(sp, CK_TRUE);
-		return (0);
-		}
-	return (1);
-	}
-#endif
-
-/*
- * Local function to simplify key template population
- * Return 0 -- error, 1 -- no error
- */
-static int
-init_template_value(BIGNUM *bn, CK_VOID_PTR *p_value,
-	CK_ULONG *ul_value_len)
-	{
-	CK_ULONG len;
-
-	/*
-	 * This function can be used on non-initialized BIGNUMs. It is easier to
-	 * check that here than individually in the callers.
-	 */
-	if (bn != NULL)
-		len = BN_num_bytes(bn);
-
-	if (bn == NULL || len == 0)
-		return (1);
-
-	*ul_value_len = len;
-	*p_value = (CK_VOID_PTR)OPENSSL_malloc((size_t)*ul_value_len);
-	if (*p_value == NULL)
-		return (0);
-
-	BN_bn2bin(bn, *p_value);
-
-	return (1);
-	}
-
-static void
-attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn)
-	{
-		if (attr->ulValueLen > 0)
-			*bn = BN_bin2bn(attr_data, attr->ulValueLen, NULL);
-	}
-
-/*
- * Find one object in the token. It is an error if we can not find the object or
- * if we find more objects based on the template we got.
- *
- * Returns:
- *	1 OK
- *	0 no object or more than 1 object found
- */
-static int
-find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
-    CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey)
-	{
-	CK_RV rv;
-	CK_ULONG objcnt;
-
-	LOCK_OBJSTORE(op);
-	if ((rv = pFuncList->C_FindObjectsInit(s, ptempl, nattr)) != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_FIND_ONE_OBJECT,
-		    PK11_R_FINDOBJECTSINIT, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjects(s, pkey, 1, &objcnt);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_FIND_ONE_OBJECT, PK11_R_FINDOBJECTS,
-		    rv);
-		goto err;
-		}
-
-	if (objcnt > 1)
-		{
-		PK11err(PK11_F_FIND_ONE_OBJECT,
-		    PK11_R_MORE_THAN_ONE_OBJECT_FOUND);
-		goto err;
-		}
-	else
-		if (objcnt == 0)
-			{
-			PK11err(PK11_F_FIND_ONE_OBJECT, PK11_R_NO_OBJECT_FOUND);
-			goto err;
-			}
-
-	(void) pFuncList->C_FindObjectsFinal(s);
-	UNLOCK_OBJSTORE(op);
-	return (1);
-err:
-	UNLOCK_OBJSTORE(op);
-	return (0);
-	}
-
-/*
- * OpenSSL 1.0.0 introduced ENGINE API for the PKEY EVP functions. Sadly,
- * "openssl dgst -dss1 ..." now uses a new function EVP_DigestSignInit() which
- * internally needs a PKEY method for DSA even when in the engine. So, to avoid
- * a regression when moving from 0.9.8 to 1.0.0, we use an internal OpenSSL
- * structure for the DSA PKEY methods to make it work. It is a future project to
- * make it work with HW acceleration.
- *
- * Note that at the time of 1.0.0d release there is no documentation as to how
- * the PKEY EVP functions are to be implemented in an engine. There is only one
- * engine shipped with 1.0.0d that uses the PKEY EVP methods, the GOST engine.
- * It was used as an example when fixing the above mentioned regression problem.
- */
-int
-pk11_engine_pkey_methods(ENGINE *e, EVP_PKEY_METHOD **pmeth, const int **nids,
-    int nid)
-	{
-	if (pmeth == NULL)
-		{
-		*nids = pk11_pkey_meth_nids;
-		return (1);
-		}
-
-	switch (nid)
-		{
-		case NID_dsa:
-			*pmeth = (EVP_PKEY_METHOD *)EVP_PKEY_meth_find(nid);
-			return (1);
-		}
-
-	/* Error branch. */
-	*pmeth = NULL;
-	return (0);
-	}
-
-#endif	/* OPENSSL_NO_HW_PK11 */
-#endif	/* OPENSSL_NO_HW */
--- a/components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_uri.c	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,888 +0,0 @@
-/*
- * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
- *
- */
-
-/*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    [email protected].
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <strings.h>
-#include <libgen.h>
-#include <pthread.h>
-#include <assert.h>
-#include <errno.h>
-
-#include <openssl/crypto.h>
-
-#ifndef OPENSSL_NO_HW
-#ifndef OPENSSL_NO_HW_PK11
-
-#include <security/cryptoki.h>
-#include <security/pkcs11.h>
-#include "e_pk11.h"
-#include "e_pk11_uri.h"
-
-/*
- * The keystore used is always from the pubkey slot so we need to know which one
- * was selected so that we can get the information needed for the URI
- * processing.
- */
-extern CK_SLOT_ID pubkey_SLOTID;
-extern CK_FUNCTION_LIST_PTR pFuncList;
-
-/*
- * Cached PIN so that child can use it during the re-login. Note that we do not
- * cache the PIN by default.
- */
-static char *token_pin;
-
-static int mlock_pin_in_memory(char *pin);
-static char *run_askpass(char *dialog);
-
-/*
- * Get the PIN. Either run the command and use its standard output as a PIN to
- * fill in the PKCS11 URI structure, or read the PIN from the terminal. Using
- * the external command is of higher precedence. The memory for PIN is allocated
- * in this function and the PIN is always NULL terminated. The caller must take
- * care of freeing the memory used for the PIN. The maximum PIN length accepted
- * is PK11_MAX_PIN_LEN.
- *
- * The function is used also during the re-initialization of the engine after
- * the fork.
- *
- * The function must not be called under the protection of the mutex "uri_lock"
- * because the lock is acquired in the prefork function.
- *
- * Returns:
- *	0 in case of troubles (and sets "*pin" to NULL)
- *	1 if we got the PIN
- */
-#define	EXEC_SPEC	"exec:"
-#define	BUILTIN_SPEC	"builtin"
-int
-pk11_get_pin(char *dialog, char **pin)
-	{
-	/* Initialize as an error. */
-	*pin = NULL;
-
-	if (strcmp(dialog, BUILTIN_SPEC) == 0)
-		{
-		/* The getpassphrase() function is not MT safe. */
-		(void) pthread_mutex_lock(uri_lock);
-		/* Note that OpenSSL is not localized at all. */
-		*pin = getpassphrase("Enter token PIN: ");
-		if (*pin == NULL)
-			{
-			PK11err(PK11_F_GET_PIN, PK11_R_COULD_NOT_READ_PIN);
-			(void) pthread_mutex_unlock(uri_lock);
-			goto err;
-			}
-		else
-			{
-			char *pw;
-
-			/*
-			 * getpassphrase() uses an internal  buffer to hold the
-			 * entered password. Note that it terminates the buffer
-			 * with '\0'.
-			 */
-			if ((pw = strdup(*pin)) == NULL)
-				{
-				PK11err(PK11_F_GET_PIN, PK11_R_MALLOC_FAILURE);
-				(void) pthread_mutex_unlock(uri_lock);
-				goto err;
-				}
-			/* Zero the internal buffer to get rid of the PIN. */
-			memset(*pin, 0, strlen(*pin));
-			*pin = pw;
-			(void) pthread_mutex_unlock(uri_lock);
-			}
-		}
-	else
-		{
-		/*
-		 * This is the "exec:" case. We will get the PIN from the output
-		 * of an external command.
-		 */
-		if (strncmp(dialog, EXEC_SPEC, strlen(EXEC_SPEC)) == 0)
-			{
-			dialog += strlen(EXEC_SPEC);
-			if ((*pin = run_askpass(dialog)) == NULL)
-				goto err;
-			}
-		else
-			{
-			/*
-			 * Invalid specification in the passphrasedialog
-			 * keyword.
-			 */
-			PK11err(PK11_F_GET_PIN, PK11_R_BAD_PASSPHRASE_SPEC);
-			goto err;
-			}
-		}
-
-	return (1);
-err:
-	return (0);
-	}
-
-/*
- * Process the PKCS#11 URI and get the PIN. It uses information from the
- * passphrasedialog keyword to get the PIN. If passphrasedialog is not present
- * it is not considered an error since it depends on the token attributes
- * whether C_Login() is required. The function expects an allocated 'uri_struct'
- * structure.
- *
- * Returns:
- *	0 if URI is not valid at all, or if we could not get the PIN
- * 	1 if all is OK
- *	2 if the URI is not the PKCS#11 URI. In that case, put the string
- *	pointer to the filename to "*file". Note that the pointer just points
- *	inside of the "uristr", possibly skipping the file:// prefix if present.
- */
-int
-pk11_process_pkcs11_uri(const char *uristr, pkcs11_uri *uri_struct,
-	const char **file)
-	{
-	char *uristr2, *l1, *l2, *tok, *name;
-
-	/* Check the "file://" case. */
-	if (strncmp(uristr, FILE_URI_PREFIX, strlen(FILE_URI_PREFIX)) == 0)
-		{
-		*file = uristr + strlen(FILE_URI_PREFIX);
-		return (2);
-		}
-
-	/*  This is the "pkcs11:" case. */
-	if (strncmp(uristr, PK11_URI_PREFIX, strlen(PK11_URI_PREFIX)) != 0)
-		{
-		/* Not PKCS#11 URI at all, could be a filename. */
-		*file = (const char *)uristr;
-		return (2);
-		}
-	else
-		{
-		/* Dup the string and skip over the pkcs11: prefix then. */
-		uristr2 = strdup(uristr + strlen(PK11_URI_PREFIX));
-		if (uristr2 == NULL)
-			{
-			PK11err(PK11_F_CHECK_TOKEN_ATTRS,
-			    PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-		}
-
-	/* Initialize the structure. */
-	memset(uri_struct, 0, sizeof (*uri_struct));
-
-	/*
-	 * Using strtok_r() would silently skip over multiple semicolons. We
-	 * must check that before moving on. We must also avoid ';' as the first
-	 * and the last character in the URI.
-	 */
-	if (strstr(uristr2, ";;") != NULL || uristr2[0] == ';' ||
-	    (strlen(uristr2) > 0 && uristr2[strlen(uristr2) - 1] == ';'))
-		goto bad_uri;
-
-	tok = strtok_r(uristr2, ";", &l1);
-	for (; tok != NULL; tok = strtok_r(NULL, ";", &l1))
-		{
-		/* "tok" is not empty so there will be something in "name". */
-		name = strtok_r(tok, "=", &l2);
-		/* Check whether there is '=' at all. */
-		if (l2 == NULL)
-			goto bad_uri;
-
-		/*
-		 * Fill out the URI structure. We do not accept duplicit
-		 * attributes.
-		 */
-		if (strcmp(name, PK11_TOKEN) == 0)
-			{
-			if (uri_struct->token == NULL)
-				{
-				if ((uri_struct->token = strdup(l2)) == NULL)
-					goto no_mem;
-				}
-			else
-				goto bad_uri;
-			}
-		else if (strcmp(name, PK11_MANUF) == 0)
-			{
-			if (uri_struct->manuf == NULL)
-				{
-				if ((uri_struct->manuf = strdup(l2)) == NULL)
-					goto no_mem;
-				}
-			else
-				goto bad_uri;
-			}
-		else if (strcmp(name, PK11_SERIAL) == 0)
-			{
-			if (uri_struct->serial == NULL)
-				{
-				if ((uri_struct->serial = strdup(l2)) == NULL)
-					goto no_mem;
-				}
-			else
-				goto bad_uri;
-			}
-		else if (strcmp(name, PK11_MODEL) == 0)
-			{
-			if (uri_struct->model == NULL)
-				{
-				if ((uri_struct->model = strdup(l2)) == NULL)
-					goto no_mem;
-				}
-			else
-				goto bad_uri;
-			}
-		else if (strcmp(name, PK11_OBJECT) == 0)
-			{
-			if (uri_struct->object == NULL)
-				{
-				if ((uri_struct->object = strdup(l2)) == NULL)
-					goto no_mem;
-				}
-			else
-				goto bad_uri;
-			}
-		else if (strcmp(name, PK11_OBJECTTYPE) == 0)
-			{
-			if (uri_struct->objecttype == NULL)
-				{
-				uri_struct->objecttype = strdup(l2);
-				if (uri_struct->objecttype == NULL)
-					goto no_mem;
-				}
-			else
-				goto bad_uri;
-			}
-		else if (strcmp(name, PK11_ASKPASS) == 0)
-			{
-			if (uri_struct->askpass == NULL)
-				{
-				if ((uri_struct->askpass = strdup(l2)) == NULL)
-					goto no_mem;
-				}
-			else
-				goto bad_uri;
-			}
-		else
-			goto bad_uri;
-		}
-
-	/* The "object" token is mandatory in the PKCS#11 URI. */
-	if (uri_struct->object == NULL)
-		{
-		PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_MISSING_OBJECT_LABEL);
-		goto err;
-		}
-
-	free(uristr2);
-	return (1);
-bad_uri:
-	PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_INVALID_PKCS11_URI);
-	if (uristr2 != NULL)
-		free(uristr2);
-	return (0);
-no_mem:
-	PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_MALLOC_FAILURE);
-err:
-	pk11_free_pkcs11_uri(uri_struct, CK_FALSE);
-	if (uristr2 != NULL)
-		free(uristr2);
-	return (0);
-	}
-
-/*
- * Free the PKCS11 URI structure and anything that might be inside.
- */
-void
-pk11_free_pkcs11_uri(pkcs11_uri *uri_struct, CK_BBOOL free_uri_itself)
-	{
-	if (uri_struct->token != NULL)
-		free(uri_struct->token);
-	if (uri_struct->manuf != NULL)
-		free(uri_struct->manuf);
-	if (uri_struct->serial != NULL)
-		free(uri_struct->serial);
-	if (uri_struct->model != NULL)
-		free(uri_struct->model);
-	if (uri_struct->object != NULL)
-		free(uri_struct->object);
-	if (uri_struct->objecttype != NULL)
-		free(uri_struct->objecttype);
-	if (uri_struct->askpass != NULL)
-		free(uri_struct->askpass);
-
-	if (free_uri_itself == CK_TRUE)
-		OPENSSL_free(uri_struct);
-	}
-
-/*
- * While our keystore is always the one used by the pubkey slot (which is
- * usually the Metaslot) we must make sure that those URI attributes that
- * specify the keystore match the real attributes of our slot keystore. Note
- * that one can use the METASLOT_OBJECTSTORE_TOKEN environment variable to
- * change the Metaslot's keystore from the softtoken to something else (see
- * libpkcs11(3LIB)). The user might want to use such attributes in the PKCS#11
- * URI to make sure that the intended keystore is used.
- *
- * Returns:
- *	1 on success
- *	0 on failure
- */
-int
-pk11_check_token_attrs(pkcs11_uri *uri_struct)
-	{
-	CK_RV rv;
-	static CK_TOKEN_INFO_PTR token_info = NULL;
-
-	(void) pthread_mutex_lock(uri_lock);
-	if (token_info == NULL)
-		{
-		token_info = OPENSSL_malloc(sizeof (CK_TOKEN_INFO));
-		if (token_info == NULL)
-			{
-			PK11err(PK11_F_CHECK_TOKEN_ATTRS,
-			    PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-
-		rv = pFuncList->C_GetTokenInfo(pubkey_SLOTID, token_info);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_CHECK_TOKEN_ATTRS,
-			    PK11_R_GETTOKENINFO, rv);
-			goto err;
-			}
-		}
-
-	if (uri_struct->token != NULL)
-		if (strncmp(uri_struct->token, (char *)token_info->label,
-		    strlen(uri_struct->token) > 32 ? 32 :
-		    strlen(uri_struct->token)) != 0)
-			{
-			goto urierr;
-			}
-
-	if (uri_struct->manuf != NULL)
-		if (strncmp(uri_struct->manuf,
-		    (char *)token_info->manufacturerID,
-		    strlen(uri_struct->manuf) > 32 ? 32 :
-		    strlen(uri_struct->manuf)) != 0)
-			goto urierr;
-
-	if (uri_struct->model != NULL)
-		if (strncmp(uri_struct->model, (char *)token_info->model,
-		    strlen(uri_struct->model) > 16 ? 16 :
-		    strlen(uri_struct->model)) != 0)
-			goto urierr;
-
-	if (uri_struct->serial != NULL)
-		if (strncmp(uri_struct->serial,
-		    (char *)token_info->serialNumber,
-		    strlen(uri_struct->serial) > 16 ? 16 :
-		    strlen(uri_struct->serial)) != 0)
-			goto urierr;
-
-	(void) pthread_mutex_unlock(uri_lock);
-	return (1);
-
-urierr:
-	PK11err(PK11_F_CHECK_TOKEN_ATTRS, PK11_R_TOKEN_ATTRS_DO_NOT_MATCH);
-	/* Correct error already set above for the "err" label. */
-err:
-	(void) pthread_mutex_unlock(uri_lock);
-	return (0);
-	}
-
-/*
- * Return the process PIN caching policy. We initialize it just once so if the
- * process change OPENSSL_PKCS11_PIN_CACHING_POLICY during the operation it will
- * not have any affect on the policy.
- *
- * We assume that the "uri_lock" mutex is already locked.
- *
- * Returns the caching policy number.
- */
-int
-pk11_get_pin_caching_policy(void)
-	{
-	char *value = NULL;
-	static int policy = POLICY_NOT_INITIALIZED;
-
-	if (policy != POLICY_NOT_INITIALIZED)
-		return (policy);
-
-	value = getenv("OPENSSL_PKCS11_PIN_CACHING_POLICY");
-
-	if (value == NULL || strcmp(value, "none") == 0)
-		{
-		policy = POLICY_NONE;
-		goto done;
-		}
-
-	if (strcmp(value, "memory") == 0)
-		{
-		policy = POLICY_MEMORY;
-		goto done;
-		}
-
-	if (strcmp(value, "mlocked-memory") == 0)
-		{
-		policy = POLICY_MLOCKED_MEMORY;
-		goto done;
-		}
-
-	return (POLICY_WRONG_VALUE);
-done:
-	return (policy);
-	}
-
-/*
- * Cache the PIN in memory once. We already know that we have either "memory" or
- * "mlocked-memory" keyword correctly set.
- *
- * Returns:
- *	1 on success
- *	0 on failure
- */
-int
-pk11_cache_pin(char *pin)
-	{
-	(void) pthread_mutex_lock(uri_lock);
-	/* We set the PIN only once since all URIs must have it the same. */
-	if (token_pin != NULL)
-		goto ok;
-
-	if (pk11_get_pin_caching_policy() == POLICY_MEMORY)
-		{
-		if ((token_pin = strdup(pin)) == NULL)
-			{
-			PK11err(PK11_F_CACHE_PIN, PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-		}
-	else
-		{
-		if (pk11_get_pin_caching_policy() == POLICY_MLOCKED_MEMORY)
-			{
-			if (mlock_pin_in_memory(pin) == 0)
-				goto err;
-			}
-		}
-
-ok:
-	(void) pthread_mutex_unlock(uri_lock);
-	return (1);
-err:
-	(void) pthread_mutex_unlock(uri_lock);
-	return (0);
-	}
-
-/*
- * Cache the PIN in mlock(3C)ed memory. If mlock(3C) fails we will not resort to
- * the normal memory caching.
- *
- * Note that this function must be called under the protection of the "uri_lock"
- * mutex.
- *
- * Returns:
- *	1 on success
- *	0 on failure
- */
-static int
-mlock_pin_in_memory(char *pin)
-	{
-	void *addr = NULL;
-	long pagesize = 0;
-
-	/* mlock(3C) locks pages so we need one whole page for the PIN. */
-	if ((pagesize = sysconf(_SC_PAGESIZE)) == -1)
-		{
-		PK11err(PK11_F_MLOCK_PIN_IN_MEMORY, PK11_R_SYSCONF_FAILED);
-		goto err;
-		}
-
-	/* This will ensure we have a page aligned pointer... */
-	if ((addr = mmap(0, pagesize, PROT_READ | PROT_WRITE,
-	    MAP_PRIVATE | MAP_ANON, -1, 0)) == MAP_FAILED)
-		{
-		PK11err(PK11_F_MLOCK_PIN_IN_MEMORY, PK11_R_MMAP_FAILED);
-		goto err;
-		}
-
-	/* ...because "addr" must be page aligned here. */
-	if (mlock(addr, pagesize) == -1)
-		{
-		/*
-		 * Missing the PRIV_PROC_LOCK_MEMORY privilege might be a common
-		 * problem so distinguish this situation from other issues.
-		 */
-		if (errno == EPERM)
-			PK11err(PK11_F_MLOCK_PIN_IN_MEMORY,
-			    PK11_R_PRIV_PROC_LOCK_MEMORY_MISSING);
-		else
-			PK11err(PK11_F_MLOCK_PIN_IN_MEMORY,
-			    PK11_R_MLOCK_FAILED);
-
-		/*
-		 * We already have a problem here so there is no need to check
-		 * that we could unmap the page. The PIN is not there yet
-		 * anyway.
-		 */
-		(void) munmap(addr, pagesize);
-		goto err;
-		}
-
-	/* Copy the PIN to the mlocked memory. */
-	token_pin = (char *)addr;
-	strlcpy(token_pin, pin, PK11_MAX_PIN_LEN + 1);
-	return (1);
-err:
-	return (0);
-	}
-
-/*
- * Log in to the keystore if we are supposed to do that at all. Take care of
- * reading and caching the PIN etc. Log in only once even when called from
- * multiple threads.
- *
- * Returns:
- *	1 on success
- *	0 on failure
- */
-int
-pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
-    pkcs11_uri *uri_struct, CK_BBOOL is_private)
-	{
-	CK_RV rv;
-
-	if ((pubkey_token_flags & CKF_TOKEN_INITIALIZED) == 0)
-		{
-		PK11err(PK11_F_TOKEN_LOGIN,
-		    PK11_R_TOKEN_NOT_INITIALIZED);
-		goto err;
-		}
-
-	/*
-	 * If login is required or needed but the PIN has not been even
-	 * initialized we can bail out right now. Note that we are supposed to
-	 * always log in if we are going to access private keys. However, we may
-	 * need to log in even for accessing public keys in case that the
-	 * CKF_LOGIN_REQUIRED flag is set.
-	 */
-	if ((pubkey_token_flags & CKF_LOGIN_REQUIRED ||
-	    is_private == CK_TRUE) && ~pubkey_token_flags &
-	    CKF_USER_PIN_INITIALIZED)
-		{
-		PK11err(PK11_F_TOKEN_LOGIN, PK11_R_TOKEN_PIN_NOT_SET);
-		goto err;
-		}
-
-	/*
-	 * Note on locking: it is possible that more than one thread gets into
-	 * pk11_get_pin() so we must deal with that. We cannot avoid it since we
-	 * cannot guard fork() in there with a lock because we could end up in
-	 * a dead lock in the child. Why? Remember we are in a multithreaded
-	 * environment so we must lock all mutexes in the prefork function to
-	 * avoid a situation in which a thread that did not call fork() held a
-	 * lock, making future unlocking impossible. We lock right before
-	 * C_Login().
-	 */
-	if (pubkey_token_flags & CKF_LOGIN_REQUIRED || is_private == CK_TRUE)
-		{
-		if (*login_done == CK_FALSE &&
-		    uri_struct->askpass == NULL)
-			{
-			PK11err(PK11_F_TOKEN_LOGIN,
-			    PK11_R_TOKEN_PIN_NOT_PROVIDED);
-			goto err;
-			}
-
-		if (*login_done == CK_FALSE &&
-		    uri_struct->askpass != NULL)
-			{
-			if (pk11_get_pin(uri_struct->askpass,
-			    &uri_struct->pin) == 0)
-				{
-				PK11err(PK11_F_TOKEN_LOGIN,
-				    PK11_R_TOKEN_PIN_NOT_PROVIDED);
-				goto err;
-				}
-			}
-
-		/*
-		 * Note that what we are logging into is the keystore from
-		 * pubkey_SLOTID because we work with OP_RSA session type here.
-		 * That also means that we can work with only one keystore in
-		 * the engine.
-		 *
-		 * We must make sure we do not try to login more than once.
-		 * Also, see the comment above on locking strategy.
-		 */
-		(void) pthread_mutex_lock(uri_lock);
-		if (*login_done == CK_FALSE)
-			{
-			if ((rv = pFuncList->C_Login(session,
-			    CKU_USER, (CK_UTF8CHAR*)uri_struct->pin,
-			    strlen(uri_struct->pin))) != CKR_OK)
-				{
-				PK11err_add_data(PK11_F_TOKEN_LOGIN,
-				    PK11_R_TOKEN_LOGIN_FAILED, rv);
-				goto err_locked;
-				}
-
-			*login_done = CK_TRUE;
-
-			/*
-			 * Cache the passphrasedialog for possible child (which
-			 * would need to relogin).
-			 */
-			if (passphrasedialog == NULL &&
-			    uri_struct->askpass != NULL)
-				{
-				passphrasedialog =
-				    strdup(uri_struct->askpass);
-
-				if (passphrasedialog == NULL)
-					{
-					PK11err_add_data(PK11_F_TOKEN_LOGIN,
-					    PK11_R_MALLOC_FAILURE, rv);
-					goto err_locked;
-					}
-				}
-
-			/*
-			 * Check the PIN caching policy. Note that user might
-			 * have provided a PIN even when no PIN was required -
-			 * in that case we always remove the PIN from memory.
-			 */
-			if (pk11_get_pin_caching_policy() ==
-			    POLICY_WRONG_VALUE)
-				{
-				PK11err(PK11_F_TOKEN_LOGIN,
-				    PK11_R_PIN_CACHING_POLICY_INVALID);
-				goto err_locked;
-				}
-
-			if (pk11_get_pin_caching_policy() != POLICY_NONE)
-				if (pk11_cache_pin(uri_struct->pin) == 0)
-					goto err_locked;
-			}
-		(void) pthread_mutex_unlock(uri_lock);
-		}
-	else
-		{
-			/*
-			 * If token does not require login we take it as the
-			 * login was done.
-			 */
-			*login_done = CK_TRUE;
-		}
-
-	/*
-	 * If we raced at pk11_get_pin() we must make sure that all threads that
-	 * called pk11_get_pin() will erase the PIN from memory, not just the
-	 * one that called C_Login(). Note that if we were supposed to cache the
-	 * PIN it was already cached by now so filling "uri_struct.pin" with
-	 * zero bytes is always OK since pk11_cache_pin() makes a copy of it.
-	 */
-	if (uri_struct->pin != NULL)
-		memset(uri_struct->pin, 0, strlen(uri_struct->pin));
-
-	return (1);
-
-err_locked:
-	(void) pthread_mutex_unlock(uri_lock);
-err:
-	/* Always get rid of the PIN. */
-	if (uri_struct->pin != NULL)
-		memset(uri_struct->pin, 0, strlen(uri_struct->pin));
-	return (0);
-	}
-
-/*
- * Log in to the keystore in the child if we were logged in in the parent. There
- * are similarities in the code with pk11_token_login() but still it is quite
- * different so we need a separate function for this.
- *
- * Note that this function is called under the locked session mutex when fork is
- * detected. That means that C_Login() will be called from the child just once.
- *
- * Returns:
- *	1 on success
- *	0 on failure
- */
-int
-pk11_token_relogin(CK_SESSION_HANDLE session)
-	{
-	CK_RV rv;
-
-	/*
-	 * We are in the child so check if we should login to the token again.
-	 * Note that it is enough to log in to the token through one session
-	 * only, all already open and all future sessions can access the token
-	 * then.
-	 */
-	if (passphrasedialog != NULL)
-		{
-		char *pin = NULL;
-
-		/* If we cached the PIN then use it. */
-		if (token_pin != NULL)
-			pin = token_pin;
-		else if (pk11_get_pin(passphrasedialog, &pin) == 0)
-			goto err;
-
-		(void) pthread_mutex_lock(uri_lock);
-		if ((rv = pFuncList->C_Login(session, CKU_USER,
-		    (CK_UTF8CHAR_PTR)pin, strlen(pin))) != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_TOKEN_RELOGIN,
-			    PK11_R_TOKEN_LOGIN_FAILED, rv);
-			(void) pthread_mutex_unlock(uri_lock);
-			goto err;
-			}
-		(void) pthread_mutex_unlock(uri_lock);
-
-		/* Forget the PIN now if we did not cache it before. */
-		if (pin != token_pin)
-			{
-			memset(pin, 0, strlen(pin));
-			OPENSSL_free(pin);
-			}
-		}
-
-	return (1);
-err:
-	return (0);
-	}
-
-/*
- * This function forks and runs an external command. It would be nice if we
- * could use popen(3C)/pclose(3C) for that but unfortunately we need to be able
- * to get rid of the PIN from the memory. With p(open|close) function calls we
- * cannot control the stdio's memory used for buffering and our tests showed
- * that the PIN really stays there even after pclose().
- *
- * Returns:
- *	allocated buffer on success
- *	NULL on failure
- */
-static char *
-run_askpass(char *dialog)
-	{
-	pid_t pid;
-	int n, p[2];
-	char *buf = NULL;
-
-	if (pipe(p) == -1)
-		{
-		PK11err(PK11_F_RUN_ASKPASS, PK11_R_PIPE_FAILED);
-		return (NULL);
-		}
-
-	switch (pid = fork())
-		{
-		case -1:
-			PK11err(PK11_F_RUN_ASKPASS, PK11_R_FORK_FAILED);
-			return (NULL);
-		/* child */
-		case 0:
-			/*
-			 * This should make sure that dup2() will not fail on
-			 * file descriptor shortage.
-			 */
-			close(p[0]);
-			(void) dup2(p[1], 1);
-			close(p[1]);
-			/*
-			 * Note that we cannot use PK11err() here since we are
-			 * in the child. However, parent will get read() error
-			 * so do not worry.
-			 */
-			(void) execl(dialog, basename(dialog), NULL);
-			exit(1);
-		/* parent */
-		default:
-			/* +1 is for the terminating '\0' */
-			buf = (char *)OPENSSL_malloc(PK11_MAX_PIN_LEN + 1);
-			if (buf == NULL)
-				{
-				PK11err(PK11_F_RUN_ASKPASS,
-				    PK11_R_MALLOC_FAILURE);
-				return (NULL);
-				}
-
-			close(p[1]);
-			n = read(p[0], buf, PK11_MAX_PIN_LEN);
-			if (n == -1 || n == 0)
-				{
-				PK11err(PK11_F_RUN_ASKPASS,
-				    PK11_R_PIN_NOT_READ_FROM_COMMAND);
-				OPENSSL_free(buf);
-				return (NULL);
-				}
-			buf[n] = '\0';
-
-			(void) waitpid(pid, NULL, 0);
-		}
-
-	return (buf);
-	}
-
-#endif	/* OPENSSL_NO_HW_PK11 */
-#endif	/* OPENSSL_NO_HW */
--- a/components/openssl/openssl-1.0.1-fips-140/engines/pkcs11/e_pk11_uri.h	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- *
- */
-
-/*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    [email protected].
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (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	E_PK11_URI_H
-#define	E_PK11_URI_H
-
-#include <security/pkcs11t.h>
-
-/* PKCS#11 URI related prefixes and attributes. */
-#define	PK11_URI_PREFIX		"pkcs11:"
-#define	FILE_URI_PREFIX		"file://"
-#define	PK11_TOKEN		"token"
-#define	PK11_MANUF		"manuf"
-#define	PK11_SERIAL		"serial"
-#define	PK11_MODEL		"model"
-#define	PK11_OBJECT		"object"
-#define	PK11_OBJECTTYPE		"objecttype"
-#define	PK11_ASKPASS		"passphrasedialog"
-
-/* PIN caching policy. */
-#define	POLICY_NOT_INITIALIZED	0
-#define	POLICY_NONE		1
-#define	POLICY_MEMORY		2
-#define	POLICY_MLOCKED_MEMORY	3
-#define	POLICY_WRONG_VALUE	4
-
-/*
- * That's what getpassphrase(3c) supports.
- */
-#define	PK11_MAX_PIN_LEN	256
-
-/* Add new attributes of the PKCS#11 URI here. */
-typedef struct pkcs11_uri_struct {
-	char	*object;	/* object label, the only mandatory info */
-	char	*objecttype;	/* (private|public|cert), currently unused */
-	char	*token;		/* token label */
-	char	*manuf;		/* manufacturer label */
-	char	*serial;	/* serial number label */
-	char	*model;		/* model label */
-	char	*askpass;	/* full path to the command to get the PIN */
-	/* Not part of the PKCS11 URI itself. */
-	char	*pin;		/* token PIN */
-} pkcs11_uri;
-
-/* For URI processing. */
-extern pthread_mutex_t *uri_lock;
-
-int pk11_get_pin(char *dialog, char **pin);
-int pk11_get_pin_caching_policy(void);
-int pk11_process_pkcs11_uri(const char *uristr, pkcs11_uri *uri_struct,
-	const char **file);
-int pk11_check_token_attrs(pkcs11_uri *uri_struct);
-void pk11_free_pkcs11_uri(pkcs11_uri *uri_struct, CK_BBOOL free_uri_itself);
-int pk11_cache_pin(char *pin);
-int pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
-	pkcs11_uri *uri_struct, CK_BBOOL is_private);
-int pk11_token_relogin(CK_SESSION_HANDLE session);
-
-#endif /* E_PK11_URI_H */
--- a/components/openssl/openssl-1.0.1-fips-140/llib-lcrypto	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* LINTLIBRARY */
-/* PROTOLIB1 */
-
-#include <openssl/asn1.h>
-#include <openssl/asn1_mac.h>
-#include <openssl/bio.h>
-#include <openssl/blowfish.h>
-#include <openssl/bn.h>
-#include <openssl/buffer.h>
-#include <openssl/comp.h>
-#include <openssl/conf.h>
-#include <openssl/conf_api.h>
-#include <openssl/crypto.h>
-#include <openssl/des.h>
-#include <openssl/dh.h>
-#include <openssl/dsa.h>
-#include <openssl/dso.h>
-#include <openssl/e_os2.h>
-#include <openssl/ebcdic.h>
-#include <openssl/engine.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#include <openssl/hmac.h>
-#include <openssl/lhash.h>
-#include <openssl/obj_mac.h>
-#include <openssl/objects.h>
-#include <openssl/opensslconf.h>
-#include <openssl/opensslv.h>
-#include <openssl/pem.h>
-#include <openssl/pem2.h>
-#include <openssl/pkcs12.h>
-#include <openssl/pkcs7.h>
-#include <openssl/rand.h>
-#include <openssl/rsa.h>
-#include <openssl/safestack.h>
-#include <openssl/sha.h>
-#include <openssl/stack.h>
-#include <openssl/symhacks.h>
-#include <openssl/txt_db.h>
-#include <openssl/x509.h>
-#include <openssl/x509_vfy.h>
-#include <openssl/x509v3.h>
--- a/components/openssl/openssl-1.0.1-fips-140/llib-lssl	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* LINTLIBRARY */
-/* PROTOLIB1 */
-
-#include <openssl/ssl.h>
-#include <openssl/ssl2.h>
-#include <openssl/ssl23.h>
-#include <openssl/ssl3.h>
--- a/components/openssl/openssl-1.0.1-fips-140/openssl-1.0.1-fips-140.license	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-
-  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. Actually both licenses are BSD-style
-  Open Source licenses. In case of any license issues related to OpenSSL
-  please contact [email protected].
-
-  OpenSSL License
-  ---------------
-
-/* ====================================================================
- * Copyright (c) 1998-2016 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    [email protected].
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * ([email protected]).  This product includes software written by Tim
- * Hudson ([email protected]).
- *
- */
-
- Original SSLeay License
- -----------------------
-
-/* Copyright (C) 1995-1998 Eric Young ([email protected])
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young ([email protected]).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson ([email protected]).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young ([email protected])"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson ([email protected])"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of 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/components/openssl/openssl-1.0.1-fips-140/openssl-1.0.1-fips-140.p5m	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,218 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
-#
-
-<transform file path=usr.*/man/.+ -> default mangler.man.stability uncommitted>
-
-# Header files.
-#
-# Take header files from the 32-bit build. This build has the patched
-# opensslconf.h (64-bit build does not). We cannot take header files from the
-# proto area since it could contain headers installed for the 64-bit build.
-<transform file path=usr/include/openssl/fips-140/openssl/(.+\.h)$ -> \
-    set action.hash $(MACH32)/include/openssl/%<1> >
-set name=pkg.fmri \
-    value=pkg:/library/security/openssl/openssl-fips-140@$(IPS_COMPONENT_VERSION),$(BUILD_VERSION)
-set name=pkg.summary value="FIPS 140-2 Capable OpenSSL libraries"
-set name=pkg.human-version value=$(COMPONENT_VERSION)
-
-# This line is needed temporarily to workaround the link check error due to
-# change of action type.  It should be removed once non-FIPS version becomes
-# available in the reference repository
-set name=pkg.linted.pkglint.dupaction010.1 value=true
-set name=com.oracle.info.description \
-    value="the FIPS 140-2 Capable OpenSSL libraries"
-set name=com.oracle.info.tpno value=$(TPNO)
-set name=info.classification value=org.opensolaris.category.2008:System/Security
-set name=info.source-url value=$(COMPONENT_ARCHIVE_URL)
-set name=info.upstream-url value=$(COMPONENT_PROJECT_URL)
-set name=org.opensolaris.arc-caseid value=PSARC/2009/507
-set name=org.opensolaris.consolidation value=$(CONSOLIDATION)
-
-# Basic directories and a configuration file.
-file etc/openssl/openssl.cnf path=etc/openssl/fips-140/openssl.cnf group=sys \
-    mode=0644 preserve=true
-link path=lib/$(MACH64)/libcrypto.so.1.0.0 \
-    target=../openssl/fips-140/$(MACH64)/libcrypto.so.1.0.0 mediator=openssl \
-    mediator-implementation=fips-140
-link path=lib/$(MACH64)/libssl.so.1.0.0 \
-    target=../openssl/fips-140/$(MACH64)/libssl.so.1.0.0 mediator=openssl \
-    mediator-implementation=fips-140
-link path=lib/$(MACH64)/llib-lcrypto \
-    target=../openssl/fips-140/$(MACH64)/llib-lcrypto mediator=openssl \
-    mediator-implementation=fips-140
-link path=lib/$(MACH64)/llib-lcrypto.ln \
-    target=../openssl/fips-140/$(MACH64)/llib-lcrypto.ln mediator=openssl \
-    mediator-implementation=fips-140
-link path=lib/$(MACH64)/llib-lssl \
-    target=../openssl/fips-140/$(MACH64)/llib-lssl mediator=openssl \
-    mediator-implementation=fips-140
-link path=lib/$(MACH64)/llib-lssl.ln \
-    target=../openssl/fips-140/$(MACH64)/llib-lssl.ln mediator=openssl \
-    mediator-implementation=fips-140
-
-# Mediator links for 32-bit libraries
-link path=lib/libcrypto.so.1.0.0 target=openssl/fips-140/libcrypto.so.1.0.0 \
-    mediator=openssl mediator-implementation=fips-140
-link path=lib/libssl.so.1.0.0 target=openssl/fips-140/libssl.so.1.0.0 \
-    mediator=openssl mediator-implementation=fips-140
-link path=lib/llib-lcrypto target=../../lib/openssl/fips-140/llib-lcrypto \
-    mediator=openssl mediator-implementation=fips-140
-link path=lib/llib-lcrypto.ln target=openssl/fips-140/llib-lcrypto.ln \
-    mediator=openssl mediator-implementation=fips-140
-link path=lib/llib-lssl target=openssl/fips-140/llib-lssl mediator=openssl \
-    mediator-implementation=fips-140
-link path=lib/llib-lssl.ln target=openssl/fips-140/llib-lssl.ln \
-    mediator=openssl mediator-implementation=fips-140
-
-# Mediator links for 64-bit libraries
-link path=lib/openssl/engines/$(MACH64)/libpk11.so.1 \
-    target=../../fips-140/engines/$(MACH64)/libpk11.so.1 mediator=openssl \
-    mediator-implementation=fips-140
-link path=lib/openssl/engines/libpk11.so.1 \
-    target=../fips-140/engines/libpk11.so.1 mediator=openssl \
-    mediator-implementation=fips-140
-file $(MACH32)/apps/openssl path=lib/openssl/fips-140/$(MACH32)/openssl \
-    owner=root group=bin mode=0555
-link path=lib/openssl/fips-140/$(MACH64)/libcrypto.so target=libcrypto.so.1.0.0
-
-# 64 bit libraries, lint libraries, and engines.
-file $(MACH64)/libcrypto.so.1.0.0 \
-    path=lib/openssl/fips-140/$(MACH64)/libcrypto.so.1.0.0
-link path=lib/openssl/fips-140/$(MACH64)/libssl.so target=libssl.so.1.0.0
-file $(MACH64)/libssl.so.1.0.0 \
-    path=lib/openssl/fips-140/$(MACH64)/libssl.so.1.0.0
-file llib-lcrypto path=lib/openssl/fips-140/$(MACH64)/llib-lcrypto
-file $(MACH64)/llib-lcrypto.ln \
-    path=lib/openssl/fips-140/$(MACH64)/llib-lcrypto.ln
-file llib-lssl path=lib/openssl/fips-140/$(MACH64)/llib-lssl
-file $(MACH64)/llib-lssl.ln path=lib/openssl/fips-140/$(MACH64)/llib-lssl.ln
-link path=lib/openssl/fips-140/64 target=$(MACH64)
-file etc/openssl/misc/CA.pl path=lib/openssl/fips-140/CA.pl
-link path=lib/openssl/fips-140/engines/$(MACH64)/libpk11.so target=libpk11.so.1
-file $(MACH64)/engines/libpk11.so \
-    path=lib/openssl/fips-140/engines/$(MACH64)/libpk11.so.1
-link path=lib/openssl/fips-140/engines/libpk11.so target=libpk11.so.1
-
-# 32 bit libraries, lint libraries, and engines.
-file $(MACH32)/engines/libpk11.so path=lib/openssl/fips-140/engines/libpk11.so.1
-link path=lib/openssl/fips-140/libcrypto.so target=libcrypto.so.1.0.0
-file $(MACH32)/libcrypto.so.1.0.0 path=lib/openssl/fips-140/libcrypto.so.1.0.0
-link path=lib/openssl/fips-140/libssl.so target=libssl.so.1.0.0
-file $(MACH32)/libssl.so.1.0.0 path=lib/openssl/fips-140/libssl.so.1.0.0
-file llib-lcrypto path=lib/openssl/fips-140/llib-lcrypto
-file $(MACH32)/llib-lcrypto.ln path=lib/openssl/fips-140/llib-lcrypto.ln
-file llib-lssl path=lib/openssl/fips-140/llib-lssl
-file $(MACH32)/llib-lssl.ln path=lib/openssl/fips-140/llib-lssl.ln
-
-# Commands.
-file $(MACH64)/apps/openssl path=lib/openssl/fips-140/openssl owner=root \
-    group=bin mode=0555
-link path=usr/bin/$(MACH32)/openssl \
-    target=../../../lib/openssl/fips-140/$(MACH32)/openssl mediator=openssl \
-    mediator-implementation=fips-140
-link path=usr/bin/CA.pl target=../../lib/openssl/fips-140/CA.pl \
-    mediator=openssl mediator-implementation=fips-140
-
-# Mediator links for the commands
-link path=usr/bin/openssl target=../../lib/openssl/fips-140/openssl \
-    mediator=openssl mediator-implementation=fips-140
-file path=usr/include/openssl/fips-140/openssl/aes.h
-file path=usr/include/openssl/fips-140/openssl/asn1.h
-file path=usr/include/openssl/fips-140/openssl/asn1_mac.h
-file path=usr/include/openssl/fips-140/openssl/asn1t.h
-file path=usr/include/openssl/fips-140/openssl/bio.h
-file path=usr/include/openssl/fips-140/openssl/blowfish.h
-file path=usr/include/openssl/fips-140/openssl/bn.h
-file path=usr/include/openssl/fips-140/openssl/buffer.h
-file path=usr/include/openssl/fips-140/openssl/cast.h
-file path=usr/include/openssl/fips-140/openssl/cmac.h
-file path=usr/include/openssl/fips-140/openssl/cms.h
-file path=usr/include/openssl/fips-140/openssl/comp.h
-file path=usr/include/openssl/fips-140/openssl/conf.h
-file path=usr/include/openssl/fips-140/openssl/conf_api.h
-file path=usr/include/openssl/fips-140/openssl/crypto.h
-file path=usr/include/openssl/fips-140/openssl/des.h
-file path=usr/include/openssl/fips-140/openssl/des_old.h
-file path=usr/include/openssl/fips-140/openssl/dh.h
-file path=usr/include/openssl/fips-140/openssl/dsa.h
-file path=usr/include/openssl/fips-140/openssl/dso.h
-file path=usr/include/openssl/fips-140/openssl/dtls1.h
-file path=usr/include/openssl/fips-140/openssl/e_os2.h
-file path=usr/include/openssl/fips-140/openssl/ebcdic.h
-file path=usr/include/openssl/fips-140/openssl/ec.h
-file path=usr/include/openssl/fips-140/openssl/ecdh.h
-file path=usr/include/openssl/fips-140/openssl/ecdsa.h
-file path=usr/include/openssl/fips-140/openssl/engine.h
-file path=usr/include/openssl/fips-140/openssl/err.h
-file path=usr/include/openssl/fips-140/openssl/evp.h
-file path=usr/include/openssl/fips-140/openssl/fips.h
-file path=usr/include/openssl/fips-140/openssl/fips_rand.h
-file path=usr/include/openssl/fips-140/openssl/hmac.h
-file path=usr/include/openssl/fips-140/openssl/krb5_asn.h
-file path=usr/include/openssl/fips-140/openssl/kssl.h
-file path=usr/include/openssl/fips-140/openssl/lhash.h
-file path=usr/include/openssl/fips-140/openssl/md2.h
-file path=usr/include/openssl/fips-140/openssl/md4.h
-file path=usr/include/openssl/fips-140/openssl/md5.h
-file path=usr/include/openssl/fips-140/openssl/modes.h
-file path=usr/include/openssl/fips-140/openssl/obj_mac.h
-file path=usr/include/openssl/fips-140/openssl/objects.h
-file path=usr/include/openssl/fips-140/openssl/ocsp.h
-file path=usr/include/openssl/fips-140/openssl/opensslconf.h
-file path=usr/include/openssl/fips-140/openssl/opensslv.h
-file path=usr/include/openssl/fips-140/openssl/ossl_typ.h
-file path=usr/include/openssl/fips-140/openssl/pem.h
-file path=usr/include/openssl/fips-140/openssl/pem2.h
-file path=usr/include/openssl/fips-140/openssl/pkcs12.h
-file path=usr/include/openssl/fips-140/openssl/pkcs7.h
-file path=usr/include/openssl/fips-140/openssl/pqueue.h
-file path=usr/include/openssl/fips-140/openssl/rand.h
-file path=usr/include/openssl/fips-140/openssl/rc2.h
-file path=usr/include/openssl/fips-140/openssl/rc4.h
-file path=usr/include/openssl/fips-140/openssl/ripemd.h
-file path=usr/include/openssl/fips-140/openssl/rsa.h
-file path=usr/include/openssl/fips-140/openssl/safestack.h
-file path=usr/include/openssl/fips-140/openssl/sha.h
-file path=usr/include/openssl/fips-140/openssl/srp.h
-file path=usr/include/openssl/fips-140/openssl/srtp.h
-file path=usr/include/openssl/fips-140/openssl/ssl.h
-file path=usr/include/openssl/fips-140/openssl/ssl2.h
-file path=usr/include/openssl/fips-140/openssl/ssl23.h
-file path=usr/include/openssl/fips-140/openssl/ssl3.h
-file path=usr/include/openssl/fips-140/openssl/stack.h
-file path=usr/include/openssl/fips-140/openssl/symhacks.h
-file path=usr/include/openssl/fips-140/openssl/tls1.h
-file path=usr/include/openssl/fips-140/openssl/ts.h
-file path=usr/include/openssl/fips-140/openssl/txt_db.h
-file path=usr/include/openssl/fips-140/openssl/ui.h
-file path=usr/include/openssl/fips-140/openssl/ui_compat.h
-file path=usr/include/openssl/fips-140/openssl/whrlpool.h
-file path=usr/include/openssl/fips-140/openssl/x509.h
-file path=usr/include/openssl/fips-140/openssl/x509_vfy.h
-file path=usr/include/openssl/fips-140/openssl/x509v3.h
-license openssl-1.0.1-fips-140.license license="OpenSSL, SSLeay"
-
-# OpenSSL packages are now managed by 'pkg mediator', and the installation
-# of 'openssl-fips-140' package requires 'openssl' package with the mediator
-# change (s11u2_build35 or later)
-depend type=optional fmri=library/security/[email protected],5.11-0.175.2.0.0.35.0
--- a/components/openssl/openssl-1.0.1-fips-140/patches-post-config/opensslconf.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
---- /tmp/opensslconf.h	Fri Feb 11 15:36:12 2011
-+++ openssl-1.0.0d/crypto/opensslconf.h	Fri Feb 11 16:58:36 2011
-@@ -181,7 +181,11 @@
- 
- #if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
- #if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
-+#if defined(__sparcv9) || defined(__x86_64)
-+#define ENGINESDIR "/lib/openssl/engines/64"
-+#else
- #define ENGINESDIR "/lib/openssl/engines"
-+#endif
- #define OPENSSLDIR "/etc/openssl"
- #endif
- #endif
-@@ -228,21 +232,39 @@
- /* 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
-+#if defined(__sparcv9) || defined(__x86_64)
-+#define DES_LONG unsigned int
-+#else
- #define DES_LONG unsigned long
- #endif
- #endif
-+#endif
- 
- #if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
- #define CONFIG_HEADER_BN_H
-+/*
-+ * OpenSSL revision 1.521 from 2005-12-15 in OpenSSL_1_0_0-stable branch changed
-+ * 64 bit sparcv9 configuration from SIXTY_FOUR_BIT_LONG to BN_LLONG.
-+ */
-+#if defined(__x86_64)
-+#undef BN_LLONG
-+#else
- #define BN_LLONG
-+#endif
- 
- /* Should we define BN_DIV2W here? */
- 
- /* Only one for the following should be defined */
-+#if defined(__x86_64)
-+#define SIXTY_FOUR_BIT_LONG
-+#undef THIRTY_TWO_BIT
-+#else
- #undef SIXTY_FOUR_BIT_LONG
- #undef SIXTY_FOUR_BIT
- #define THIRTY_TWO_BIT
- #endif
-+#undef SIXTY_FOUR_BIT
-+#endif
- 
- #if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
- #define CONFIG_HEADER_RC4_LOCL_H
--- a/components/openssl/openssl-1.0.1-fips-140/patches/08-6193522.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-diff -ruN openssl-0.9.8a/apps/CA.pl.in openssl-0.9.8a/apps/CA.pl.in
---- openssl-0.9.8a/apps/CA.pl.in	2005-07-04 23:44:22.000000000 +0200
-+++ openssl-0.9.8a/apps/CA.pl.in	2009-04-21 16:08:45.354925289 +0200
-@@ -53,7 +53,7 @@
- $X509="$openssl x509";
- $PKCS12="$openssl pkcs12";
- 
--$CATOP="./demoCA";
-+$CATOP="/etc/openssl";
- $CAKEY="cakey.pem";
- $CAREQ="careq.pem";
- $CACERT="cacert.pem";
-diff -ruN openssl-0.9.8a/apps/openssl.cnf openssl-0.9.8a/apps/openssl.cnf
---- openssl-0.9.8a/apps/openssl.cnf	2005-09-16 14:20:24.000000000 +0200
-+++ openssl-0.9.8a/apps/openssl.cnf	2009-04-21 16:07:13.910980196 +0200
-@@ -39,7 +39,7 @@
- ####################################################################
- [ CA_default ]
- 
--dir		= ./demoCA		# Where everything is kept
-+dir		= /etc/openssl		# Where everything is kept
- certs		= $dir/certs		# Where the issued certs are kept
- crl_dir		= $dir/crl		# Where the issued crl are kept
- database	= $dir/index.txt	# database index file.
-@@ -49,7 +49,7 @@
- 
- certificate	= $dir/cacert.pem 	# The CA certificate
- serial		= $dir/serial 		# The current serial number
--crlnumber	= $dir/crlnumber	# the current crl number
-+#crlnumber	= $dir/crlnumber	# the current crl number
- 					# must be commented out to leave a V1 CRL
- crl		= $dir/crl.pem 		# The current CRL
- private_key	= $dir/private/cakey.pem# The private key
-@@ -126,17 +126,17 @@
- 
- [ req_distinguished_name ]
- countryName			= Country Name (2 letter code)
--countryName_default		= AU
-+#countryName_default		= US
- countryName_min			= 2
- countryName_max			= 2
- 
- stateOrProvinceName		= State or Province Name (full name)
--stateOrProvinceName_default	= Some-State
-+#stateOrProvinceName_default	= Some-State
- 
- localityName			= Locality Name (eg, city)
- 
- 0.organizationName		= Organization Name (eg, company)
--0.organizationName_default	= Internet Widgits Pty Ltd
-+#0.organizationName_default	= Unconfigured OpenSSL Installation
- 
- # we can do this but it is not needed normally :-)
- #1.organizationName		= Second Organization Name (eg, company)
--- a/components/openssl/openssl-1.0.1-fips-140/patches/11-6546806.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-diff -ruN openssl-0.9.8a/doc/crypto/hmac.pod openssl-0.9.8a/doc/crypto/hmac.pod
---- openssl-0.9.8a/doc/crypto/hmac.pod	2002-07-18 20:54:45.000000000 +0200
-+++ openssl-0.9.8a/doc/crypto/hmac.pod	2009-04-10 11:09:46.449071541 +0200
-@@ -2,7 +2,7 @@
- 
- =head1 NAME
- 
--HMAC, HMAC_Init, HMAC_Update, HMAC_Final, HMAC_cleanup - HMAC message
-+HMAC, HMAC_CTX_init, HMAC_Init, HMAC_Init_ex, HMAC_Update, HMAC_Final, HMAC_CTX_cleanup, HMAC_cleanup - HMAC message
- authentication code
- 
- =head1 SYNOPSIS
--- a/components/openssl/openssl-1.0.1-fips-140/patches/15-pkcs11_engine-0.9.8a.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,206 +0,0 @@
-#
-# This patch file adds the Solaris's pkcs11 engine.
-# This is Solaris-specific (developed in house): not suitable for upstream.
-#
---- /tmp/Configure	Fri Feb 11 14:40:39 2011
-+++ openssl-1.0.0d/Configure	Fri Feb 11 14:41:36 2011
-@@ -10,7 +10,7 @@
- 
- # see INSTALL for instructions.
- 
--my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [experimental-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-krb5] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
-+my $usage="Usage: Configure --pk11-libname=PK11_LIB_LOCATION [no-<cipher> ...] [enable-<cipher> ...] [experimental-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-krb5] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
- 
- # Options:
- #
-@@ -19,6 +19,9 @@
- # --prefix      prefix for the OpenSSL include, lib and bin directories
- #               (Default: the OPENSSLDIR directory)
- #
-+# --pk11-libname  PKCS#11 library name.
-+#               (Default: none)
-+#
- # --install_prefix  Additional prefix for package builders (empty by
- #               default).  This needn't be set in advance, you can
- #               just as well use "make INSTALL_PREFIX=/whatever install".
-@@ -657,6 +661,9 @@
- my $idx_arflags = $idx++;
- my $idx_multilib = $idx++;
- 
-+# PKCS#11 engine patch
-+my $pk11_libname="";
-+
- my $prefix="";
- my $libdir="";
- my $openssldir="";
-@@ -882,6 +888,10 @@
-				$_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei;
-				$flags.=$_." ";
-				}
-+			elsif (/^--pk11-libname=(.*)$/)
-+				{
-+				$pk11_libname=$1;
-+				}
-			elsif (/^--prefix=(.*)$/)
-				{
-				$prefix=$1;
-@@ -1049,6 +1059,13 @@
- 	exit 0;
- }
- 
-+if (! $pk11_libname)
-+        {
-+        print STDERR "You must set --pk11-libname for PKCS#11 library.\n";
-+        print STDERR "See README.pkcs11 for more information.\n";
-+        exit 1;
-+        }
-+
- if ($target =~ m/^CygWin32(-.*)$/) {
- 	$target = "Cygwin".$1;
- }
-@@ -1215,6 +1232,8 @@
- if ($flags ne "")	{ $cflags="$flags$cflags"; }
- else			{ $no_user_cflags=1;       }
- 
-+$cflags="-DPK11_LIB_LOCATION=\"$pk11_libname\" $cflags";
-+
- # Kerberos settings.  The flavor must be provided from outside, either through
- # the script "config" or manually.
- if (!$no_krb5)
-@@ -1604,6 +1623,7 @@
- 	s/^VERSION=.*/VERSION=$version/;
- 	s/^MAJOR=.*/MAJOR=$major/;
- 	s/^MINOR=.*/MINOR=$minor/;
-+	s/^PK11_LIB_LOCATION=.*/PK11_LIB_LOCATION=$pk11_libname/;
- 	s/^SHLIB_VERSION_NUMBER=.*/SHLIB_VERSION_NUMBER=$shlib_version_number/;
- 	s/^SHLIB_VERSION_HISTORY=.*/SHLIB_VERSION_HISTORY=$shlib_version_history/;
- 	s/^SHLIB_MAJOR=.*/SHLIB_MAJOR=$shlib_major/;
---- /tmp/Makefile.org	Fri Feb 11 14:41:54 2011
-+++ openssl-1.0.0d/Makefile.org	Fri Feb 11 14:38:01 2011
-@@ -26,6 +26,9 @@
- INSTALL_PREFIX=
- INSTALLTOP=/usr/local/ssl
- 
-+# You must set this through --pk11-libname configure option.
-+PK11_LIB_LOCATION=
-+
- # Do not edit this manually. Use Configure --openssldir=DIR do change this!
- OPENSSLDIR=/usr/local/ssl
- 
---- /tmp/Makefile	Mon Feb 14 14:59:22 2011
-+++ openssl-1.0.0d/engines/Makefile	Mon Feb 14 15:00:35 2011
-@@ -26,7 +26,8 @@
- APPS=
- 
- LIB=$(TOP)/libcrypto.a
--LIBNAMES= 4758cca aep atalla cswift gmp chil nuron sureware ubsec padlock capi
-+LIBNAMES= 4758cca aep atalla cswift gmp chil nuron sureware ubsec padlock capi \
-+	  pk11
- 
- LIBSRC=	e_4758cca.c \
- 	e_aep.c \
-@@ -38,7 +39,8 @@
- 	e_sureware.c \
- 	e_ubsec.c \
- 	e_padlock.c \
--	e_capi.c
-+	e_capi.c \
-+	e_pk11.c
- LIBOBJ= e_4758cca.o \
- 	e_aep.o \
- 	e_atalla.o \
-@@ -49,7 +51,8 @@
- 	e_sureware.o \
- 	e_ubsec.o \
- 	e_padlock.o \
--	e_capi.o
-+	e_capi.o \
-+	e_pk11.o
- 
- SRC= $(LIBSRC)
- 
-@@ -63,7 +66,8 @@
- 	e_nuron_err.c e_nuron_err.h \
- 	e_sureware_err.c e_sureware_err.h \
- 	e_ubsec_err.c e_ubsec_err.h \
--	e_capi_err.c e_capi_err.h
-+	e_capi_err.c e_capi_err.h \
-+	e_pk11.h e_pk11_uri.h e_pk11_err.h e_pk11_pub.c e_pk11_uri.c e_pk11_err.c
- 
- ALL=    $(GENERAL) $(SRC) $(HEADER)
- 
-@@ -78,7 +82,7 @@
- 		for l in $(LIBNAMES); do \
- 			$(MAKE) -f ../Makefile.shared -e \
- 				LIBNAME=$$l LIBEXTRAS=e_$$l.o \
--				LIBDEPS='-L.. -lcrypto $(EX_LIBS)' \
-+				LIBDEPS='-L.. -lcrypto -lcryptoutil $(EX_LIBS)' \
- 				link_o.$(SHLIB_TARGET); \
- 		done; \
- 	else \
---- crypto/engine/eng_all.c Thu Sep  5 12:59:50 2013
-+++ openssl-1.0.1e/crypto/engine/eng_all.c Thu Sep  5 12:59:50 2013
-@@ -60,6 +60,16 @@
- #include "cryptlib.h"
- #include "eng_int.h"
-
-+/*
-+ * pkcs11 engine no longer is a built-in engine, and ENGINE_load_pk11() needs to be
-+ * defined in libcrypto.so for ssh.  Instead of load pkcs11 engine, it load dynamic
-+ * engines.
-+ */
-+void ENGINE_load_pk11(void)
-+	{
-+	ENGINE_load_dynamic();
-+	}
-+
- void ENGINE_load_builtin_engines(void)
- {
-     /* Some ENGINEs need this */
-@@ -80,6 +90,9 @@
-     ENGINE_load_rdrand();
- #endif
-     ENGINE_load_dynamic();
-+#ifndef OPENSSL_NO_HW_PKCS11
-+    ENGINE_load_pk11();
-+#endif
- #ifndef OPENSSL_NO_STATIC_ENGINE
- # ifndef OPENSSL_NO_HW
- #  ifndef OPENSSL_NO_HW_4758_CCA
---- crypto/dso/dso_lib.c Thu Sep  5 12:59:50 2013
-+++ openssl-1.0.1e/crypto/dso/dso_lib.c Thu Sep  5 12:59:50 2013
-@@ -396,6 +396,24 @@
-         DSOerr(DSO_F_DSO_CONVERT_FILENAME, DSO_R_NO_FILENAME);
-         return (NULL);
-     }
-+    /*
-+     * For pkcs11 engine, use libpk11.so (instead of libpkcs11.so) to
-+     * avoid the name collision with PKCS#11 library.
-+     */
-+    if (strcmp(filename, "pkcs11") == 0) {
-+#ifdef  _LP64
-+        static const char fullpath[] = "/lib/openssl/engines/64/libpk11.so";
-+#else
-+        static const char fullpath[] = "/lib/openssl/engines/libpk11.so";
-+#endif
-+        result = OPENSSL_malloc(strlen(fullpath) + 1);
-+        if(result == NULL) {
-+            DSOerr(DSO_F_DSO_CONVERT_FILENAME, ERR_R_MALLOC_FAILURE);
-+            return(NULL);
-+        }
-+        BUF_strlcpy(result, fullpath, strlen(fullpath) + 1);
-+        return (result);
-+    }
-     if ((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) {
-         if (dso->name_converter != NULL)
-             result = dso->name_converter(dso, filename);
---- /tmp/engine.h       Fri Feb 11 14:46:24 2011
-+++ openssl-1.0.0d/crypto/engine/engine.h       Fri Feb 11 14:47:32 2011
-@@ -413,6 +413,7 @@
- #  endif
- # endif
- void ENGINE_load_cryptodev(void);
-+void ENGINE_load_pk11(void);
- void ENGINE_load_rsax(void);
- void ENGINE_load_rdrand(void);
- void ENGINE_load_builtin_engines(void);
--- a/components/openssl/openssl-1.0.1-fips-140/patches/18-compiler_opts.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-#
-# Solaris-specific; not suitable for upstream
-#
-diff -ruN openssl-0.9.8k/Configure openssl-0.9.8k/Configure
---- openssl-0.9.8k/Configure	2009-02-16 09:44:22.000000000 +0100
-+++ openssl-0.9.8k/Configure	2009-06-25 16:19:22.897811727 +0200
-@@ -133,7 +133,7 @@
-
- my $x86_64_asm="x86_64cpuid.o:x86_64-gcc.o x86_64-mont.o x86_64-mont5.o x86_64-gf2m.o modexp512-x86_64.o::aes-x86_64.o vpaes-x86_64.o bsaes-x86_64.o aesni-x86_64.o aesni-sha1-x86_64.o::md5-x86_64.o:sha1-x86_64.o sha256-x86_64.o sha512-x86_64.o::rc4-x86_64.o rc4-md5-x86_64.o:::wp-x86_64.o:cmll-x86_64.o cmll_misc.o:ghash-x86_64.o:";
- my $ia64_asm="ia64cpuid.o:bn-ia64.o ia64-mont.o::aes_core.o aes_cbc.o aes-ia64.o::md5-ia64.o:sha1-ia64.o sha256-ia64.o sha512-ia64.o::rc4-ia64.o rc4_skey.o:::::ghash-ia64.o::void";
--my $sparcv9_asm="sparcv9cap.o sparccpuid.o:bn-sparcv9.o sparcv9-mont.o sparcv9a-mont.o:des_enc-sparc.o fcrypt_b.o:aes_core.o aes_cbc.o aes-sparcv9.o:::sha1-sparcv9.o sha256-sparcv9.o sha512-sparcv9.o:::::::ghash-sparcv9.o::void";
-+my $sparcv9_asm="sparcv9cap.o sparccpuid.o:bn-sparcv9.o sparcv9-mont.o:des_enc-sparc.o fcrypt_b.o:aes_core.o aes_cbc.o aes-sparcv9.o:::sha1-sparcv9.o sha256-sparcv9.o sha512-sparcv9.o:::::::ghash-sparcv9.o::void";
- my $sparcv8_asm=":sparcv8.o:des_enc-sparc.o fcrypt_b.o:::::::::::::void";
- my $alpha_asm="alphacpuid.o:bn_asm.o alpha-mont.o:::::sha1-alpha.o:::::::ghash-alpha.o::void";
- my $mips32_asm=":bn-mips.o::aes_cbc.o aes-mips.o:::sha1-mips.o sha256-mips.o::::::::";
-@@ -257,6 +264,12 @@
- #"sunos-cc", "cc:-O4 -DNOPROTO -DNOCONST::(unknown):SUNOS::DES_UNROLL:${no_asm}::",
- "sunos-gcc","gcc:-O3 -mcpu=v8 -Dssize_t=int::(unknown):SUNOS::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL DES_PTR DES_RISC1:${no_asm}::",
- 
-+#### Solaris configs, used for OpenSSL as delivered by OpenSolaris
-+"solaris-x86-cc-sunw","cc:-m32 -xO3 -xspace -Xa::-D_REENTRANT::-lsocket -lnsl -lc -R /lib/openssl/fips-140:BN_LLONG RC4_CHUNK DES_PTR DES_UNROLL BF_PTR:${x86_elf_asm}:dlfcn:solaris-shared:-KPIC:-m32 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign -M/usr/lib/ld/map.noexdata:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-+"solaris64-x86_64-cc-sunw","cc:-xO3 -m64 -xstrconst -Xa -DL_ENDIAN::-D_REENTRANT::-lsocket -lnsl -lc -R /lib/openssl/fips-140/64:SIXTY_FOUR_BIT_LONG RC4_CHUNK BF_PTR DES_PTR DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:solaris-shared:-KPIC:-m64 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign -M/usr/lib/ld/map.noexdata:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-+"solaris-sparcv8-cc-sunw","cc:-xtarget=ultra -m32 -Qoption cg -xregs=no%appl -xO5 -xstrconst -xdepend -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -lc -lsoftcrypto -R /lib/openssl/fips-140:BN_LLONG RC4_CHUNK_LL DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-m32 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-+"solaris64-sparcv9-cc-sunw","cc:-xtarget=ultra -m64 -Qoption cg -xregs=no%appl -xO5 -xstrconst -xdepend -xspace -Xa -DB_ENDIAN::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -lc -lsoftcrypto -R /lib/openssl/fips-140/64:BN_LLONG RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-m64 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):/usr/ccs/bin/ar rs::/64",
-+
- #### IRIX 5.x configs
- # -mips2 flag is added by ./config when appropriate.
- "irix-gcc","gcc:-O3 -DB_ENDIAN::(unknown):::BN_LLONG MD2_CHAR RC4_INDEX RC4_CHAR RC4_CHUNK DES_UNROLL DES_RISC2 DES_PTR BF_PTR:${mips32_asm}:o32:dlfcn:irix-shared:::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
--- a/components/openssl/openssl-1.0.1-fips-140/patches/20-remove_rpath.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
---- /export/openssl/openssl-1.0.0d/Makefile.shared	Sat Aug 21 13:36:49 2010
-+++ openssl-1.0.0d/Makefile.shared	Mon Feb 14 14:25:51 2011
-@@ -393,7 +393,7 @@
- 	@ if $(DETECT_GNU_LD); then \
- 		$(DO_GNU_APP); \
- 	else \
--		LDFLAGS="$(CFLAGS) -R $(LIBRPATH)"; \
-+		LDFLAGS="$(CFLAGS)"; \
- 	fi; \
- 	$(LINK_APP)
- 
--- a/components/openssl/openssl-1.0.1-fips-140/patches/23-noexstack.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
---- /tmp/Makefile.shared	Mon Feb 14 14:33:05 2011
-+++ openssl-1.0.0d/Makefile.shared	Mon Feb 14 14:35:56 2011
-@@ -389,6 +389,7 @@
- 		SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX -Wl,-Bsymbolic"; \
- 	fi; \
- 	$(LINK_SO_A)
-+# Make sure the apps have non-executable stacks and data (x86/x64 only).
- link_app.solaris:
- 	@ if $(DETECT_GNU_LD); then \
- 		$(DO_GNU_APP); \
-@@ -395,6 +396,10 @@
- 	else \
- 		LDFLAGS="$(CFLAGS)"; \
- 	fi; \
-+	if expr $(PLATFORM) : '.*x86.*' > /dev/null; then \
-+		LDFLAGS="$${LDFLAGS} -M/usr/lib/ld/map.noexdata"; \
-+	fi; \
-+	LDFLAGS="$${LDFLAGS} -M/usr/lib/ld/map.noexstk -M/usr/lib/ld/map.pagealign"; \
- 	$(LINK_APP)
- 
- # OpenServer 5 native compilers used
--- a/components/openssl/openssl-1.0.1-fips-140/patches/26-openssl_fips.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-#
-# Patch developed in-house.  Solaris-specific; not suitable for upstream. 
-#
---- openssl-0.9.8m/apps/openssl.c	Thu Oct 15 19:28:02 2009
-+++ openssl-0.9.8m/apps/openssl.c	Fri Feb 26 16:12:30 2010
-@@ -135,6 +135,9 @@
- # include <openssl/fips.h>
- #endif
- 
-+/* Solaris OpenSSL */
-+#include <dlfcn.h>
-+
- /*
-  * The LHASH callbacks ("hash" & "cmp") have been replaced by functions with
-  * the base prototypes (we cast each variable inside the function to the
-@@ -155,9 +158,10 @@
- BIO *bio_err = NULL;
- #endif
- 
-+static int *modes;
-+
- 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;
- 
-@@ -167,7 +168,7 @@
-         goto err;
-     }
- 
--    if (type < 0 || type >= CRYPTO_NUM_LOCKS) {
-+    if (type < 0 || type >= CRYPTO_num_locks()) {
-         errstr = "type out of bounds";
-         goto err;
-     }
-@@ -305,6 +306,14 @@
-     if (getenv("OPENSSL_DEBUG_LOCKING") != NULL)
- #endif
-     {
-+        modes = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (int));
-+        if (modes == NULL) {
-+            ERR_load_crypto_strings();
-+            BIO_printf(bio_err,"Memory allocation failure\n");
-+            ERR_print_errors(bio_err);
-+            EXIT(1);
-+        }
-+        memset(modes, 0, CRYPTO_num_locks() * sizeof (int));
-         CRYPTO_set_locking_callback(lock_dbg_cb);
-     }
- 
-@@ -308,18 +320,28 @@
-         CRYPTO_set_locking_callback(lock_dbg_cb);
-     }
- 
-+/*
-+ * Solaris OpenSSL
-+ * Add a further check for the FIPS_mode_set() symbol before calling to
-+ * allow openssl(1openssl) to be run against both fips and non-fips libraries.
-+ */
-     if (getenv("OPENSSL_FIPS")) {
--#ifdef OPENSSL_FIPS
--        if (!FIPS_mode_set(1)) {
-+
-+        int (*FIPS_mode_set)(int);
-+        FIPS_mode_set = (int (*)(int)) dlsym(RTLD_NEXT, "FIPS_mode_set");
-+
-+        if (FIPS_mode_set != NULL) {
-+            if (!(*FIPS_mode_set)(1)) {
-             ERR_load_crypto_strings();
-             ERR_print_errors(BIO_new_fp(stderr, BIO_NOCLOSE));
-             EXIT(1);
-         }
--#else
--        fprintf(stderr, "FIPS mode not supported.\n");
-+    } else {
-+            fprintf(stderr, "Failed to enable FIPS mode. "
-+                "For more information about running in FIPS mode see openssl(5).\n");
-         EXIT(1);
--#endif
-     }
-+    }
- 
-     apps_startup();
- 
--- a/components/openssl/openssl-1.0.1-fips-140/patches/27-6978791.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
---- /tmp/Makefile.shared	Mon Feb 14 14:39:29 2011
-+++ openssl-1.0.0d/Makefile.shared	Mon Feb 14 14:50:52 2011
-@@ -387,6 +387,9 @@
- 		ALLSYMSFLAGS="$${MINUSZ}allextract"; \
- 		NOALLSYMSFLAGS="$${MINUSZ}defaultextract"; \
- 		SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX -Wl,-Bsymbolic"; \
-+		if [ $(LIBNAME) = "ssl" ]; then \
-+			SHAREDFLAGS="$$SHAREDFLAGS $${MINUSZ}nodelete"; \
-+		fi; \
- 	fi; \
- 	$(LINK_SO_A)
- # Make sure the apps have non-executable stacks and data (x86/x64 only).
--- a/components/openssl/openssl-1.0.1-fips-140/patches/28-enginesdir.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-#
-# This was developed in house to configure the engine dir.
-# Not suitable for upstream.
-#
---- /tmp/18/Configure	Fri Feb 11 15:15:50 2011
-+++ openssl-1.0.0d/Configure	Fri Feb 11 15:18:09 2011
-@@ -18,6 +18,8 @@
- #               --prefix option is given; /usr/local/ssl otherwise)
- # --prefix      prefix for the OpenSSL include, lib and bin directories
- #               (Default: the OPENSSLDIR directory)
-+# --enginesdir  engines shared library location
-+#               (Default: $prefix/lib/engines)
- #
- # --pk11-libname  PKCS#11 library name.
- #               (Default: none)
-@@ -679,6 +679,7 @@
- my $prefix="";
- my $libdir="";
- my $openssldir="";
-+my $enginesdir="";
- my $exe_ext="";
- my $install_prefix= "$ENV{'INSTALL_PREFIX'}";
- my $cross_compile_prefix="";
-@@ -917,6 +920,10 @@
- 				{
- 				$openssldir=$1;
- 				}
-+			elsif (/^--enginesdir=(.*)$/)
-+				{
-+				$enginesdir=$1;
-+				}
- 			elsif (/^--install.prefix=(.*)$/)
- 				{
- 				$install_prefix=$1;
-@@ -1224,6 +1231,10 @@
- # we're ready to tolerate, so don't...
- $multilib="" if !-d "$prefix/lib$multilib";
- 
-+if ($enginesdir eq "") {
-+	$enginesdir = "$prefix/lib/engines";
-+}
-+
- $libdir="lib$multilib" if $libdir eq "";
- 
- $cflags = "$cflags$exp_cflags";
-@@ -1846,7 +1857,7 @@
- 		}
- 	elsif	(/^#define\s+ENGINESDIR/)
- 		{
--		my $foo = "$prefix/$libdir/engines";
-+		my $foo = "$enginesdir";
- 		$foo =~ s/\\/\\\\/g;
- 		print OUT "#define ENGINESDIR \"$foo\"\n";
- 		}
--- a/components/openssl/openssl-1.0.1-fips-140/patches/29_fork_safe.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,274 +0,0 @@
-#
-# This file adds the code to setup internal mutexes and callback function.
-#       PSARC/2014/077
-#	PSARC/2015/043
-# This change was implemented in-house.  The issue was brought up to
-# the upstream engineers, but there was no commitment.
-#
---- openssl-1.0.1f/crypto/cryptlib.c.~1~	Fri Feb  7 10:41:36 2014
-+++ openssl-1.0.1f/crypto/cryptlib.c    Thu Feb  6 16:03:58 2014
-@@ -116,6 +116,7 @@
- 
- #include "cryptlib.h"
- #include <openssl/safestack.h>
-+#include <pthread.h>
- 
- #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
- static double SSLeay_MSVC5_hack = 0.0; /* and for VC1.5 */
-@@ -184,6 +185,8 @@
-  */
- static STACK_OF(CRYPTO_dynlock) *dyn_locks = NULL;
- 
-+static pthread_mutex_t *solaris_openssl_locks;
-+
- static void (MS_FAR *locking_callback) (int mode, int type,
-                                         const char *file, int line) = 0;
- static int (MS_FAR *add_lock_callback) (int *pointer, int amount,
-@@ -373,7 +376,10 @@
- void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func)
-                                          (const char *file, int line))
- {
--    dynlock_create_callback = func;
-+	/*
-+	 * We now setup our own dynamic locking callback, and disallow
-+	 * setting of another locking callback.
-+	 */
- }
- 
- void CRYPTO_set_dynlock_lock_callback(void (*func) (int mode,
-@@ -382,7 +388,10 @@
-                                                     const char *file,
-                                                     int line))
- {
--    dynlock_lock_callback = func;
-+	/*
-+	 * We now setup our own dynamic locking callback, and disallow
-+	 * setting of another locking callback.
-+	 */
- }
- 
- void CRYPTO_set_dynlock_destroy_callback(void (*func)
-@@ -389,7 +398,10 @@
-                                           (struct CRYPTO_dynlock_value *l,
-                                            const char *file, int line))
- {
--    dynlock_destroy_callback = func;
-+	/*
-+	 * We now setup our own dynamic locking callback, and disallow
-+	 * setting of another locking callback.
-+	 */
- }
- 
- void (*CRYPTO_get_locking_callback(void)) (int mode, int type,
-@@ -402,6 +414,127 @@
-     return (add_lock_callback);
- }
- 
-+/*
-+ * This is the locking callback function which all applications will be
-+ * using when CRYPTO_lock() is called.
-+ */ 
-+static void solaris_locking_callback(int mode, int type, const char *file,
-+    int line)
-+{
-+	if (mode & CRYPTO_LOCK) {
-+		pthread_mutex_lock(&solaris_openssl_locks[type]);
-+	} else {
-+		pthread_mutex_unlock(&solaris_openssl_locks[type]);
-+	}
-+}
-+
-+/*
-+ * Implement Solaris's own dynamic locking routines.
-+ */
-+static struct CRYPTO_dynlock_value *
-+solaris_dynlock_create(const char *file, int line)
-+{
-+	int		ret;
-+	pthread_mutex_t	*dynlock;
-+
-+	dynlock = OPENSSL_malloc(sizeof(pthread_mutex_t));
-+	if (dynlock == NULL) {
-+		return (NULL);
-+	}
-+
-+	ret = pthread_mutex_init(dynlock, NULL);
-+	OPENSSL_assert(ret);
-+
-+	return ((struct CRYPTO_dynlock_value *)dynlock);
-+}
-+
-+static void
-+solaris_dynlock_lock(int mode, struct CRYPTO_dynlock_value *dynlock,
-+    const char *file, int line)
-+{
-+	int	ret;
-+
-+	if (mode & CRYPTO_LOCK) {
-+		ret = pthread_mutex_lock((pthread_mutex_t *)dynlock);
-+	} else {
-+		ret = pthread_mutex_unlock((pthread_mutex_t *)dynlock);
-+	}
-+
-+	OPENSSL_assert(ret == 0);
-+}
-+
-+static void
-+solaris_dynlock_destroy(struct CRYPTO_dynlock_value *dynlock,
-+    const char *file, int line)
-+{
-+	int	ret;
-+	ret = pthread_mutex_destroy((pthread_mutex_t *)dynlock);
-+	OPENSSL_assert(ret);
-+}
-+
-+/*
-+ * This function is called when a child process is forked to setup its own
-+ * global locking callback function ptr and mutexes.
-+ */
-+static void solaris_fork_child(void)
-+{
-+	/*
-+	 * clear locking_callback to indicate that locks should
-+	 * be reinitialized.
-+	 */
-+	locking_callback = NULL;
-+	solaris_locking_setup();
-+}
-+
-+/*
-+ * This function allocates and initializes the global mutex array, and
-+ * sets the locking callback.
-+ */
-+void solaris_locking_setup()
-+{
-+	int i;
-+	int num_locks;
-+
-+	/* setup the dynlock callback if not already */
-+	if (dynlock_create_callback == NULL) {
-+		dynlock_create_callback = solaris_dynlock_create;
-+	}
-+	if (dynlock_lock_callback == NULL) {
-+		dynlock_lock_callback = solaris_dynlock_lock;
-+	}
-+	if (dynlock_destroy_callback == NULL) {
-+		dynlock_destroy_callback = solaris_dynlock_destroy;
-+	}
-+
-+	/* locking callback is already setup. Nothing to do */
-+	if (locking_callback != NULL) {
-+		return;
-+	}
-+
-+	/*
-+	 * Set atfork handler so that child can setup its own mutexes and
-+	 * locking callbacks when it is forked
-+	 */
-+	(void) pthread_atfork(NULL, NULL, solaris_fork_child);
-+
-+	/* allocate locks needed by OpenSSL  */
-+	num_locks = CRYPTO_num_locks();
-+	solaris_openssl_locks =
-+	    OPENSSL_malloc(sizeof (pthread_mutex_t) * num_locks);
-+	if (solaris_openssl_locks == NULL) {
-+		fprintf(stderr,
-+			"solaris_locking_setup: memory allocation failure.\n");
-+		abort();
-+	}
-+
-+	/* initialize openssl mutexes */
-+	for (i = 0; i < num_locks; i++) {
-+		pthread_mutex_init(&solaris_openssl_locks[i], NULL);
-+	}
-+	locking_callback = solaris_locking_callback;
-+
-+}
-+
- void CRYPTO_set_locking_callback(void (*func) (int mode, int type,
-                                                const char *file, int line))
- {
-@@ -410,7 +543,11 @@
-      * started.
-      */
-     OPENSSL_init();
--    locking_callback = func;
-+
-+	/*
-+	 * we now setup our own locking callback and mutexes, and disallow
-+	 * setting of another locking callback.
-+	 */
- }
- 
- void CRYPTO_set_add_lock_callback(int (*func) (int *num, int mount, int type,
-@@ -471,9 +608,10 @@
- 
- int CRYPTO_THREADID_set_callback(void (*func) (CRYPTO_THREADID *))
- {
--    if (threadid_callback)
--        return 0;
--    threadid_callback = func;
-+    /*
-+     * Use the backup method (the address of 'errno') to identify the
-+     * thread and disallow setting the threadid callback.
-+     */
-     return 1;
- }
- 
-@@ -529,7 +667,10 @@
- 
- void CRYPTO_set_id_callback(unsigned long (*func) (void))
- {
--    id_callback = func;
-+    /*
-+     * Use the backup method (the address of 'errno') to identify the
-+     * thread and disallow setting the threadid callback.
-+     */
- }
- 
- unsigned long CRYPTO_thread_id(void)
-
---- openssl-1.0.1f/crypto/cryptlib.h.~1~	Fri Feb  7 10:41:42 2014
-+++ openssl-1.0.1f/crypto/cryptlib.h    Thu Feb  6 16:04:16 2014
-@@ -104,6 +104,8 @@
- void *OPENSSL_stderr(void);
- extern int OPENSSL_NONPIC_relocated;
-
-+void solaris_locking_setup();
-+
- #ifdef  __cplusplus
- }
- #endif
---- openssl-1.0.1f/crypto/sparccpuid.S.~1~      Fri Feb  7 10:41:37 2014
-+++ openssl-1.0.1f/crypto/sparccpuid.S  Thu Feb  6 16:04:14 2014
-@@ -398,5 +398,7 @@
- .size	OPENSSL_cleanse,.-OPENSSL_cleanse
- 
- .section	".init",#alloc,#execinstr
-+	call	solaris_locking_setup
-+	nop
-	call	OPENSSL_cpuid_setup
-	nop
---- openssl-1.0.1f/crypto/x86_64cpuid.pl.~1~    Wed Feb 12 13:20:09 2014
-+++ openssl-1.0.1f/crypto/x86_64cpuid.pl	Wed Feb 12 13:21:20 2014
-@@ -20,7 +20,10 @@
- print<<___;
- .extern		OPENSSL_cpuid_setup
- .hidden		OPENSSL_cpuid_setup
-+.extern		solaris_locking_setup
-+.hidden		solaris_locking_setup
- .section	.init
-+	call	solaris_locking_setup
-	call	OPENSSL_cpuid_setup
- 
- .hidden	OPENSSL_ia32cap_P
---- openssl-1.0.1f/crypto/x86cpuid.pl.~1~       Wed Feb 12 13:38:03 2014
-+++ openssl-1.0.1f/crypto/x86cpuid.pl   Wed Feb 12 13:38:31 2014
-@@ -353,6 +353,7 @@
- 	&ret	();
- &function_end_B("OPENSSL_ia32_rdrand");
- 
-+&initseg("solaris_locking_setup");
- &initseg("OPENSSL_cpuid_setup");
- 
- &asm_finish();
--- a/components/openssl/openssl-1.0.1-fips-140/patches/32_aes_cbc_len_check.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-#
-# This was developed in house and reported to the upstream.
-#
---- openssl-1.0.1e/crypto/evp/e_aes.c        Tue Jul  2 11:03:12 2013
-+++ openssl-1.0.1e/crypto/evp/e_aes.c.new    Tue Jul  2 11:04:56 2013
-@@ -536,8 +536,12 @@
- static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-                           const unsigned char *in, size_t len)
- {
-+    size_t	bl = ctx->cipher->block_size;
-     EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data;
- 
-+    if (len < bl)
-+        return 1;
-+
-     if (dat->stream.cbc)
-         (*dat->stream.cbc) (in, out, len, &dat->ks, ctx->iv, ctx->encrypt);
-     else if (ctx->encrypt)
--- a/components/openssl/openssl-1.0.1-fips-140/patches/33_cert_chain.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +0,0 @@
-This patch comes from OpenSSL upstream code, and the change has been commited to OpenSSL 1.0.2.
-  http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=fbd2164044f92383955a801ad1b2857d71e83f27
-  http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=51e7a4378a78bb0870a2cdc5c524c230c929ebcb
-  http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=2dabd822366df7b2608b55d5ca5f31d5d484cbaf
-
-Index: openssl/crypto/x509/x509_trs.c
-============================================================================
-$ diff -ru crypto/x509/x509_trs.c crypto/x509/x509_trs.c 
---- openssl/crypto/x509/x509_trs.c.orig    4 Dec 2012 17:26:04 -0000    1.133.2.11.2.6.2.3
-+++ openssl/crypto/x509/x509_trs.c    14 Dec 2012 14:30:45 -0000    1.133.2.11.2.6.2.4
-@@ -119,6 +119,14 @@ int X509_check_trust(X509 *x, int id, int flags)
-     int idx;
-     if (id == -1)
-         return 1;
-+    /* We get this as a default value */
-+    if (id == 0) {
-+        int rv;
-+        rv = obj_trust(NID_anyExtendedKeyUsage, x, 0);
-+        if (rv != X509_TRUST_UNTRUSTED)
-+            return rv;
-+        return trust_compat(NULL, x, 0);
-+    }
-     idx = X509_TRUST_get_by_id(id);
-     if (idx == -1)
-         return default_trust(id, x, flags);
-Index: openssl/crypto/x509/x509_vfy.c
-============================================================================
-$ cvs diff -u -r1.105.2.9.2.4.2.3 -r1.105.2.9.2.4.2.4 x509_vfy.c
---- openssl/crypto/x509/x509_vfy.c    14 Dec 2012 12:53:48 -0000    1.105.2.9.2.4.2.3
-+++ openssl/crypto/x509/x509_vfy.c    14 Dec 2012 14:30:46 -0000    1.105.2.9.2.4.2.4
-@@ -149,6 +149,33 @@
- }
- #endif
- 
-+/* Given a certificate try and find an exact match in the store */
-+
-+static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x)
-+    {
-+    STACK_OF(X509) *certs;
-+    X509 *xtmp = NULL;
-+    int i;
-+    /* Lookup all certs with matching subject name */
-+    certs = ctx->lookup_certs(ctx, X509_get_subject_name(x));
-+    if (certs == NULL)
-+        return NULL;
-+    /* Look for exact match */
-+    for (i = 0; i < sk_X509_num(certs); i++)
-+        {
-+        xtmp = sk_X509_value(certs, i);
-+        if (!X509_cmp(xtmp, x))
-+            break;
-+        }
-+    if (i < sk_X509_num(certs))
-+        CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509);
-+    else
-+        xtmp = NULL;
-+    sk_X509_pop_free(certs, X509_free);
-+    return xtmp;
-+    }
-+
-+
- int X509_verify_cert(X509_STORE_CTX *ctx)
- {
-     X509 *x, *xtmp, *xtmp2, *chain_ss = NULL;
-@@ -304,8 +331,17 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
-         }
-     } while (retry);
- 
--    /* Is last certificate looked up self signed? */
--    if (!ctx->check_issued(ctx, x, x)) {
-+    i = check_trust(ctx);
-+
-+    /* If explicitly rejected error */
-+    if (i == X509_TRUST_REJECTED)
-+        goto end;
-+    /*
-+     * If not explicitly trusted then indicate error unless it's a single
-+     * self signed certificate in which case we've indicated an error already
-+     * and set bad_chain == 1
-+     */
-+    if (i != X509_TRUST_TRUSTED && !bad_chain) {
-         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;
-@@ -340,14 +376,6 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
-     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 */
-@@ -630,28 +658,53 @@ static int check_name_constraints(X509_STORE_CTX *ctx)
- 
- static int check_trust(X509_STORE_CTX *ctx)
- {
--#ifdef OPENSSL_NO_CHAIN_VERIFY
--    return 1;
--#else
-     int i, ok;
--    X509 *x;
-+    X509 *x = NULL;
-     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
-+    /* Check all trusted certificates in chain */
-+    for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++) {
-+        x = sk_X509_value(ctx->chain, i);
-+        ok = X509_check_trust(x, ctx->param->trust, 0);
-+        /* If explicitly trusted return trusted */
-+        if (ok == X509_TRUST_TRUSTED)
-+            return X509_TRUST_TRUSTED;
-+        /*
-+         * If explicitly rejected notify callback and reject if not
-+         * overridden.
-+         */
-+        if (ok == X509_TRUST_REJECTED) {
-+            ctx->error_depth = i;
-+            ctx->current_cert = x;
-+            ctx->error = X509_V_ERR_CERT_REJECTED;
-+            ok = cb(0, ctx);
-+            if (!ok)
-+                return X509_TRUST_REJECTED;
-+        }
-+    }
-+    /*
-+     * If we accept partial chains and have at least one trusted certificate
-+     * return success.
-+     */
-+    if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
-+        X509 *mx;
-+        if (ctx->last_untrusted < sk_X509_num(ctx->chain))
-+            return X509_TRUST_TRUSTED;
-+        x = sk_X509_value(ctx->chain, 0);
-+        mx = lookup_cert_match(ctx, x);
-+        if (mx) {
-+            (void)sk_X509_set(ctx->chain, 0, mx);
-+            X509_free(x);
-+            ctx->last_untrusted = 0;
-+            return X509_TRUST_TRUSTED;
-+        }
-+    }
-+
-+    /*
-+     * If no trusted certs in chain at all return untrusted and allow
-+     * standard (no issuer cert) etc errors to be indicated.
-+     */
-+    return X509_TRUST_UNTRUSTED;
- }
- 
- static int check_revocation(X509_STORE_CTX *ctx)
-@@ -1526,6 +1579,8 @@ static int internal_verify(X509_STORE_CTX *ctx)
-     if (ctx->check_issued(ctx, xi, xi))
-         xs = xi;
-     else {
-+        if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN && n == 0)
-+            return check_cert_time(ctx, xi);
-         if (n <= 0) {
-             ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
-             ctx->current_cert = xi;
-Index: openssl/crypto/x509/x509_vfy.h
-============================================================================
-$ cvs diff -u -r1.67.2.3.4.1 -r1.67.2.3.4.2 x509_vfy.h
---- openssl/crypto/x509/x509_vfy.h    26 Sep 2012 13:50:42 -0000    1.67.2.3.4.1
-+++ openssl/crypto/x509/x509_vfy.h    14 Dec 2012 14:30:46 -0000    1.67.2.3.4.2
-@@ -412,6 +412,9 @@
-  */
- # define X509_V_FLAG_NO_ALT_CHAINS               0x100000
- 
-+/* Allow partial chains if at least one certificate is in trusted store */
-+# define X509_V_FLAG_PARTIAL_CHAIN               0x80000
-+
- # define X509_VP_FLAG_DEFAULT                    0x1
- # define X509_VP_FLAG_OVERWRITE                  0x2
- # define X509_VP_FLAG_RESET_FLAGS                0x4
-Index: openssl/apps/apps.c
-============================================================================
-$ cvs diff -u -r1.133.2.11.2.6.2.3 -r1.133.2.11.2.6.2.4 apps.c
---- openssl/apps/apps.c    4 Dec 2012 17:26:04 -0000    1.133.2.11.2.6.2.3
-+++ openssl/apps/apps.c    14 Dec 2012 14:30:45 -0000    1.133.2.11.2.6.2.4
-@@ -2238,6 +2238,8 @@
-         flags |= X509_V_FLAG_NOTIFY_POLICY;
-     else if (!strcmp(arg, "-check_ss_sig"))
-         flags |= X509_V_FLAG_CHECK_SS_SIGNATURE;
-+    else if (!strcmp(arg, "-partial_chain"))
-+        flags |= X509_V_FLAG_PARTIAL_CHAIN;
-     else if (!strcmp(arg, "-no_alt_chains"))
-         flags |= X509_V_FLAG_NO_ALT_CHAINS;
-     else
--- a/components/openssl/openssl-1.0.1-fips-140/patches/36_evp_leak.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,144 +0,0 @@
-Patch developed in-house.  Solaris-specific; not suitable for upstream.
-
---- openssl-1.0.1f/crypto/evp/evp_enc.c.orig    Mon Feb 11 07:26:04 2013
-+++ openssl-1.0.1f/crypto/evp/evp_enc.c    Mon Feb  3 16:40:48 2014
-@@ -379,11 +379,13 @@
-
-     if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
-         ret = M_do_cipher(ctx, out, NULL, 0);
--        if (ret < 0)
--            return 0;
--        else
-+        if (ret < 0) {
-+            ret = 0;
-+            goto cleanup;
-+        } else
-             *outl = ret;
--        return 1;
-+        ret = 1;
-+        goto cleanup;
-     }
-
-     b = ctx->cipher->block_size;
-@@ -390,7 +392,8 @@
-     OPENSSL_assert(b <= sizeof ctx->buf);
-     if (b == 1) {
-         *outl = 0;
--        return 1;
-+        ret = 1;
-+        goto cleanup;
-     }
-     bl = ctx->buf_len;
-     if (ctx->flags & EVP_CIPH_NO_PADDING) {
-@@ -397,10 +400,12 @@
-         if (bl) {
-             EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX,
-                    EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
--            return 0;
-+            ret = 0;
-+            goto cleanup;
-         }
-         *outl = 0;
--        return 1;
-+        ret = 1;
-+        goto cleanup;
-     }
- 
-     n = b - bl;
-@@ -411,6 +416,11 @@
-     if (ret)
-         *outl = b;
- 
-+cleanup:
-+    if (ctx->cipher->cleanup) {
-+        ctx->cipher->cleanup(ctx);
-+    }
-+
-     return ret;
- }
- 
-@@ -478,6 +488,7 @@
- int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
- {
-     int i, n;
-+    int err = 1;
-     unsigned int b;
-     *outl = 0;
- 
-@@ -483,11 +494,13 @@
-
-     if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
-         i = M_do_cipher(ctx, out, NULL, 0);
--        if (i < 0)
--            return 0;
--        else
-+        if (i < 0) {
-+            err = 0;
-+            goto cleanup;
-+        } else
-             *outl = i;
--        return 1;
-+        err = 1;
-+        goto cleanup;
-     }
-
-     b = ctx->cipher->block_size;
-@@ -495,10 +508,12 @@
-         if (ctx->buf_len) {
-             EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,
-                    EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
--            return 0;
-+            err = 0;
-+            goto cleanup;
-         }
-         *outl = 0;
--        return 1;
-+        err = 1;
-+        goto cleanup;
-     }
-     if (b > 1) {
-         if (ctx->buf_len || !ctx->final_used) {
-@@ -503,7 +518,8 @@
-     if (b > 1) {
-         if (ctx->buf_len || !ctx->final_used) {
-             EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_WRONG_FINAL_BLOCK_LENGTH);
--            return (0);
-+            err = 0;
-+            goto cleanup;
-         }
-         OPENSSL_assert(b <= sizeof ctx->final);
- 
-@@ -514,7 +530,8 @@
-         n = ctx->final[b - 1];
-         if (n == 0 || n > (int)b) {
-             EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT);
--            return (0);
-+            err = 0;
-+            goto cleanup;
-         }
-         for (i = 0; i < n; i++) {
-             if (ctx->final[--b] != n) {
-@@ -519,7 +536,8 @@
-         for (i = 0; i < n; i++) {
-             if (ctx->final[--b] != n) {
-                 EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT);
--                return (0);
-+                err = 0;
-+                goto cleanup;
-             }
-         }
-         n = ctx->cipher->block_size - n;
-@@ -528,7 +546,12 @@
-         *outl = n;
-     } else
-         *outl = 0;
--    return (1);
-+    err = 1;
-+cleanup:
-+    if (ctx->cipher->cleanup) {
-+        ctx->cipher->cleanup(ctx);
-+    }
-+    return err;
- }
- 
- void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
--- a/components/openssl/openssl-1.0.1-fips-140/patches/38_remove_illegal_instruction_calls.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,167 +0,0 @@
-#
-# This patch was developed in house.
-# This is Solaris-specific: not suitable for upstream.
-#
---- openssl-1.0.1g/crypto/sparcv9cap.c.~1~	Thu May  1 13:07:00 2014
-+++ openssl-1.0.1g/crypto/sparcv9cap.c	Thu May  1 13:11:33 2014
-@@ -2,9 +2,9 @@
- #include <stdlib.h>
- #include <string.h>
- #include <setjmp.h>
--#include <signal.h>
- #include <sys/time.h>
- #include <openssl/bn.h>
-+#include <sys/auxv.h>
- 
- #define SPARCV9_TICK_PRIVILEGED (1<<0)
- #define SPARCV9_PREFER_FPU      (1<<1)
-@@ -11,6 +11,7 @@
- #define SPARCV9_VIS1            (1<<2)
- #define SPARCV9_VIS2            (1<<3) /* reserved */
- #define SPARCV9_FMADD           (1<<4) /* reserved for SPARC64 V */
-+#define SPARCV9_BLK             (1<<5)
- 
- static int OPENSSL_sparcv9cap_P = SPARCV9_TICK_PRIVILEGED;
- 
-@@ -31,10 +31,7 @@
- }
-
- unsigned long _sparcv9_rdtick(void);
--void _sparcv9_vis1_probe(void);
- unsigned long _sparcv9_vis1_instrument(void);
--void _sparcv9_vis2_probe(void);
--void _sparcv9_fmadd_probe(void);
- 
- unsigned long OPENSSL_rdtsc(void)
- {
-@@ -170,18 +167,11 @@
-
- #else
-
--static sigjmp_buf common_jmp;
--static void common_handler(int sig)
--{
--    siglongjmp(common_jmp, sig);
--}
--
- void OPENSSL_cpuid_setup(void)
- {
-     char *e;
--    struct sigaction common_act, ill_oact, bus_oact;
--    sigset_t all_masked, oset;
-     static int trigger = 0;
-+    uint_t ui = 0;
-
-     if (trigger)
-         return;
-@@ -192,54 +182,24 @@
-         return;
-     }
- 
-+    (void) getisax(&ui, 1);
-+
-     /* Initial value, fits UltraSPARC-I&II... */
--    OPENSSL_sparcv9cap_P = SPARCV9_PREFER_FPU | SPARCV9_TICK_PRIVILEGED;
-+    OPENSSL_sparcv9cap_P = SPARCV9_BLK;
- 
--    sigfillset(&all_masked);
--    sigdelset(&all_masked, SIGILL);
--    sigdelset(&all_masked, SIGTRAP);
--# ifdef SIGEMT
--    sigdelset(&all_masked, SIGEMT);
--# endif
--    sigdelset(&all_masked, SIGFPE);
--    sigdelset(&all_masked, SIGBUS);
--    sigdelset(&all_masked, SIGSEGV);
--    sigprocmask(SIG_SETMASK, &all_masked, &oset);
--
--    memset(&common_act, 0, sizeof(common_act));
--    common_act.sa_handler = common_handler;
--    common_act.sa_mask = all_masked;
--
--    sigaction(SIGILL, &common_act, &ill_oact);
--    sigaction(SIGBUS, &common_act, &bus_oact); /* T1 fails 16-bit ldda [on
--                                                * Linux] */
--
--    if (sigsetjmp(common_jmp, 1) == 0) {
--        _sparcv9_rdtick();
--        OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
--    }
--
--    if (sigsetjmp(common_jmp, 1) == 0) {
--        _sparcv9_vis1_probe();
--        OPENSSL_sparcv9cap_P |= SPARCV9_VIS1;
--        /* detect UltraSPARC-Tx, see sparccpud.S for details... */
--        if (_sparcv9_vis1_instrument() >= 12)
--            OPENSSL_sparcv9cap_P &= ~(SPARCV9_VIS1 | SPARCV9_PREFER_FPU);
--        else {
--            _sparcv9_vis2_probe();
--            OPENSSL_sparcv9cap_P |= SPARCV9_VIS2;
-+    if (ui & AV_SPARC_VIS) {
-+        /* detect UltraSPARC-Tx, see sparccpuid.S for details... */
-+        if (_sparcv9_vis1_instrument() < 7)
-+            OPENSSL_sparcv9cap_P |= SPARCV9_TICK_PRIVILEGED;
-+        if (_sparcv9_vis1_instrument() < 12) {
-+            OPENSSL_sparcv9cap_P |= SPARCV9_VIS1|SPARCV9_PREFER_FPU;
-+            if (ui & AV_SPARC_VIS2)
-+                OPENSSL_sparcv9cap_P |= SPARCV9_VIS2;
-         }
-     }
- 
--    if (sigsetjmp(common_jmp, 1) == 0) {
--        _sparcv9_fmadd_probe();
-+    if (ui & AV_SPARC_FMAF)
-         OPENSSL_sparcv9cap_P |= SPARCV9_FMADD;
--    }
--
--    sigaction(SIGBUS, &bus_oact, NULL);
--    sigaction(SIGILL, &ill_oact, NULL);
--
--    sigprocmask(SIG_SETMASK, &oset, NULL);
- }
- 
- #endif
---- openssl-1.0.1g/crypto/sparccpuid.S.~1~      Thu May  1 13:07:00 2014
-+++ openssl-1.0.1g/crypto/sparccpuid.S  Thu May  1 13:11:33 2014
-@@ -232,16 +232,6 @@
- .type	_sparcv9_rdtick,#function
- .size	_sparcv9_rdtick,.-_sparcv9_rdtick
- 
--.global	_sparcv9_vis1_probe
--.align	8
--_sparcv9_vis1_probe:
--	add	%sp,BIAS+2,%o1
--	.word	0xc19a5a40	!ldda	[%o1]ASI_FP16_P,%f0
--	retl
--	.word	0x81b00d80	!fxor	%f0,%f0,%f0
--.type	_sparcv9_vis1_probe,#function
--.size	_sparcv9_vis1_probe,.-_sparcv9_vis1_probe
--
- ! Probe and instrument VIS1 instruction. Output is number of cycles it
- ! takes to execute rdtick and pair of VIS1 instructions. US-Tx VIS unit
- ! is slow (documented to be 6 cycles on T2) and the core is in-order
-@@ -296,24 +286,6 @@
- .type	_sparcv9_vis1_instrument,#function
- .size	_sparcv9_vis1_instrument,.-_sparcv9_vis1_instrument
- 
--.global	_sparcv9_vis2_probe
--.align	8
--_sparcv9_vis2_probe:
--	retl
--	.word	0x81b00980	!bshuffle	%f0,%f0,%f0
--.type	_sparcv9_vis2_probe,#function
--.size	_sparcv9_vis2_probe,.-_sparcv9_vis2_probe
--
--.global	_sparcv9_fmadd_probe
--.align	8
--_sparcv9_fmadd_probe:
--	.word	0x81b00d80	!fxor	%f0,%f0,%f0
--	.word	0x85b08d82	!fxor	%f2,%f2,%f2
--	retl
--	.word	0x81b80440	!fmaddd	%f0,%f0,%f2,%f0
--.type	_sparcv9_fmadd_probe,#function
--.size	_sparcv9_fmadd_probe,.-_sparcv9_fmadd_probe
--
- .global	OPENSSL_cleanse
- .align	32
- OPENSSL_cleanse:
--- a/components/openssl/openssl-1.0.1-fips-140/patches/39_test.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-#
-# Patch developed in-house. Solaris-specific; not suitable for upstream.
-#
-# Remove test 'test_ca' because it depends on directories
-# not present in the build directory. The rest of tests are ok.
-#
---- a/test/Makefile.orig	Thu Apr  2 12:11:12 2015
-+++ b/test/Makefile	Thu Apr  2 12:11:21 2015
-@@ -142,7 +142,7 @@
- 	test_rand test_bn test_ec test_ecdsa test_ecdh \
- 	test_enc test_x509 test_rsa test_crl test_sid \
- 	test_gen test_req test_pkcs7 test_verify test_dh test_dsa \
--	test_ss test_ca test_engine test_evp test_evp_extra test_ssl test_tsa test_ige \
-+	test_ss test_engine test_evp test_evp_extra test_ssl test_tsa test_ige \
- 	test_jpake test_srp test_cms test_heartbeat test_constant_time test_verify_extra \
- 	test_clienthello
- 
- test_evp:
--- a/components/openssl/openssl-1.0.1-fips-140/patches/41_uninitialized_ctx.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-#
-# This was developed in house. Upstream notified.
-#
---- openssl-1.0.1m/crypto/evp/evp_enc.c.orig	Tue Jun  2 13:18:15 2015
-+++ openssl-1.0.1m/crypto/evp/evp_enc.c	Tue Jun  2 13:19:19 2015
-@@ -179,6 +179,7 @@
-                 EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE);
-                 return 0;
-             }
-+	    (void) memset(ctx->cipher_data, 0, ctx->cipher->ctx_size);
-         } else {
-             ctx->cipher_data = NULL;
-         }
--- a/components/openssl/openssl-1.0.1-fips-140/patches/42_rm_sslv2.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,526 +0,0 @@
-#
-# This was developed in house.  Not applicable to the upstream.
-#
---- openssl-1.0.1/ssl/ssl.h	Tue May 26 11:13:15 2015
-+++ openssl-1.0.1/ssl/ssl.h.new	Tue May 26 11:32:09 2015
-@@ -2016,12 +2016,28 @@
- /* This sets the 'default' SSL version that SSL_new() will create */
- int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth);
- 
--# ifndef OPENSSL_NO_SSL2_METHOD
--const SSL_METHOD *SSLv2_method(void); /* SSLv2 */
--const SSL_METHOD *SSLv2_server_method(void); /* SSLv2 */
--const SSL_METHOD *SSLv2_client_method(void); /* SSLv2 */
--# endif
-
-+#ifndef __has_attribute
-+# define __has_attribute(x) 0
-+#endif
-+
-+/* Mark SSLv2_* functions deprecated */
-+#if __has_attribute(deprecated) \
-+    || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 301)) \
-+    || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5130))
-+# define DEPRECATED __attribute__((deprecated))
-+#else
-+# define DEPRECATED
-+#endif
-+
-+# ifndef OPENSSL_NO_SSL2
-+# ifndef OPENSSL_NO_SSL2_METHOD
-+DEPRECATED const SSL_METHOD *SSLv2_method(void); /* SSLv2 */
-+DEPRECATED const SSL_METHOD *SSLv2_server_method(void); /* SSLv2 */
-+DEPRECATED const SSL_METHOD *SSLv2_client_method(void); /* SSLv2 */
-+# endif
-+# endif
-+
- # ifndef OPENSSL_NO_SSL3_METHOD
- const SSL_METHOD *SSLv3_method(void); /* SSLv3 */
- const SSL_METHOD *SSLv3_server_method(void); /* SSLv3 */
---- openssl-1.0.1/doc/ssl/SSL_CIPHER_get_name.pod	Tue May 26 11:13:15 2015
-+++ openssl-1.0.1/doc/ssl/SSL_CIPHER_get_name.pod.new	Tue May 26 11:32:09 2015
-@@ -25,7 +25,7 @@
- 
- SSL_CIPHER_get_version() returns string which indicates the SSL/TLS protocol
- version that first defined the cipher.
--This is currently B<SSLv2> or B<TLSv1/SSLv3>.
-+This is currently B<TLSv1/SSLv3>.
- In some cases it should possibly return "TLSv1.2" but does not;
- use SSL_CIPHER_description() instead.
- If B<cipher> is NULL, "(NONE)" is returned.
-@@ -56,7 +56,7 @@
- 
- =item <protocol version>
- 
--Protocol version: B<SSLv2>, B<SSLv3>, B<TLSv1.2>. The TLSv1.0 ciphers are
-+Protocol version: B<SSLv3>, B<TLSv1.2>. The TLSv1.0 ciphers are
- flagged with SSLv3. No new ciphers were added by TLSv1.1.
- 
- =item Kx=<key exchange>
---- openssl-1.0.1/doc/ssl/SSL_CTX_new.pod	Tue Mar  1 14:02:53 2016
-+++ openssl-1.0.1/doc/ssl/SSL_CTX_new.pod.new	Tue Mar  1 14:35:59 2016
-@@ -62,12 +62,12 @@
- These are the general-purpose I<version-flexible> SSL/TLS methods.
- The actual protocol version used will be negotiated to the highest version
- mutually supported by the client and the server.
--The supported protocols are SSLv2, SSLv3, TLSv1, TLSv1.1 and TLSv1.2.
-+The supported protocols are SSLv3, TLSv1, TLSv1.1 and TLSv1.2.
- Most applications should use these method, and avoid the version specific
- methods described below.
- 
- The list of protocols available can be further limited using the
--B<SSL_OP_NO_SSLv2>, B<SSL_OP_NO_SSLv3>, B<SSL_OP_NO_TLSv1>,
-+B<SSL_OP_NO_SSLv3>, B<SSL_OP_NO_TLSv1>,
- B<SSL_OP_NO_TLSv1_1> and B<SSL_OP_NO_TLSv1_2> options of the
- L<SSL_CTX_set_options(3)> or L<SSL_set_options(3)> functions.
- Clients should avoid creating "holes" in the set of protocols they support,
-@@ -81,8 +81,6 @@
- Applications should typically use L<SSL_CTX_set_options(3)> in combination with
- the B<SSL_OP_NO_SSLv3> flag to disable negotiation of SSLv3 via the above
- I<version-flexible> SSL/TLS methods.
--The B<SSL_OP_NO_SSLv2> option is set by default, and would need to be cleared
--via L<SSL_CTX_clear_options(3)> in order to enable negotiation of SSLv2.
- 
- =item TLSv1_2_method(), TLSv1_2_server_method(), TLSv1_2_client_method()
- 
-@@ -115,13 +113,7 @@
- 
- =item SSLv2_method(), SSLv2_server_method(), SSLv2_client_method()
- 
--A TLS/SSL connection established with these methods will only understand the
--SSLv2 protocol.  A client will send out SSLv2 client hello messages and will
--also indicate that it only understand SSLv2.  A server will only understand
--SSLv2 client hello messages.  The SSLv2 protocol offers little to no security
--and should not be used.
--As of OpenSSL 1.0.1s, EXPORT ciphers and 56-bit DES are no longer available
--with SSLv2.
-+The SSLv2 protocol offers little to no security and has been deprecated.
- 
- =item DTLSv1_method(), DTLSv1_server_method(), DTLSv1_client_method()
- 
---- openssl-1.0.1/doc/ssl/SSL_CTX_set_cipher_list.pod	Thu Mar 19 06:37:10 2015
-+++ openssl-1.0.1/doc/ssl/SSL_CTX_set_cipher_list.pod.new	Tue May 26 11:38:09 2015
-@@ -54,10 +54,6 @@
- keys), the "no shared cipher" (SSL_R_NO_SHARED_CIPHER) error is generated
- and the handshake will fail.
- 
--If the cipher list does not contain any SSLv2 cipher suites (this is the
--default) then SSLv2 is effectively disabled and neither clients nor servers
--will attempt to use SSLv2.
--
- =head1 RETURN VALUES
- 
- SSL_CTX_set_cipher_list() and SSL_set_cipher_list() return 1 if any cipher
---- openssl-1.0.1/doc/ssl/SSL_CTX_set_generate_session_id.pod	Thu Jan 15 06:43:49 2015
-+++ openssl-1.0.1/doc/ssl/SSL_CTX_set_generate_session_id.pod.new	Tue May 26 11:40:47 2015
-@@ -32,9 +32,8 @@
- 
- When a new session is established between client and server, the server
- generates a session id. The session id is an arbitrary sequence of bytes.
--The length of the session id is 16 bytes for SSLv2 sessions and between
--1 and 32 bytes for SSLv3/TLSv1. The session id is not security critical
--but must be unique for the server. Additionally, the session id is
-+The length of the session id is between 1 and 32 bytes. The session id is not
-+security critical but must be unique for the server. Additionally, the session id is
- transmitted in the clear when reusing the session so it must not contain
- sensitive information.
- 
-@@ -51,12 +50,6 @@
- the callback B<must never> increase B<id_len> or write to the location
- B<id> exceeding the given limit.
- 
--If a SSLv2 session id is generated and B<id_len> is reduced, it will be
--restored after the callback has finished and the session id will be padded
--with 0x00. It is not recommended to change the B<id_len> for SSLv2 sessions.
--The callback can use the L<SSL_get_version(3)|SSL_get_version(3)> function
--to check, whether the session is of type SSLv2.
--
- The location B<id> is filled with 0x00 before the callback is called, so the
- callback may only fill part of the possible length and leave B<id_len>
- untouched while maintaining reproducibility.
-@@ -63,9 +56,8 @@
- 
- Since the sessions must be distinguished, session ids must be unique.
- Without the callback a random number is used, so that the probability
--of generating the same session id is extremely small (2^128 possible ids
--for an SSLv2 session, 2^256 for SSLv3/TLSv1). In order to assure the
--uniqueness of the generated session id, the callback must call
-+of generating the same session id is extremely small (2^256 for SSLv3/TLSv1).
-+In order to assure the uniqueness of the generated session id, the callback must call
- SSL_has_matching_session_id() and generate another id if a conflict occurs.
- If an id conflict is not resolved, the handshake will fail.
- If the application codes e.g. a unique host id, a unique process number, and
-@@ -85,10 +77,6 @@
- the external cache is not tested with SSL_has_matching_session_id()
- and the same race condition applies.
- 
--When calling SSL_has_matching_session_id() for an SSLv2 session with
--reduced B<id_len>, the match operation will be performed using the
--fixed length required and with a 0x00 padded id.
--
- The callback must return 0 if it cannot generate a session id for whatever
- reason and return 1 on success.
- 
-@@ -104,12 +92,7 @@
-                               unsigned int *id_len)
-       {
-       unsigned int count = 0;
--      const char *version;
- 
--      version = SSL_get_version(ssl);
--      if (!strcmp(version, "SSLv2"))
--	  /* we must not change id_len */;
--
-       do      {
-               RAND_pseudo_bytes(id, *id_len);
-               /* Prefix the session_id with the required prefix. NB: If our
---- openssl-1.0.1/doc/ssl/SSL_CTX_set_options.pod	Tue Jan 20 04:33:36 2015
-+++ openssl-1.0.1/doc/ssl/SSL_CTX_set_options.pod.new	Tue May 26 11:41:47 2015
-@@ -63,18 +63,11 @@
- 
- =item SSL_OP_MICROSOFT_SESS_ID_BUG
- 
--www.microsoft.com - when talking SSLv2, if session-id reuse is
--performed, the session-id passed back in the server-finished message
--is different from the one decided upon.
-+As of OpenSSL 1.0.0 this option has no effect.
- 
- =item SSL_OP_NETSCAPE_CHALLENGE_BUG
- 
--Netscape-Commerce/1.12, when talking SSLv2, accepts a 32 byte
--challenge but then appears to only use 16 bytes when generating the
--encryption keys.  Using 16 bytes is ok but it should be ok to use 32.
--According to the SSLv3 spec, one should use 32 bytes for the challenge
--when operating in SSLv2/v3 compatibility mode, but as mentioned above,
--this breaks this server so 16 bytes is the way to go.
-+As of OpenSSL 1.0.0 this option has no effect.
- 
- =item SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
- 
---- openssl-1.0.1/doc/ssl/SSL_get_default_timeout.pod	Thu Jan 15 06:43:49 2015
-+++ openssl-1.0.1/doc/ssl/SSL_get_default_timeout.pod.new	Tue May 26 11:42:15 2015
-@@ -24,7 +24,7 @@
- timeout for the protocol will be used.
- 
- SSL_get_default_timeout() return this hardcoded value, which is 300 seconds
--for all currently supported protocols (SSLv2, SSLv3, and TLSv1).
-+for all currently supported protocols.
- 
- =head1 RETURN VALUES
- 
---- openssl-1.0.1/doc/ssl/SSL_get_version.pod	Thu Jan 15 06:43:49 2015
-+++ openssl-1.0.1/doc/ssl/SSL_get_version.pod.new	Tue May 26 11:42:45 2015
-@@ -21,9 +21,6 @@
- 
- =over 4
- 
--=item SSLv2
--
--The connection uses the SSLv2 protocol.
- 
- =item SSLv3
- 
---- openssl-1.0.1/doc/ssl/SSL_new.pod	Thu Jan 15 06:43:49 2015
-+++ openssl-1.0.1/doc/ssl/SSL_new.pod.new	Tue May 26 11:43:12 2015
-@@ -14,7 +14,7 @@
- 
- SSL_new() creates a new B<SSL> structure which is needed to hold the
- data for a TLS/SSL connection. The new structure inherits the settings
--of the underlying context B<ctx>: connection method (SSLv2/v3/TLSv1),
-+of the underlying context B<ctx>: connection method,
- options, verification settings, timeout settings.
- 
- =head1 RETURN VALUES
---- openssl-1.0.1/doc/ssl/SSL_shutdown.pod	Thu Mar 19 06:37:10 2015
-+++ openssl-1.0.1/doc/ssl/SSL_shutdown.pod.new	Tue May 26 11:43:56 2015
-@@ -60,9 +60,7 @@
- 
- It is therefore recommended, to check the return value of SSL_shutdown()
- and call SSL_shutdown() again, if the bidirectional shutdown is not yet
--complete (return value of the first call is 0). As the shutdown is not
--specially handled in the SSLv2 protocol, SSL_shutdown() will succeed on
--the first call.
-+complete (return value of the first call is 0).
- 
- The behaviour of SSL_shutdown() additionally depends on the underlying BIO. 
- 
---- openssl-1.0.1/doc/ssl/ssl.pod	Tue Mar  1 05:40:03 2016
-+++ openssl-1.0.1/doc/ssl/ssl.pod.new	Tue Mar  1 15:42:46 2016
-@@ -9,7 +9,7 @@
- 
- =head1 DESCRIPTION
- 
--The OpenSSL B<ssl> library implements the Secure Sockets Layer (SSL v2/v3) and
-+The OpenSSL B<ssl> library implements the Secure Sockets Layer (SSL v3) and
- Transport Layer Security (TLS v1) protocols. It provides a rich API which is
- documented here.
- 
-@@ -45,8 +45,8 @@
- =item B<SSL_METHOD> (SSL Method)
- 
- That's a dispatch structure describing the internal B<ssl> library
--methods/functions which implement the various protocol versions (SSLv1, SSLv2
--and TLSv1). It's needed to create an B<SSL_CTX>.
-+methods/functions which implement the various protocol versions (SSLv3,
-+TLSv1, ...). It's needed to create an B<SSL_CTX>.
- 
- =item B<SSL_CIPHER> (SSL Cipher)
- 
-@@ -93,7 +93,7 @@
- 
- =item B<ssl2.h>
- 
--That's the sub header file dealing with the SSLv2 protocol only.
-+That's the sub header file dealing with the deprecated SSLv2 protocol only.
- I<Usually you don't have to include it explicitly because
- it's already included by ssl.h>.
- 
-@@ -105,8 +105,8 @@
- 
- =item B<ssl23.h>
- 
--That's the sub header file dealing with the combined use of the SSLv2 and
--SSLv3 protocols.
-+That's the sub header file dealing with the combined use of the different
-+protocol versions.
- I<Usually you don't have to include it explicitly because
- it's already included by ssl.h>.
- 
-@@ -201,15 +201,15 @@
- =item const SSL_METHOD *B<SSLv2_method>(void);
- 
- Constructor for the SSLv2 SSL_METHOD structure for clients, servers
--or both.
-+or both. (deprecated)
- 
- =item const SSL_METHOD *B<SSLv2_client_method>(void);
- 
--Constructor for the SSLv2 SSL_METHOD structure for clients.
-+Constructor for the SSLv2 SSL_METHOD structure for clients. (deprecated)
- 
- =item const SSL_METHOD *B<SSLv2_server_method>(void);
- 
--Constructor for the SSLv2 SSL_METHOD structure for servers.
-+Constructor for the SSLv2 SSL_METHOD structure for servers. (deprecated)
- 
- =back
- 
-@@ -234,12 +234,12 @@
- =item const char *B<SSL_CIPHER_get_name>(SSL_CIPHER *cipher);
- 
- Return the internal name of I<cipher> as a string. These are the various
--strings defined by the I<SSL2_TXT_xxx>, I<SSL3_TXT_xxx> and I<TLS1_TXT_xxx>
-+strings defined by the I<SSL3_TXT_xxx> and I<TLS1_TXT_xxx>
- definitions in the header files.
- 
- =item char *B<SSL_CIPHER_get_version>(SSL_CIPHER *cipher);
- 
--Returns a string like "C<TLSv1/SSLv3>" or "C<SSLv2>" which indicates the
-+Returns a string like "C<TLSv1/SSLv3>" which indicates the
- SSL/TLS protocol version to which I<cipher> belongs (i.e. where it was defined
- in the specification the first time).
- 
---- openssl-1.0.1/doc/apps/ciphers.pod	Tue Mar  1 05:40:03 2016
-+++ openssl-1.0.1/doc/apps/ciphers.pod.new	Tue Mar  1 15:28:28 2016
-@@ -9,7 +9,6 @@
- B<openssl> B<ciphers>
- [B<-v>]
- [B<-V>]
--[B<-ssl2>]
- [B<-ssl3>]
- [B<-tls1>]
- [B<cipherlist>]
-@@ -27,12 +26,9 @@
- =item B<-v>
- 
- Verbose option. List ciphers with a complete description of
--protocol version (SSLv2 or SSLv3; the latter includes TLS), key exchange,
-+protocol version, key exchange,
- authentication, encryption and mac algorithms used along with any key size
- restrictions and whether the algorithm is classed as an "export" cipher.
--Note that without the B<-v> option, ciphers may seem to appear twice
--in a cipher list; this is when similar ciphers are available for
--SSL v2 and for SSL v3/TLS v1.
- 
- =item B<-V>
- 
-@@ -42,10 +38,6 @@
- 
- This lists ciphers compatible with any of SSLv3, TLSv1, TLSv1.1 or TLSv1.2.
- 
--=item B<-ssl2>
--
--Only include SSLv2 ciphers.
--
- =item B<-h>, B<-?>
- 
- Print a brief usage message.
-@@ -255,9 +247,9 @@
- ciphers suites using FORTEZZA key exchange, authentication, encryption or all
- FORTEZZA algorithms. Not implemented.
- 
--=item B<TLSv1.2>, B<TLSv1>, B<SSLv3>, B<SSLv2>
-+=item B<TLSv1.2>, B<TLSv1>, B<SSLv3>
- 
--TLS v1.2, TLS v1.0, SSL v3.0 or SSL v2.0 cipher suites respectively. Note:
-+TLS v1.2, TLS v1.0, or SSL v3.0 cipher suites respectively. Note:
- there are no ciphersuites specific to TLS v1.1.
- 
- =item B<AES128>, B<AES256>, B<AES>
-@@ -578,16 +570,6 @@
-  TLS_PSK_WITH_AES_128_CBC_SHA              PSK-AES128-CBC-SHA
-  TLS_PSK_WITH_AES_256_CBC_SHA              PSK-AES256-CBC-SHA
- 
--=head2 Deprecated SSL v2.0 cipher suites.
--
-- SSL_CK_RC4_128_WITH_MD5                 RC4-MD5
-- SSL_CK_RC4_128_EXPORT40_WITH_MD5        Not implemented.
-- SSL_CK_RC2_128_CBC_WITH_MD5             RC2-CBC-MD5
-- SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5    Not implemented.
-- SSL_CK_IDEA_128_CBC_WITH_MD5            IDEA-CBC-MD5
-- SSL_CK_DES_64_CBC_WITH_MD5              Not implemented.
-- SSL_CK_DES_192_EDE3_CBC_WITH_MD5        DES-CBC3-MD5
--
- =head1 NOTES
- 
- The non-ephemeral DH modes are currently unimplemented in OpenSSL
---- openssl-1.0.1/doc/apps/s_client.pod	Tue Mar  1 05:40:03 2016
-+++ openssl-1.0.1/doc/apps/s_client.pod.new	Tue Mar  1 15:37:40 2016
-@@ -32,10 +32,8 @@
- [B<-ign_eof>]
- [B<-no_ign_eof>]
- [B<-quiet>]
--[B<-ssl2>]
- [B<-ssl3>]
- [B<-tls1>]
--[B<-no_ssl2>]
- [B<-no_ssl3>]
- [B<-no_tls1>]
- [B<-bugs>]
-@@ -197,7 +195,7 @@
- given as a hexadecimal number without leading 0x, for example -psk
- 1a2b3c4d.
- 
--=item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2>
-+=item B<-ssl3>, B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2>
- 
- These options require or disable the use of the specified SSL or TLS protocols.
- By default the initial handshake uses a I<version-flexible> method which will
-@@ -215,10 +213,6 @@
- supported cipher in the list sent by the client. See the B<ciphers>
- command for more information.
- 
--=item B<-serverpref>
--
--use the server's cipher preferences; only used for SSLV2.
--
- =item B<-starttls protocol>
- 
- send the protocol-specific message(s) to switch to TLS for communication.
-@@ -295,8 +289,8 @@
- then an HTTP command can be given such as "GET /" to retrieve a web page.
- 
- If the handshake fails then there are several possible causes, if it is
--nothing obvious like no client certificate then the B<-bugs>, B<-ssl2>,
--B<-ssl3>, B<-tls1>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1> options can be tried
-+nothing obvious like no client certificate then the B<-bugs>,
-+B<-ssl3>, B<-tls1>, B<-no_ssl3>, B<-no_tls1> options can be tried
- in case it is a buggy server. In particular you should play with these
- options B<before> submitting a bug report to an OpenSSL mailing list.
- 
-@@ -318,10 +312,6 @@
- If there are problems verifying a server certificate then the
- B<-showcerts> option can be used to show the whole chain.
- 
--Since the SSLv23 client hello cannot include compression methods or extensions
--these will only be supported if its use is disabled, for example by using the
--B<-no_sslv2> option.
--
- The B<s_client> utility is a test tool and is designed to continue the
- handshake after any certificate verification errors. As a result it will
- accept any certificate chain (trusted or not) sent by the peer. None test
---- openssl-1.0.1/doc/apps/s_server.pod	Tue Mar  1 05:40:03 2016
-+++ openssl-1.0.1/doc/apps/s_server.pod.new	Tue Mar  1 15:38:50 2016
-@@ -39,10 +39,8 @@
- [B<-serverpref>]
- [B<-quiet>]
- [B<-no_tmp_rsa>]
--[B<-ssl2>]
- [B<-ssl3>]
- [B<-tls1>]
--[B<-no_ssl2>]
- [B<-no_ssl3>]
- [B<-no_tls1>]
- [B<-no_dhe>]
-@@ -221,7 +219,7 @@
- given as a hexadecimal number without leading 0x, for example -psk
- 1a2b3c4d.
- 
--=item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2>
-+=item B<-ssl3>, B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2>
- 
- These options require or disable the use of the specified SSL or TLS protocols.
- By default the initial handshake uses a I<version-flexible> method which will
---- openssl-1.0.1/doc/apps/s_time.pod	Thu Jan 15 06:43:49 2015
-+++ openssl-1.0.1/doc/apps/s_time.pod.new	Tue May 26 12:20:09 2015
-@@ -19,7 +19,6 @@
- [B<-verify depth>]
- [B<-nbio>]
- [B<-time seconds>]
--[B<-ssl2>]
- [B<-ssl3>]
- [B<-bugs>]
- [B<-cipher cipherlist>]
-@@ -92,18 +90,17 @@
- 
- turns on non-blocking I/O.
- 
--=item B<-ssl2>, B<-ssl3>
-+=item B<-ssl3>
- 
- these options disable the use of certain SSL or TLS protocols. By default
- the initial handshake uses a method which should be compatible with all
--servers and permit them to use SSL v3, SSL v2 or TLS as appropriate.
-+servers and permit them to use SSL v3 or TLS as appropriate.
- The timing program is not as rich in options to turn protocols on and off as
- the L<s_client(1)|s_client(1)> program and may not connect to all servers.
- 
- Unfortunately there are a lot of ancient and broken servers in use which
- cannot handle this technique and will fail to connect. Some servers only
--work if TLS is turned off with the B<-ssl3> option; others
--will only support SSL v2 and may need the B<-ssl2> option.
-+work if TLS is turned off with the B<-ssl3> option.
- 
- =item B<-bugs>
- 
-@@ -137,7 +122,7 @@
- for details.
- 
- If the handshake fails then there are several possible causes, if it is
--nothing obvious like no client certificate then the B<-bugs>, B<-ssl2>,
-+nothing obvious like no client certificate then the B<-bugs>,
- B<-ssl3> options can be tried
- in case it is a buggy server. In particular you should play with these
- options B<before> submitting a bug report to an OpenSSL mailing list.
---- openssl-1.0.1/doc/apps/sess_id.pod	Thu Jan 15 06:43:49 2015
-+++ openssl-1.0.1/doc/apps/sess_id.pod.new	Tue May 26 12:21:07 2015
-@@ -91,7 +91,7 @@
- 
- =item B<Protocol>
- 
--this is the protocol in use TLSv1, SSLv3 or SSLv2.
-+this is the protocol in use TLSv1.2, TLSv1.1, TLSv1 or SSLv3.
- 
- =item B<Cipher>
- 
-@@ -110,10 +110,6 @@
- 
- this is the SSL session master key.
- 
--=item B<Key-Arg>
--
--the key argument, this is only used in SSL v2.
--
- =item B<Start Time>
- 
- this is the session start time represented as an integer in standard Unix format.
--- a/components/openssl/openssl-1.0.1-fips-140/patches/47_xmpp_detection.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-# The patch is based on the following commit from the upstream:
-# https://github.com/openssl/openssl/commit/4e48c77572a9a96a301e362a3646cd3cc7eca0f9 
-# The fix is patched until the new version becomes available
-# from the upstream.
---- a/apps/s_client.c
-+++ b/apps/s_client.c
-@@ -1640,8 +1640,8 @@
-                    "xmlns='jabber:client' to='%s' version='1.0'>", host);
-         seen = BIO_read(sbio, mbuf, BUFSIZZ);
-         mbuf[seen] = 0;
--        while (!strstr
--               (mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'")) {
-+        while (!strstr(mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'") &&
-+               !strstr(mbuf, "<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"")) {
-             if (strstr(mbuf, "/stream:features>"))
-                 goto shut;
-             seen = BIO_read(sbio, mbuf, BUFSIZZ);
--- a/components/openssl/openssl-1.0.1/Makefile	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,410 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
-#
-include ../../../make-rules/shared-macros.mk
-
-COMPONENT_NAME =	openssl
-# When new version of OpenSSL comes in, you must update both COMPONENT_VERSION
-# and IPS_COMPONENT_VERSION.
-# When upgrading OpenSSL, please, DON'T FORGET TO TEST WANBOOT too. 
-# For more information about wanboot-openssl testing, please refer to
-# ../README.
-COMPONENT_VERSION =	1.0.1u
-# Version for IPS. It is easier to do it manually than convert the letter to a
-# number while taking into account that there might be no letter at all.
-IPS_COMPONENT_VERSION = 1.0.1.21
-COMPONENT_PROJECT_URL=	http://www.openssl.org/
-COMPONENT_SRC =		$(COMPONENT_NAME)-$(COMPONENT_VERSION)
-COMPONENT_ARCHIVE =	$(COMPONENT_SRC).tar.gz
-COMPONENT_ARCHIVE_HASH=	\
-    sha256:4312b4ca1215b6f2c97007503d80db80d5157f76f8f7d3febbe6b4c56ff26739
-
-COMPONENT_ARCHIVE_URL =	$(COMPONENT_PROJECT_URL)source/$(COMPONENT_ARCHIVE)
-COMPONENT_BUGDB=	library/openssl
-
-TPNO=			31796
-
-include $(WS_MAKE_RULES)/prep.mk
-include $(WS_MAKE_RULES)/configure.mk
-include $(WS_MAKE_RULES)/ips.mk
-include $(WS_MAKE_RULES)/lint-libraries.mk
-
-PATH=$(SPRO_VROOT)/bin:/usr/bin:/usr/gnu/bin:/usr/perl5/bin
-
-# Variant of OpenSSL for wanboot is built in build/sparcv9-wanboot.
-BUILD_DIR_WANBOOT = $(BUILD_DIR)/$(MACH64)-wanboot
-
-# OpenSSL does not use autoconf but its own configure system.
-CONFIGURE_SCRIPT = $(SOURCE_DIR)/Configure
-
-# This is to force OpenSSL's Configure script to use gmake for 'make links'. 
-# Otherwise it fails with:
-#     mksh: Fatal error in reader: Unmatched `(' on line
-CONFIGURE_ENV += MAKE="$(GMAKE)"
-
-# Used in the configure options below.
-PKCS11_LIB32 = /usr/lib/libpkcs11.so.1
-PKCS11_LIB64 = /usr/lib/64/libpkcs11.so.1
-ENGINESDIR_32 = /lib/openssl/engines
-ENGINESDIR_64 = /lib/openssl/engines/64
-
-# Configure options common to both regular OpenSSL and OpenSSL for wanboot.
-CONFIGURE_OPTIONS =  -DSOLARIS_OPENSSL -DNO_WINDOWS_BRAINDEATH
-CONFIGURE_OPTIONS += --openssldir=/etc/openssl
-CONFIGURE_OPTIONS += --prefix=/usr
-# We use OpenSSL install code for installing only manual pages and we do that
-# for 32-bit version only.
-CONFIGURE_OPTIONS += --install_prefix=$(PROTO_DIR)
-CONFIGURE_OPTIONS += no-ec
-CONFIGURE_OPTIONS += no-ecdh
-CONFIGURE_OPTIONS += no-ecdsa
-CONFIGURE_OPTIONS += no-rc3
-CONFIGURE_OPTIONS += no-rc5
-CONFIGURE_OPTIONS += no-mdc2
-CONFIGURE_OPTIONS += no-idea
-CONFIGURE_OPTIONS += no-hw_4758_cca
-CONFIGURE_OPTIONS += no-hw_aep
-CONFIGURE_OPTIONS += no-hw_atalla
-CONFIGURE_OPTIONS += no-hw_chil
-CONFIGURE_OPTIONS += no-hw_gmp
-CONFIGURE_OPTIONS += no-hw_ncipher
-CONFIGURE_OPTIONS += no-hw_nuron
-CONFIGURE_OPTIONS += no-hw_padlock
-CONFIGURE_OPTIONS += no-hw_sureware
-CONFIGURE_OPTIONS += no-hw_ubsec
-CONFIGURE_OPTIONS += no-hw_cswift
-# MD2 is not enabled by default in OpensSSL but some software we have in
-# Userland needs it. One example is nmap.
-CONFIGURE_OPTIONS += enable-md2
-CONFIGURE_OPTIONS += no-seed
-
-# Disable SSLv2 protocol
-CONFIGURE_OPTIONS += no-ssl2
-
-# We use both no-whirlpool and no-whrlpool since there is an inconsistency in
-# the OpenSSL code and one needs both to build OpenSSL successfully with
-# Whirlpool implementation removed.
-CONFIGURE_OPTIONS += no-whirlpool
-CONFIGURE_OPTIONS += no-whrlpool
-# Some additional options needed for our engines.
-CONFIGURE_OPTIONS += --pk11-libname=$(PKCS11_LIB$(BITS))
-CONFIGURE_OPTIONS += --enginesdir=$(ENGINESDIR_$(BITS))
-
-# We define our own compiler and linker option sets for Solaris. See Configure
-# for more information.
-CONFIGURE_OPTIONS32_i386 =	solaris-x86-cc-sunw
-CONFIGURE_OPTIONS32_sparc =	solaris-sparcv9-cc-sunw
-CONFIGURE_OPTIONS64_i386 =	solaris64-x86_64-cc-sunw
-CONFIGURE_OPTIONS64_sparc =	solaris64-sparcv9-cc-sunw
-
-# Options specific to regular build.
-# They must not be specified as common, as they cannot be overridden.
-$(BUILD_DIR)/$(MACH32)/.configured:	CONFIGURE_OPTIONS += threads
-$(BUILD_DIR)/$(MACH64)/.configured:	CONFIGURE_OPTIONS += threads
-$(BUILD_DIR)/$(MACH32)/.configured:	CONFIGURE_OPTIONS += shared
-$(BUILD_DIR)/$(MACH64)/.configured:	CONFIGURE_OPTIONS += shared
-$(BUILD_DIR)/$(MACH32)/.configured:	CONFIGURE_OPTIONS += shared
-$(BUILD_DIR)/$(MACH64)/.configured:	CONFIGURE_OPTIONS += shared
-$(BUILD_DIR)/$(MACH32)/.configured:	CONFIGURE_OPTIONS += \
-	$(CONFIGURE_OPTIONS32_$(MACH))
-$(BUILD_DIR)/$(MACH64)/.configured:	CONFIGURE_OPTIONS += \
-	$(CONFIGURE_OPTIONS64_$(MACH))
-
-# OpenSSL for wanboot specific options
-$(BUILD_DIR_WANBOOT)/.configured:	BITS=64
-$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += -DNO_CHMOD
-$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += -D_BOOT
-$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += -DOPENSSL_NO_DTLS1
-$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += -DOPENSSL_NO_HEARTBEATS
-$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += -DOPENSSL_NO_SRP
-$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += no-cast
-$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += no-dso
-$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += no-rc4
-$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += no-ripemd
-$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += no-hw
-$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += no-threads
-$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += no-shared
-$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += \
-	solaris64-sparcv9-cc-sunw-wanboot
-
-
-# OpenSSL has its own configure system which must be run from the fully
-# populated source code directory. However, the Userland configuration phase is
-# run from the build directory. So, we must get the full source code into the
-# build directory.
-COMPONENT_PRE_CONFIGURE_ACTION = \
-    ( $(CLONEY) $(SOURCE_DIR) $(BUILD_DIR)/$(MACH$(BITS)); )
-
-$(BUILD_DIR_WANBOOT)/.configured:	COMPONENT_PRE_CONFIGURE_ACTION = \
-	    ( $(CLONEY) $(SOURCE_DIR) $(BUILD_DIR_WANBOOT); )
-
-# We deliver only one opensslconf.h file which must be suitable for both 32 and
-# 64 bits. Depending on the configuration option, OpenSSL's Configure script
-# creates opensslconf.h for either 32 or 64 bits. A patch makes the resulting
-# header file usable on both architectures. The patch was generated against the
-# opensslconf.h version from the 32 bit build.
-COMPONENT_POST_CONFIGURE_ACTION = \
-    ( [ $(BITS) -eq 32 ] && $(GPATCH) -p1 $(@D)/crypto/opensslconf.h \
-      patches-post-config/opensslconf.patch; cd $(@D); $(MAKE) depend; )
-
-
-# We do not ship our engines as patches since it would be more difficult to
-# update the files which have been under continuous development. We rather copy
-# the files to the right directories.
-# Same holds for wanboot-stubs.c, which stubs out several functions, that are
-# not available in the stand-alone environment of wanboot.
-#
-# We generally use symbolic links for the Solaris-specific files added below.
-# But 45-use-srln.patch patches dest4-sparcv9.pl and sparcv9_modes.pl and 11.3's
-# version of 'patch' does not patch symlinks.  So we copy these 2 files instead.
-COMPONENT_POST_UNPACK_ACTION = \
-    ( echo "Cloning engines..."; \
-      $(LN) -fs $(COMPONENT_DIR)/engines/pkcs11/*.[ch]		$(@D)/engines; \
-      $(LN) -fs $(COMPONENT_DIR)/wanboot-openssl/wanboot-stubs.c	$(@D)/crypto; \
-      $(LN) -fs $(COMPONENT_DIR)/inline-t4/sparc_arch.h			$(@D)/crypto/; \
-      $(LN) -fs $(COMPONENT_DIR)/inline-t4/md5-sparcv9.pl		$(@D)/crypto/md5/asm; \
-      $(LN) -fs $(COMPONENT_DIR)/inline-t4/aest4-sparcv9.pl		$(@D)/crypto/aes/asm; \
-      $(CP) $(COMPONENT_DIR)/inline-t4/dest4-sparcv9.pl		$(@D)/crypto/des/asm; \
-      $(CP) $(COMPONENT_DIR)/inline-t4/sparcv9_modes.pl		$(@D)/crypto/perlasm; \
-      $(LN) -fs $(COMPONENT_DIR)/inline-t4/vis3-mont.pl			$(@D)/crypto/bn/asm; \
-      $(LN) -fs $(COMPONENT_DIR)/inline-t4/sparcv9-gf2m.pl		$(@D)/crypto/bn/asm; \
-      $(LN) -fs $(COMPONENT_DIR)/inline-t4/sparct4-mont.pl		$(@D)/crypto/bn/asm; )
-
-# Enable ASLR for this component
-ASLR_MODE =	$(ASLR_ENABLE)
-
-# OpenSSL for wanboot is built on sparc only.
-ifeq ($(MACH), sparc)
-BUILD_64 +=	$(BUILD_DIR_WANBOOT)/.built
-endif
-
-build:		$(BUILD_32_and_64)
-
-# Object files for wanboot-openssl.o have to be listed explicitly.
-WANBOOT_OBJS =  \
-    crypto/aes/aes-sparcv9.o crypto/aes/aes_cbc.o crypto/aes/aes_core.o \
-    crypto/aes/aes_misc.o crypto/aes/aes_wrap.o crypto/aes/aest4-sparcv9.o \
-    crypto/asn1/a_bitstr.o \
-    crypto/asn1/a_bool.o crypto/asn1/a_bytes.o crypto/asn1/a_d2i_fp.o \
-    crypto/asn1/a_digest.o crypto/asn1/a_dup.o crypto/asn1/a_enum.o \
-    crypto/asn1/a_gentm.o crypto/asn1/a_i2d_fp.o crypto/asn1/a_int.o \
-    crypto/asn1/a_mbstr.o crypto/asn1/a_object.o crypto/asn1/a_octet.o \
-    crypto/asn1/a_print.o crypto/asn1/a_set.o crypto/asn1/a_sign.o \
-    crypto/asn1/a_strex.o crypto/asn1/a_strnid.o crypto/asn1/a_time.o \
-    crypto/asn1/a_type.o crypto/asn1/a_utctm.o crypto/asn1/a_utf8.o \
-    crypto/asn1/a_verify.o crypto/asn1/ameth_lib.o crypto/asn1/asn1_err.o \
-    crypto/asn1/asn1_gen.o crypto/asn1/asn1_lib.o crypto/asn1/asn1_par.o \
-    crypto/asn1/asn_mime.o crypto/asn1/asn_pack.o crypto/asn1/bio_asn1.o \
-    crypto/asn1/bio_ndef.o crypto/asn1/d2i_pr.o crypto/asn1/evp_asn1.o \
-    crypto/asn1/f_int.o crypto/asn1/f_string.o crypto/asn1/i2d_pr.o \
-    crypto/asn1/nsseq.o crypto/asn1/p5_pbe.o crypto/asn1/p5_pbev2.o \
-    crypto/asn1/p8_pkey.o crypto/asn1/t_pkey.o crypto/asn1/t_x509.o \
-    crypto/asn1/t_x509a.o crypto/asn1/tasn_dec.o crypto/asn1/tasn_enc.o \
-    crypto/asn1/tasn_fre.o crypto/asn1/tasn_new.o crypto/asn1/tasn_prn.o \
-    crypto/asn1/tasn_typ.o crypto/asn1/tasn_utl.o crypto/asn1/x_algor.o \
-    crypto/asn1/x_attrib.o crypto/asn1/x_bignum.o crypto/asn1/x_crl.o \
-    crypto/asn1/x_exten.o crypto/asn1/x_info.o crypto/asn1/x_long.o \
-    crypto/asn1/x_name.o crypto/asn1/x_pkey.o crypto/asn1/x_pubkey.o \
-    crypto/asn1/x_req.o crypto/asn1/x_sig.o crypto/asn1/x_spki.o \
-    crypto/asn1/x_val.o crypto/asn1/x_x509.o crypto/asn1/x_x509a.o \
-    crypto/bf/bf_cfb64.o crypto/bf/bf_ecb.o crypto/bf/bf_enc.o \
-    crypto/bf/bf_ofb64.o crypto/bf/bf_skey.o crypto/bio/b_dump.o \
-    crypto/bio/b_print.o crypto/bio/bf_buff.o crypto/bio/bio_err.o \
-    crypto/bio/bio_lib.o crypto/bio/bss_file.o crypto/bio/bss_mem.o \
-    crypto/bio/bss_null.o crypto/bio/bss_sock.o crypto/bn/bn-sparcv9.o \
-    crypto/bn/bn_add.o crypto/bn/bn_blind.o crypto/bn/bn_ctx.o \
-    crypto/bn/bn_div.o crypto/bn/bn_err.o crypto/bn/bn_exp.o \
-    crypto/bn/bn_exp2.o crypto/bn/bn_gcd.o crypto/bn/bn_lib.o \
-    crypto/bn/bn_mod.o crypto/bn/bn_mont.o crypto/bn/bn_mul.o \
-    crypto/bn/bn_prime.o crypto/bn/bn_print.o crypto/bn/bn_rand.o \
-    crypto/bn/bn_recp.o crypto/bn/bn_shift.o crypto/bn/bn_sqr.o \
-    crypto/bn/bn_word.o crypto/bn/sparcv9-mont.o crypto/bn/sparcv9a-mont.o \
-    crypto/bn/sparct4-mont.o crypto/bn/vis3-mont.o \
-    crypto/buffer/buf_err.o crypto/buffer/buf_str.o crypto/buffer/buffer.o \
-    crypto/camellia/camellia.o crypto/camellia/cmll_cbc.o \
-    crypto/camellia/cmll_cfb.o crypto/camellia/cmll_ecb.o \
-    crypto/camellia/cmll_misc.o crypto/camellia/cmll_ofb.o \
-    crypto/camellia/cmll_utl.o crypto/cmac/cm_ameth.o crypto/cmac/cm_pmeth.o \
-    crypto/cmac/cmac.o crypto/cms/cms_asn1.o crypto/cms/cms_att.o \
-    crypto/cms/cms_dd.o crypto/cms/cms_enc.o crypto/cms/cms_env.o \
-    crypto/cms/cms_err.o crypto/cms/cms_io.o crypto/cms/cms_lib.o \
-    crypto/cms/cms_pwri.o crypto/cms/cms_sd.o crypto/comp/c_zlib.o \
-    crypto/comp/comp_err.o crypto/comp/comp_lib.o crypto/conf/conf_api.o \
-    crypto/conf/conf_def.o crypto/conf/conf_err.o crypto/conf/conf_lib.o \
-    crypto/conf/conf_mod.o crypto/cpt_err.o crypto/cryptlib.o \
-    crypto/des/cfb64ede.o crypto/des/cfb64enc.o crypto/des/cfb_enc.o \
-    crypto/des/des_enc-sparc.o crypto/des/ecb3_enc.o crypto/des/ecb_enc.o \
-    crypto/des/ofb64ede.o crypto/des/ofb64enc.o crypto/des/dest4-sparcv9.o \
-    crypto/des/set_key.o \
-    crypto/des/xcbc_enc.o crypto/dh/dh_ameth.o crypto/dh/dh_asn1.o \
-    crypto/dh/dh_check.o crypto/dh/dh_err.o crypto/dh/dh_gen.o \
-    crypto/dh/dh_key.o crypto/dh/dh_lib.o crypto/dh/dh_pmeth.o \
-    crypto/dsa/dsa_ameth.o crypto/dsa/dsa_asn1.o crypto/dsa/dsa_err.o \
-    crypto/dsa/dsa_gen.o crypto/dsa/dsa_key.o crypto/dsa/dsa_lib.o \
-    crypto/dsa/dsa_ossl.o crypto/dsa/dsa_pmeth.o crypto/dsa/dsa_sign.o \
-    crypto/dsa/dsa_vrf.o crypto/dso/dso_lib.o crypto/dso/dso_null.o \
-    crypto/dso/dso_openssl.o crypto/engine/eng_ctrl.o crypto/engine/eng_err.o \
-    crypto/engine/eng_init.o crypto/engine/eng_lib.o crypto/engine/eng_list.o \
-    crypto/engine/eng_pkey.o crypto/engine/eng_table.o \
-    crypto/engine/tb_asnmth.o crypto/engine/tb_cipher.o crypto/engine/tb_dh.o \
-    crypto/engine/tb_digest.o crypto/engine/tb_dsa.o \
-    crypto/engine/tb_pkmeth.o crypto/engine/tb_rand.o crypto/engine/tb_rsa.o \
-    crypto/err/err.o crypto/err/err_all.o crypto/err/err_prn.o \
-    crypto/evp/bio_b64.o crypto/evp/bio_enc.o crypto/evp/bio_md.o \
-    crypto/evp/c_all.o crypto/evp/c_allc.o crypto/evp/c_alld.o \
-    crypto/evp/digest.o crypto/evp/e_aes.o crypto/evp/e_aes_cbc_hmac_sha1.o \
-    crypto/evp/e_bf.o crypto/evp/e_camellia.o crypto/evp/e_des.o \
-    crypto/evp/e_des3.o crypto/evp/e_null.o crypto/evp/e_rc2.o \
-    crypto/evp/e_xcbc_d.o crypto/evp/encode.o crypto/evp/evp_enc.o \
-    crypto/evp/evp_err.o crypto/evp/evp_key.o crypto/evp/evp_lib.o \
-    crypto/evp/evp_pbe.o crypto/evp/evp_pkey.o crypto/evp/m_dss.o \
-    crypto/evp/m_dss1.o crypto/evp/m_md4.o crypto/evp/m_md5.o \
-    crypto/evp/m_sha.o crypto/evp/m_sha1.o crypto/evp/m_sigver.o \
-    crypto/evp/names.o crypto/evp/p5_crpt.o crypto/evp/p5_crpt2.o \
-    crypto/evp/p_lib.o crypto/evp/p_sign.o crypto/evp/p_verify.o \
-    crypto/evp/pmeth_fn.o crypto/evp/pmeth_gn.o crypto/evp/pmeth_lib.o \
-    crypto/ex_data.o crypto/hmac/hm_ameth.o crypto/hmac/hm_pmeth.o \
-    crypto/hmac/hmac.o crypto/lhash/lhash.o crypto/md4/md4_dgst.o \
-    crypto/md5/md5-sparcv9.o \
-    crypto/md5/md5_dgst.o crypto/mem.o crypto/mem_dbg.o crypto/modes/cbc128.o \
-    crypto/modes/ccm128.o crypto/modes/cfb128.o crypto/modes/ctr128.o \
-    crypto/modes/gcm128.o crypto/modes/ghash-sparcv9.o crypto/modes/ofb128.o \
-    crypto/modes/xts128.o crypto/o_dir.o crypto/o_init.o crypto/o_time.o \
-    crypto/objects/o_names.o crypto/objects/obj_dat.o \
-    crypto/objects/obj_err.o crypto/objects/obj_lib.o \
-    crypto/objects/obj_xref.o crypto/ocsp/ocsp_asn.o crypto/ocsp/ocsp_err.o \
-    crypto/pem/pem_all.o crypto/pem/pem_err.o crypto/pem/pem_info.o \
-    crypto/pem/pem_lib.o crypto/pem/pem_oth.o crypto/pem/pem_pk8.o \
-    crypto/pem/pem_pkey.o crypto/pem/pem_x509.o crypto/pem/pem_xaux.o \
-    crypto/pkcs12/p12_add.o crypto/pkcs12/p12_asn.o crypto/pkcs12/p12_attr.o \
-    crypto/pkcs12/p12_crpt.o crypto/pkcs12/p12_decr.o crypto/pkcs12/p12_key.o \
-    crypto/pkcs12/p12_mutl.o crypto/pkcs12/p12_p8d.o crypto/pkcs12/p12_p8e.o \
-    crypto/pkcs12/p12_utl.o crypto/pkcs12/pk12err.o crypto/pkcs7/pk7_asn1.o \
-    crypto/pkcs7/pk7_attr.o crypto/pkcs7/pk7_doit.o crypto/pkcs7/pk7_lib.o \
-    crypto/pkcs7/pkcs7err.o crypto/pqueue/pqueue.o crypto/rand/md_rand.o \
-    crypto/rand/rand_err.o crypto/rand/rand_lib.o crypto/rand/rand_unix.o \
-    crypto/rand/randfile.o crypto/rc2/rc2_cbc.o crypto/rc2/rc2_ecb.o \
-    crypto/rc2/rc2_skey.o crypto/rc2/rc2cfb64.o crypto/rc2/rc2ofb64.o \
-    crypto/rsa/rsa_ameth.o crypto/rsa/rsa_asn1.o crypto/rsa/rsa_crpt.o \
-    crypto/rsa/rsa_eay.o crypto/rsa/rsa_err.o crypto/rsa/rsa_gen.o \
-    crypto/rsa/rsa_lib.o crypto/rsa/rsa_none.o crypto/rsa/rsa_oaep.o \
-    crypto/rsa/rsa_pk1.o crypto/rsa/rsa_pmeth.o crypto/rsa/rsa_pss.o \
-    crypto/rsa/rsa_saos.o crypto/rsa/rsa_sign.o crypto/rsa/rsa_ssl.o \
-    crypto/rsa/rsa_x931.o crypto/sha/sha1-sparcv9.o crypto/sha/sha1dgst.o \
-    crypto/sha/sha256-sparcv9.o crypto/sha/sha256.o \
-    crypto/sha/sha512-sparcv9.o crypto/sha/sha512.o crypto/sha/sha_dgst.o \
-    crypto/sparccpuid.o crypto/sparcv9cap.o crypto/srp/srp_lib.o \
-    crypto/srp/srp_vfy.o crypto/stack/stack.o crypto/ts/ts_err.o \
-    crypto/txt_db/txt_db.o crypto/ui/ui_err.o crypto/wanboot-stubs.o \
-    crypto/x509/by_dir.o crypto/x509/by_file.o crypto/x509/x509_att.o \
-    crypto/x509/x509_cmp.o crypto/x509/x509_d2.o crypto/x509/x509_def.o \
-    crypto/x509/x509_err.o crypto/x509/x509_ext.o crypto/x509/x509_lu.o \
-    crypto/x509/x509_obj.o crypto/x509/x509_req.o crypto/x509/x509_trs.o \
-    crypto/x509/x509_txt.o crypto/x509/x509_v3.o crypto/x509/x509_vfy.o \
-    crypto/x509/x509_vpm.o crypto/x509/x509name.o crypto/x509/x509rset.o \
-    crypto/x509/x509type.o crypto/x509/x_all.o crypto/x509v3/pcy_cache.o \
-    crypto/x509v3/pcy_data.o crypto/x509v3/pcy_lib.o crypto/x509v3/pcy_map.o \
-    crypto/x509v3/pcy_node.o crypto/x509v3/pcy_tree.o crypto/x509v3/v3_akey.o \
-    crypto/x509v3/v3_akeya.o crypto/x509v3/v3_alt.o crypto/x509v3/v3_bcons.o \
-    crypto/x509v3/v3_bitst.o crypto/x509v3/v3_conf.o crypto/x509v3/v3_cpols.o \
-    crypto/x509v3/v3_crld.o crypto/x509v3/v3_enum.o crypto/x509v3/v3_extku.o \
-    crypto/x509v3/v3_genn.o crypto/x509v3/v3_ia5.o crypto/x509v3/v3_info.o \
-    crypto/x509v3/v3_int.o crypto/x509v3/v3_lib.o crypto/x509v3/v3_ncons.o \
-    crypto/x509v3/v3_ocsp.o crypto/x509v3/v3_pci.o crypto/x509v3/v3_pcia.o \
-    crypto/x509v3/v3_pcons.o crypto/x509v3/v3_pku.o crypto/x509v3/v3_pmaps.o \
-    crypto/x509v3/v3_prn.o crypto/x509v3/v3_purp.o crypto/x509v3/v3_skey.o \
-    crypto/x509v3/v3_sxnet.o crypto/x509v3/v3_utl.o crypto/x509v3/v3err.o \
-    ssl/s3_both.o ssl/s3_clnt.o ssl/s3_enc.o ssl/s3_lib.o ssl/s3_pkt.o \
-    ssl/ssl_algs.o ssl/ssl_asn1.o ssl/ssl_cert.o ssl/ssl_ciph.o ssl/ssl_err.o \
-    ssl/ssl_err2.o ssl/ssl_lib.o ssl/ssl_rsa.o ssl/ssl_sess.o ssl/t1_enc.o \
-    ssl/t1_lib.o ssl/t1_reneg.o ssl/d1_srtp.o ssl/s3_cbc.o ssl/t1_clnt.o
-
-# Linking of openssl bits for wanboot.
-# Interface for wanboot is specified in mapfile.wanboot. Object files are
-# compiled to have functions in separate sections, unused sections get
-# discarded.
-CREATE_BIG_OBJECT_FILE = ( \
-    cd $(BUILD_DIR_WANBOOT); \
-    $(LD) -o wanboot-openssl.o -r -M../../mapfile.wanboot -Breduce \
-        -zdiscard-unused=sections,files -zguidance \
-        $(WANBOOT_OBJS); \
-    )
-
-$(BUILD_DIR_WANBOOT)/.built:	COMPONENT_POST_BUILD_ACTION = \
-    ($(CREATE_BIG_OBJECT_FILE); )
-
-# OpenSSL uses sections man[1357] by default so we must create the man
-# directories we use for OpenSSL man pages in Solaris. Note that we patch the
-# OpenSSL man page install script to use the correct directories.
-MANDIR_SECTIONS =  $(PROTO_DIR)/usr/share/man/man1openssl
-MANDIR_SECTIONS += $(PROTO_DIR)/usr/share/man/man3openssl
-MANDIR_SECTIONS += $(PROTO_DIR)/usr/share/man/man5openssl
-MANDIR_SECTIONS += $(PROTO_DIR)/usr/share/man/man7openssl
-
-# We must create man page directories manually since we patched OpenSSL install
-# code to install into manXopenssl instead of manX. Also, OpenSSL does not
-# install into <dir>/$(MACH64) for 64-bit install so no such directory is
-# created and Userland install code would fail when installing lint libraries.
-COMPONENT_PRE_INSTALL_ACTION = ( $(MKDIR) $(MANDIR_SECTIONS); \
-    $(MKDIR) $(PROTO_DIR)/usr/lib/$(MACH64); )
-
-# The install_docs target will install man pages into $(PROTO_DIR)/$(MANDIR). We
-# also add /usr/perl5/bin to PATH so that OpenSSL install code can locate the
-# system pod2man. If not set, OpenSSL make would use an internal implementation
-# from the tarball which would corrupt some man pages.
-COMPONENT_INSTALL_ARGS += PATH=$(PATH) MANDIR=/usr/share/man
-
-WANBOOT_TO      = $(PROTO_DIR)/lib/openssl/wanboot/$(MACH64)
-
-# We could run OpenSSL install code for 32 bits only to process header files and
-# manual pages. However, lint libraries depend on install stamps so we run
-# install for 64 bit as well. Note that we must take built binary files from
-# build directories, not from the proto area which contains whatever was
-# installed first.
-# OpenSSL for wanboot is built on sparc only.
-ifeq ($(MACH), sparc)
-install:	$(INSTALL_32_and_64) $(BUILD_DIR_WANBOOT)/.built
-	$(MKDIR) -p $(WANBOOT_TO);
-	$(CP) $(BUILD_DIR_WANBOOT)/wanboot-openssl.o $(WANBOOT_TO);
-else
-install:	$(INSTALL_32_and_64)
-endif
-
-# We need to modify the default lint flags to include patched opensslconf.h from
-# the build directory. If we do not do that, lint will complain about md2.h
-# which is not enabled by default but it is in our opensslconf.h.
-LFLAGS_32 := -I$(BUILD_DIR_32)/include $(LINT_FLAGS) -lsoftcrypto
-LFLAGS_64 := -I$(BUILD_DIR_64)/include $(LINT_FLAGS) -lsoftcrypto
-
-# Set modified lint flags for our lint library targets.
-$(BUILD_DIR_32)/llib-lcrypto.ln: LINT_FLAGS=$(LFLAGS_32)
-$(BUILD_DIR_32)/llib-lssl.ln: LINT_FLAGS=$(LFLAGS_32)
-$(BUILD_DIR_64)/llib-lcrypto.ln: LINT_FLAGS=$(LFLAGS_64)
-$(BUILD_DIR_64)/llib-lssl.ln: LINT_FLAGS=$(LFLAGS_64)
-
-# There are also separate STC test suites 'openssl' and 'openssl-engine'
-# for regression testing. These internal tests are unit tests only.
-COMPONENT_TEST_TARGETS = test
-test:		$(TEST_32_and_64)
-
-
-REQUIRED_PACKAGES += system/library
--- a/components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11.c	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3711 +0,0 @@
-/*
- * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* crypto/engine/e_pk11.c */
-/*
- * This product includes software developed by the OpenSSL Project for
- * use in the OpenSSL Toolkit (http://www.openssl.org/).
- *
- * This project also referenced hw_pkcs11-0.9.7b.patch written by
- * Afchine Madjlessi.
- */
-/*
- * ====================================================================
- * 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
- *    [email protected].
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * ([email protected]).  This product includes software written by Tim
- * Hudson ([email protected]).
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <strings.h>
-
-#include <openssl/e_os2.h>
-#include <openssl/crypto.h>
-#include <openssl/engine.h>
-#include <openssl/dso.h>
-#include <openssl/err.h>
-#include <openssl/bn.h>
-#include <openssl/md5.h>
-#include <openssl/pem.h>
-#ifndef OPENSSL_NO_RSA
-#include <openssl/rsa.h>
-#endif
-#ifndef OPENSSL_NO_DSA
-#include <openssl/dsa.h>
-#endif
-#ifndef OPENSSL_NO_DH
-#include <openssl/dh.h>
-#endif
-#include <openssl/rand.h>
-#include <openssl/objects.h>
-#include <openssl/x509.h>
-#include <openssl/aes.h>
-#include <dlfcn.h>
-#include <pthread.h>
-
-#ifndef OPENSSL_NO_HW
-#ifndef OPENSSL_NO_HW_PK11
-
-/* label for debug messages printed on stderr */
-#define	PK11_DBG	"PKCS#11 ENGINE DEBUG"
-/* prints a lot of debug messages on stderr about slot selection process */
-#undef	DEBUG_SLOT_SELECTION
-/*
- * Solaris specific code. See comment at check_hw_mechanisms() for more
- * information.
- */
-#if defined(__SVR4) && defined(__sun)
-#define	SOLARIS_HW_SLOT_SELECTION
-#endif
-
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-#include <sys/auxv.h>
-#endif
-
-#ifdef DEBUG_SLOT_SELECTION
-#define	DEBUG_SLOT_SEL(...) fprintf(stderr, __VA_ARGS__)
-#else
-#define	DEBUG_SLOT_SEL(...)
-#endif
-
-#include <security/cryptoki.h>
-#include <security/pkcs11.h>
-#include "e_pk11.h"
-#include "e_pk11_uri.h"
-
-static CK_BBOOL pk11_true = CK_TRUE;
-static CK_BBOOL pk11_false = CK_FALSE;
-#define	PK11_ENGINE_LIB_NAME "PKCS#11 engine"
-#include "e_pk11_err.c"
-#include "e_pk11_uri.c"
-#include "e_pk11_pub.c"
-
-/*
- * We use this lock to prevent multiple C_Login()s, guard getpassphrase(),
- * uri_struct manipulation, and static token info. All of that is used by the
- * RSA keys by reference feature.
- */
-pthread_mutex_t *uri_lock = NULL;
-
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-/*
- * Tables for symmetric ciphers and digest mechs found in the pkcs11_kernel
- * library. See comment at check_hw_mechanisms() for more information.
- */
-int *hw_cnids;
-int *hw_dnids;
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-
-/* PKCS#11 session caches and their locks for all operation types */
-static PK11_CACHE session_cache[OP_MAX];
-
-/*
- * We cache the flags so that we do not have to run C_GetTokenInfo() again when
- * logging into the token.
- */
-CK_FLAGS pubkey_token_flags;
-
-/*
- * As stated in v2.20, 11.7 Object Management Function, in section for
- * C_FindObjectsInit(), at most one search operation may be active at a given
- * time in a given session. Therefore, C_Find{,Init,Final}Objects() should be
- * grouped together to form one atomic search operation. This is already
- * ensured by the property of unique PKCS#11 session handle used for each
- * PK11_SESSION object.
- *
- * This is however not the biggest concern - maintaining consistency of the
- * underlying object store is more important. The same section of the spec also
- * says that one thread can be in the middle of a search operation while another
- * thread destroys the object matching the search template which would result in
- * invalid handle returned from the search operation.
- *
- * Hence, the following locks are used for both protection of the object stores.
- * They are also used for active list protection.
- */
-pthread_mutex_t *find_lock[OP_MAX] = { NULL };
-
-/*
- * lists of asymmetric key handles which are active (referenced by at least one
- * PK11_SESSION structure, either held by a thread or present in free_session
- * list) for given algorithm type
- */
-PK11_active *active_list[OP_MAX] = { NULL };
-
-/*
- * Create all secret key objects in a global session so that they are available
- * to use for other sessions. These other sessions may be opened or closed
- * without losing the secret key objects.
- */
-static CK_SESSION_HANDLE	global_session = CK_INVALID_HANDLE;
-
-/* Index for the supported ciphers */
-enum pk11_cipher_id {
-	PK11_DES_CBC,
-	PK11_DES3_CBC,
-	PK11_DES_ECB,
-	PK11_DES3_ECB,
-	PK11_RC4,
-	PK11_AES_128_CBC,
-	PK11_AES_192_CBC,
-	PK11_AES_256_CBC,
-	PK11_AES_128_ECB,
-	PK11_AES_192_ECB,
-	PK11_AES_256_ECB,
-	PK11_BLOWFISH_CBC,
-	PK11_AES_128_CTR,
-	PK11_AES_192_CTR,
-	PK11_AES_256_CTR,
-	PK11_CIPHER_MAX
-};
-
-/* Index for the supported digests */
-enum pk11_digest_id {
-	PK11_MD5,
-	PK11_SHA1,
-	PK11_SHA224,
-	PK11_SHA256,
-	PK11_SHA384,
-	PK11_SHA512,
-	PK11_DIGEST_MAX
-};
-
-typedef struct PK11_CIPHER_st
-	{
-	enum pk11_cipher_id	id;
-	int			nid;
-	int			iv_len;
-	int			min_key_len;
-	int			max_key_len;
-	CK_KEY_TYPE		key_type;
-	CK_MECHANISM_TYPE	mech_type;
-	} PK11_CIPHER;
-
-typedef struct PK11_DIGEST_st
-	{
-	enum pk11_digest_id	id;
-	int			nid;
-	CK_MECHANISM_TYPE	mech_type;
-	} PK11_DIGEST;
-
-/* ENGINE level stuff */
-static int pk11_init(ENGINE *e);
-static int pk11_library_init(ENGINE *e);
-static int pk11_finish(ENGINE *e);
-static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)());
-static int pk11_destroy(ENGINE *e);
-
-/* RAND stuff */
-static void pk11_rand_seed(const void *buf, int num);
-static void pk11_rand_add(const void *buf, int num, double add_entropy);
-static void pk11_rand_cleanup(void);
-static int pk11_rand_bytes(unsigned char *buf, int num);
-static int pk11_rand_status(void);
-
-/* These functions are also used in other files */
-PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
-void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
-
-/* active list manipulation functions used in this file */
-extern int pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type);
-extern void pk11_free_active_list(PK11_OPTYPE type);
-
-#ifndef OPENSSL_NO_RSA
-int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
-int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
-int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
-#endif
-#ifndef OPENSSL_NO_DSA
-int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
-int pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
-int pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
-#endif
-#ifndef OPENSSL_NO_DH
-int pk11_destroy_dh_key_objects(PK11_SESSION *session);
-int pk11_destroy_dh_object(PK11_SESSION *session, CK_BBOOL uselock);
-#endif
-
-/* Local helper functions */
-static int pk11_free_all_sessions(void);
-static int pk11_free_session_list(PK11_OPTYPE optype);
-static int pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype);
-static int pk11_destroy_cipher_key_objects(PK11_SESSION *session);
-static int pk11_destroy_object(CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE oh,
-    CK_BBOOL persistent);
-static const char *get_PK11_LIBNAME(void);
-static void free_PK11_LIBNAME(void);
-static long set_PK11_LIBNAME(const char *name);
-
-/* Symmetric cipher and digest support functions */
-static int cipher_nid_to_pk11(int nid);
-static int pk11_usable_ciphers(const int **nids);
-static int pk11_usable_digests(const int **nids);
-static int pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-	const unsigned char *iv, int enc);
-static int pk11_cipher_final(PK11_SESSION *sp);
-static int pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-	const unsigned char *in, size_t inl);
-static int pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx);
-static int pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
-	const int **nids, int nid);
-static int pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
-	const int **nids, int nid);
-static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
-	const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp);
-static int check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key,
-	int key_len);
-static int md_nid_to_pk11(int nid);
-static int pk11_digest_init(EVP_MD_CTX *ctx);
-static int pk11_digest_update(EVP_MD_CTX *ctx, const void *data,
-	size_t count);
-static int pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md);
-static int pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);
-static int pk11_digest_cleanup(EVP_MD_CTX *ctx);
-
-static int pk11_choose_slots(int *any_slot_found);
-static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
-    CK_SLOT_ID current_slot, int *current_slot_n_cipher,
-    int *local_cipher_nids);
-static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
-    CK_SLOT_ID current_slot, int *current_slot_n_digest,
-    int *local_digest_nids);
-static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR, int slot_id,
-    int *current_slot_n_cipher, int *local_cipher_nids,
-    PK11_CIPHER *cipher);
-static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
-    int *current_slot_n_digest, int *local_digest_nids,
-    PK11_DIGEST *digest);
-
-static int pk11_init_all_locks(void);
-static void pk11_free_all_locks(void);
-
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-static int check_hw_mechanisms(void);
-static int nid_in_table(int nid, int *nid_table);
-static int hw_aes_instruction_set_present(void);
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-
-#define	TRY_OBJ_DESTROY(sp, obj_hdl, retval, uselock, alg_type)	\
-	{								\
-	if (uselock)							\
-		LOCK_OBJSTORE(alg_type);				\
-	if (pk11_active_delete(obj_hdl, alg_type) == 1)			\
-		{							\
-		retval = pk11_destroy_object(sp->session, obj_hdl,	\
-		    sp->persistent);					\
-		}							\
-	if (uselock)							\
-		UNLOCK_OBJSTORE(alg_type);				\
-	}
-
-static int cipher_nids[PK11_CIPHER_MAX];
-static int digest_nids[PK11_DIGEST_MAX];
-static int cipher_count		= 0;
-static int digest_count		= 0;
-static CK_BBOOL pk11_have_rsa	= CK_FALSE;
-static CK_BBOOL pk11_have_dsa	= CK_FALSE;
-static CK_BBOOL pk11_have_dh	= CK_FALSE;
-static CK_BBOOL pk11_have_random = CK_FALSE;
-
-/*
- * Static list of ciphers.
- * Note, that ciphers array is indexed by member PK11_CIPHER.id,
- * thus ciphers[i].id == i
- * Rows must be kept in sync with enum pk11_cipher_id.
- */
-static PK11_CIPHER ciphers[] =
-	{
-	{ PK11_DES_CBC,		NID_des_cbc,		8,	 8,   8,
-		CKK_DES,	CKM_DES_CBC, },
-	{ PK11_DES3_CBC,	NID_des_ede3_cbc,	8,	24,  24,
-		CKK_DES3,	CKM_DES3_CBC, },
-	{ PK11_DES_ECB,		NID_des_ecb,		0,	 8,   8,
-		CKK_DES,	CKM_DES_ECB, },
-	{ PK11_DES3_ECB,	NID_des_ede3_ecb,	0,	24,  24,
-		CKK_DES3,	CKM_DES3_ECB, },
-	{ PK11_RC4,		NID_rc4,		0,	16, 256,
-		CKK_RC4,	CKM_RC4, },
-	{ PK11_AES_128_CBC,	NID_aes_128_cbc,	16,	16,  16,
-		CKK_AES,	CKM_AES_CBC, },
-	{ PK11_AES_192_CBC,	NID_aes_192_cbc,	16,	24,  24,
-		CKK_AES,	CKM_AES_CBC, },
-	{ PK11_AES_256_CBC,	NID_aes_256_cbc,	16,	32,  32,
-		CKK_AES,	CKM_AES_CBC, },
-	{ PK11_AES_128_ECB,	NID_aes_128_ecb,	0,	16,  16,
-		CKK_AES,	CKM_AES_ECB, },
-	{ PK11_AES_192_ECB,	NID_aes_192_ecb,	0,	24,  24,
-		CKK_AES,	CKM_AES_ECB, },
-	{ PK11_AES_256_ECB,	NID_aes_256_ecb,	0,	32,  32,
-		CKK_AES,	CKM_AES_ECB, },
-	{ PK11_BLOWFISH_CBC,	NID_bf_cbc,		8,	16,  16,
-		CKK_BLOWFISH,	CKM_BLOWFISH_CBC, },
-	{ PK11_AES_128_CTR,	NID_aes_128_ctr,	16,	16,  16,
-		CKK_AES,	CKM_AES_CTR, },
-	{ PK11_AES_192_CTR,	NID_aes_192_ctr,	16,	24,  24,
-		CKK_AES,	CKM_AES_CTR, },
-	{ PK11_AES_256_CTR,	NID_aes_256_ctr,	16,	32,  32,
-		CKK_AES,	CKM_AES_CTR, },
-	};
-
-/*
- * Static list of digests.
- * Note, that digests array is indexed by member PK11_DIGEST.id,
- * thus digests[i].id == i
- * Rows must be kept in sync with enum pk11_digest_id.
- */
-static PK11_DIGEST digests[] =
-	{
-	{PK11_MD5,	NID_md5,	CKM_MD5, },
-	{PK11_SHA1,	NID_sha1,	CKM_SHA_1, },
-	{PK11_SHA224,	NID_sha224,	CKM_SHA224, },
-	{PK11_SHA256,	NID_sha256,	CKM_SHA256, },
-	{PK11_SHA384,	NID_sha384,	CKM_SHA384, },
-	{PK11_SHA512,	NID_sha512,	CKM_SHA512, },
-	{0,		NID_undef,	0xFFFF, },
-	};
-
-/*
- * Structure to be used for the cipher_data/md_data in
- * EVP_CIPHER_CTX/EVP_MD_CTX structures in order to use the same pk11
- * session in multiple cipher_update calls
- */
-typedef struct PK11_CIPHER_STATE_st
-	{
-	PK11_SESSION	*sp;
-	} PK11_CIPHER_STATE;
-
-
-/*
- * libcrypto EVP stuff - this is how we get wired to EVP so the engine gets
- * called when libcrypto requests a cipher NID.
- *
- * Note how the PK11_CIPHER_STATE is used here.
- */
-
-/* DES CBC EVP */
-static const EVP_CIPHER pk11_des_cbc =
-	{
-	NID_des_cbc,
-	8, 8, 8,
-	EVP_CIPH_CBC_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-/* 3DES CBC EVP */
-static const EVP_CIPHER pk11_3des_cbc =
-	{
-	NID_des_ede3_cbc,
-	8, 24, 8,
-	EVP_CIPH_CBC_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-/*
- * ECB modes don't use an Initial Vector so that's why set_asn1_parameters and
- * get_asn1_parameters fields are set to NULL.
- */
-static const EVP_CIPHER pk11_des_ecb =
-	{
-	NID_des_ecb,
-	8, 8, 8,
-	EVP_CIPH_ECB_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	NULL,
-	NULL,
-	NULL
-	};
-
-static const EVP_CIPHER pk11_3des_ecb =
-	{
-	NID_des_ede3_ecb,
-	8, 24, 8,
-	EVP_CIPH_ECB_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	NULL,
-	NULL,
-	NULL
-	};
-
-
-static const EVP_CIPHER pk11_aes_128_cbc =
-	{
-	NID_aes_128_cbc,
-	16, 16, 16,
-	EVP_CIPH_CBC_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-static const EVP_CIPHER pk11_aes_192_cbc =
-	{
-	NID_aes_192_cbc,
-	16, 24, 16,
-	EVP_CIPH_CBC_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-static const EVP_CIPHER pk11_aes_256_cbc =
-	{
-	NID_aes_256_cbc,
-	16, 32, 16,
-	EVP_CIPH_CBC_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-/*
- * ECB modes don't use IV so that's why set_asn1_parameters and
- * get_asn1_parameters are set to NULL.
- */
-static const EVP_CIPHER pk11_aes_128_ecb =
-	{
-	NID_aes_128_ecb,
-	16, 16, 0,
-	EVP_CIPH_ECB_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	NULL,
-	NULL,
-	NULL
-	};
-
-static const EVP_CIPHER pk11_aes_192_ecb =
-	{
-	NID_aes_192_ecb,
-	16, 24, 0,
-	EVP_CIPH_ECB_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	NULL,
-	NULL,
-	NULL
-	};
-
-static const EVP_CIPHER pk11_aes_256_ecb =
-	{
-	NID_aes_256_ecb,
-	16, 32, 0,
-	EVP_CIPH_ECB_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	NULL,
-	NULL,
-	NULL
-	};
-
-static EVP_CIPHER pk11_aes_128_ctr =
-	{
-	NID_aes_128_ctr,
-	16, 16, 16,
-	EVP_CIPH_CTR_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-static EVP_CIPHER pk11_aes_192_ctr =
-	{
-	NID_aes_192_ctr,
-	16, 24, 16,
-	EVP_CIPH_CTR_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-static EVP_CIPHER pk11_aes_256_ctr =
-	{
-	NID_aes_256_ctr,
-	16, 32, 16,
-	EVP_CIPH_CTR_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-static const EVP_CIPHER pk11_bf_cbc =
-	{
-	NID_bf_cbc,
-	8, 16, 8,
-	EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CBC_MODE,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	EVP_CIPHER_set_asn1_iv,
-	EVP_CIPHER_get_asn1_iv,
-	NULL
-	};
-
-static const EVP_CIPHER pk11_rc4 =
-	{
-	NID_rc4,
-	1, 16, 0,
-	EVP_CIPH_VARIABLE_LENGTH,
-	pk11_cipher_init,
-	pk11_cipher_do_cipher,
-	pk11_cipher_cleanup,
-	sizeof (PK11_CIPHER_STATE),
-	NULL,
-	NULL,
-	NULL
-	};
-
-static const EVP_MD pk11_md5 =
-	{
-	NID_md5,
-	NID_md5WithRSAEncryption,
-	MD5_DIGEST_LENGTH,
-	0,
-	pk11_digest_init,
-	pk11_digest_update,
-	pk11_digest_final,
-	pk11_digest_copy,
-	pk11_digest_cleanup,
-	EVP_PKEY_RSA_method,
-	MD5_CBLOCK,
-	sizeof (PK11_CIPHER_STATE),
-	};
-
-static const EVP_MD pk11_sha1 =
-	{
-	NID_sha1,
-	NID_sha1WithRSAEncryption,
-	SHA_DIGEST_LENGTH,
-	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
-	pk11_digest_init,
-	pk11_digest_update,
-	pk11_digest_final,
-	pk11_digest_copy,
-	pk11_digest_cleanup,
-	EVP_PKEY_RSA_method,
-	SHA_CBLOCK,
-	sizeof (PK11_CIPHER_STATE),
-	};
-
-static const EVP_MD pk11_sha224 =
-	{
-	NID_sha224,
-	NID_sha224WithRSAEncryption,
-	SHA224_DIGEST_LENGTH,
-	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
-	pk11_digest_init,
-	pk11_digest_update,
-	pk11_digest_final,
-	pk11_digest_copy,
-	pk11_digest_cleanup,
-	EVP_PKEY_RSA_method,
-	/* SHA-224 uses the same cblock size as SHA-256 */
-	SHA256_CBLOCK,
-	sizeof (PK11_CIPHER_STATE),
-	};
-
-static const EVP_MD pk11_sha256 =
-	{
-	NID_sha256,
-	NID_sha256WithRSAEncryption,
-	SHA256_DIGEST_LENGTH,
-	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
-	pk11_digest_init,
-	pk11_digest_update,
-	pk11_digest_final,
-	pk11_digest_copy,
-	pk11_digest_cleanup,
-	EVP_PKEY_RSA_method,
-	SHA256_CBLOCK,
-	sizeof (PK11_CIPHER_STATE),
-	};
-
-static const EVP_MD pk11_sha384 =
-	{
-	NID_sha384,
-	NID_sha384WithRSAEncryption,
-	SHA384_DIGEST_LENGTH,
-	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
-	pk11_digest_init,
-	pk11_digest_update,
-	pk11_digest_final,
-	pk11_digest_copy,
-	pk11_digest_cleanup,
-	EVP_PKEY_RSA_method,
-	/* SHA-384 uses the same cblock size as SHA-512 */
-	SHA512_CBLOCK,
-	sizeof (PK11_CIPHER_STATE),
-	};
-
-static const EVP_MD pk11_sha512 =
-	{
-	NID_sha512,
-	NID_sha512WithRSAEncryption,
-	SHA512_DIGEST_LENGTH,
-	EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
-	pk11_digest_init,
-	pk11_digest_update,
-	pk11_digest_final,
-	pk11_digest_copy,
-	pk11_digest_cleanup,
-	EVP_PKEY_RSA_method,
-	SHA512_CBLOCK,
-	sizeof (PK11_CIPHER_STATE),
-	};
-
-/*
- * Initialization function. Sets up various PKCS#11 library components.
- * The definitions for control commands specific to this engine
- */
-#define	PK11_CMD_SO_PATH		ENGINE_CMD_BASE
-static const ENGINE_CMD_DEFN pk11_cmd_defns[] =
-	{
-		{
-		PK11_CMD_SO_PATH,
-		"SO_PATH",
-		"Specifies the path to the 'pkcs#11' shared library",
-		ENGINE_CMD_FLAG_STRING
-		},
-		{0, NULL, NULL, 0}
-	};
-
-
-static RAND_METHOD pk11_random =
-	{
-	pk11_rand_seed,
-	pk11_rand_bytes,
-	pk11_rand_cleanup,
-	pk11_rand_add,
-	pk11_rand_bytes,
-	pk11_rand_status
-	};
-
-
-/* Constants used when creating the ENGINE */
-static const char *engine_pk11_id = "pkcs11";
-static const char *engine_pk11_name = "PKCS #11 engine support";
-
-CK_FUNCTION_LIST_PTR pFuncList = NULL;
-static const char PK11_GET_FUNCTION_LIST[] = "C_GetFunctionList";
-
-/*
- * This is a static string constant for the DSO file name and the function
- * symbol names to bind to. We set it in the Configure script based on whether
- * this is 32 or 64 bit build.
- */
-static const char def_PK11_LIBNAME[] = PK11_LIB_LOCATION;
-
-/* Needed in e_pk11_pub.c as well so that's why it is not static. */
-CK_SLOT_ID pubkey_SLOTID = 0;
-static CK_SLOT_ID rand_SLOTID = 0;
-static CK_SLOT_ID SLOTID = 0;
-static CK_BBOOL pk11_library_initialized = CK_FALSE;
-static CK_BBOOL pk11_atfork_initialized = CK_FALSE;
-static int pk11_pid = 0;
-static ENGINE* pk11_engine = NULL;
-
-static DSO *pk11_dso = NULL;
-
-/* allocate and initialize all locks used by the engine itself */
-static int pk11_init_all_locks(void)
-	{
-	int type;
-
-#ifndef OPENSSL_NO_RSA
-	find_lock[OP_RSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
-	if (find_lock[OP_RSA] == NULL)
-		goto malloc_err;
-	(void) pthread_mutex_init(find_lock[OP_RSA], NULL);
-#endif /* OPENSSL_NO_RSA */
-
-	if ((uri_lock = OPENSSL_malloc(sizeof (pthread_mutex_t))) == NULL)
-		goto malloc_err;
-	(void) pthread_mutex_init(uri_lock, NULL);
-
-#ifndef OPENSSL_NO_DSA
-	find_lock[OP_DSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
-	if (find_lock[OP_DSA] == NULL)
-		goto malloc_err;
-	(void) pthread_mutex_init(find_lock[OP_DSA], NULL);
-#endif /* OPENSSL_NO_DSA */
-
-#ifndef OPENSSL_NO_DH
-	find_lock[OP_DH] = OPENSSL_malloc(sizeof (pthread_mutex_t));
-	if (find_lock[OP_DH] == NULL)
-		goto malloc_err;
-	(void) pthread_mutex_init(find_lock[OP_DH], NULL);
-#endif /* OPENSSL_NO_DH */
-
-	for (type = 0; type < OP_MAX; type++)
-		{
-		session_cache[type].lock =
-		    OPENSSL_malloc(sizeof (pthread_mutex_t));
-		if (session_cache[type].lock == NULL)
-			goto malloc_err;
-		(void) pthread_mutex_init(session_cache[type].lock, NULL);
-		}
-
-	return (1);
-
-malloc_err:
-	pk11_free_all_locks();
-	PK11err(PK11_F_INIT_ALL_LOCKS, PK11_R_MALLOC_FAILURE);
-	return (0);
-	}
-
-static void pk11_free_all_locks(void)
-	{
-	int type;
-
-#ifndef OPENSSL_NO_RSA
-	if (find_lock[OP_RSA] != NULL)
-		{
-		(void) pthread_mutex_destroy(find_lock[OP_RSA]);
-		OPENSSL_free(find_lock[OP_RSA]);
-		find_lock[OP_RSA] = NULL;
-		}
-#endif /* OPENSSL_NO_RSA */
-#ifndef OPENSSL_NO_DSA
-	if (find_lock[OP_DSA] != NULL)
-		{
-		(void) pthread_mutex_destroy(find_lock[OP_DSA]);
-		OPENSSL_free(find_lock[OP_DSA]);
-		find_lock[OP_DSA] = NULL;
-		}
-#endif /* OPENSSL_NO_DSA */
-#ifndef OPENSSL_NO_DH
-	if (find_lock[OP_DH] != NULL)
-		{
-		(void) pthread_mutex_destroy(find_lock[OP_DH]);
-		OPENSSL_free(find_lock[OP_DH]);
-		find_lock[OP_DH] = NULL;
-		}
-#endif /* OPENSSL_NO_DH */
-
-	for (type = 0; type < OP_MAX; type++)
-		{
-		if (session_cache[type].lock != NULL)
-			{
-			(void) pthread_mutex_destroy(session_cache[type].lock);
-			OPENSSL_free(session_cache[type].lock);
-			session_cache[type].lock = NULL;
-			}
-		}
-	/* Free uri_lock */
-	(void) pthread_mutex_destroy(uri_lock);
-	OPENSSL_free(uri_lock);
-	uri_lock = NULL;
-	}
-
-/*
- * This internal function is used by ENGINE_pk11() and "dynamic" ENGINE support.
- */
-static int bind_pk11(ENGINE *e)
-	{
-#ifndef OPENSSL_NO_RSA
-	const RSA_METHOD *rsa = NULL;
-	RSA_METHOD *pk11_rsa = PK11_RSA();
-#endif	/* OPENSSL_NO_RSA */
-	if (!pk11_library_initialized)
-		if (!pk11_library_init(e))
-			return (0);
-
-	if (!ENGINE_set_id(e, engine_pk11_id) ||
-	    !ENGINE_set_name(e, engine_pk11_name) ||
-	    !ENGINE_set_ciphers(e, pk11_engine_ciphers) ||
-	    !ENGINE_set_digests(e, pk11_engine_digests))
-		return (0);
-
-	if (!ENGINE_set_pkey_meths(e, pk11_engine_pkey_methods))
-		return (0);
-
-#ifndef OPENSSL_NO_RSA
-	if (pk11_have_rsa == CK_TRUE)
-		{
-		if (!ENGINE_set_RSA(e, PK11_RSA()) ||
-		    !ENGINE_set_load_privkey_function(e, pk11_load_privkey) ||
-		    !ENGINE_set_load_pubkey_function(e, pk11_load_pubkey))
-			return (0);
-		DEBUG_SLOT_SEL("%s: registered RSA\n", PK11_DBG);
-		}
-#endif	/* OPENSSL_NO_RSA */
-#ifndef OPENSSL_NO_DSA
-	if (pk11_have_dsa == CK_TRUE)
-		{
-		if (!ENGINE_set_DSA(e, PK11_DSA()))
-			return (0);
-		DEBUG_SLOT_SEL("%s: registered DSA\n", PK11_DBG);
-		}
-#endif	/* OPENSSL_NO_DSA */
-#ifndef OPENSSL_NO_DH
-	if (pk11_have_dh == CK_TRUE)
-		{
-		if (!ENGINE_set_DH(e, PK11_DH()))
-			return (0);
-		DEBUG_SLOT_SEL("%s: registered DH\n", PK11_DBG);
-		}
-#endif	/* OPENSSL_NO_DH */
-	if (pk11_have_random)
-		{
-		if (!ENGINE_set_RAND(e, &pk11_random))
-			return (0);
-		DEBUG_SLOT_SEL("%s: registered random\n", PK11_DBG);
-		}
-	if (!ENGINE_set_init_function(e, pk11_init) ||
-	    !ENGINE_set_destroy_function(e, pk11_destroy) ||
-	    !ENGINE_set_finish_function(e, pk11_finish) ||
-	    !ENGINE_set_ctrl_function(e, pk11_ctrl) ||
-	    !ENGINE_set_cmd_defns(e, pk11_cmd_defns))
-		return (0);
-
-/*
- * Apache calls OpenSSL function RSA_blinding_on() once during startup
- * which in turn calls bn_mod_exp. Since we do not implement bn_mod_exp
- * here, we wire it back to the OpenSSL software implementation.
- * Since it is used only once, performance is not a concern.
- */
-#ifndef OPENSSL_NO_RSA
-	rsa = RSA_PKCS1_SSLeay();
-	pk11_rsa->rsa_mod_exp = rsa->rsa_mod_exp;
-	pk11_rsa->bn_mod_exp = rsa->bn_mod_exp;
-#endif	/* OPENSSL_NO_RSA */
-
-	/* Ensure the pk11 error handling is set up */
-	ERR_load_pk11_strings();
-
-	return (1);
-	}
-
-static int bind_helper(ENGINE *e, const char *id)
-	{
-	if (id && (strcmp(id, engine_pk11_id) != 0))
-		return (0);
-
-	if (!bind_pk11(e))
-		return (0);
-
-	return (1);
-	}
-
-IMPLEMENT_DYNAMIC_CHECK_FN()
-IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
-
-/*
- * These are the static string constants for the DSO file name and
- * the function symbol names to bind to.
- */
-static const char *PK11_LIBNAME = NULL;
-
-static const char *get_PK11_LIBNAME(void)
-	{
-	if (PK11_LIBNAME)
-		return (PK11_LIBNAME);
-
-	return (def_PK11_LIBNAME);
-	}
-
-static void free_PK11_LIBNAME(void)
-	{
-	if (PK11_LIBNAME)
-		OPENSSL_free((void*)PK11_LIBNAME);
-
-	PK11_LIBNAME = NULL;
-	}
-
-static long set_PK11_LIBNAME(const char *name)
-	{
-	free_PK11_LIBNAME();
-
-	return ((PK11_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
-	}
-
-/* acquire all engine specific mutexes before fork */
-static void pk11_fork_prepare(void)
-	{
-	int i;
-
-	if (!pk11_library_initialized)
-		return;
-
-	LOCK_OBJSTORE(OP_RSA);
-	LOCK_OBJSTORE(OP_DSA);
-	LOCK_OBJSTORE(OP_DH);
-	(void) pthread_mutex_lock(uri_lock);
-	for (i = 0; i < OP_MAX; i++)
-		{
-		(void) pthread_mutex_lock(session_cache[i].lock);
-		}
-	}
-
-/* release all engine specific mutexes */
-static void pk11_fork_parent(void)
-	{
-	int i;
-
-	if (!pk11_library_initialized)
-		return;
-
-	for (i = OP_MAX - 1; i >= 0; i--)
-		{
-		(void) pthread_mutex_unlock(session_cache[i].lock);
-		}
-	UNLOCK_OBJSTORE(OP_DH);
-	UNLOCK_OBJSTORE(OP_DSA);
-	UNLOCK_OBJSTORE(OP_RSA);
-	(void) pthread_mutex_unlock(uri_lock);
-	}
-
-/*
- * same situation as in parent - we need to unlock all locks to make them
- * accessible to all threads.
- */
-static void pk11_fork_child(void)
-	{
-	int i;
-
-	if (!pk11_library_initialized)
-		return;
-
-	/* invalidate the global session */
-	global_session = CK_INVALID_HANDLE;
-
-	for (i = OP_MAX - 1; i >= 0; i--)
-		{
-		(void) pthread_mutex_unlock(session_cache[i].lock);
-		}
-	UNLOCK_OBJSTORE(OP_DH);
-	UNLOCK_OBJSTORE(OP_DSA);
-	UNLOCK_OBJSTORE(OP_RSA);
-	(void) pthread_mutex_unlock(uri_lock);
-	}
-
-/* Initialization function for the pk11 engine */
-static int pk11_init(ENGINE *e)
-{
-	return (pk11_library_init(e));
-}
-
-/*
- * Helper function that unsets reference to current engine (pk11_engine = NULL).
- *
- * Use of local variable only seems clumsy, it needs to be this way!
- * This is to prevent double free in the unlucky scenario:
- *     ENGINE_free calls pk11_destroy calls pk11_finish calls ENGINE_free
- * Setting pk11_engine to NULL prior to ENGINE_free() avoids this.
- */
-static void pk11_engine_free()
-	{
-	ENGINE* old_engine = pk11_engine;
-
-	if (old_engine) {
-		pk11_engine = NULL;
-	}
-	}
-
-/*
- * Initialization function. Sets up various PKCS#11 library components.
- * It selects a slot based on predefined critiera. In the process, it also
- * count how many ciphers and digests to support. Since the cipher and
- * digest information is needed when setting default engine, this function
- * needs to be called before calling ENGINE_set_default.
- */
-/* ARGSUSED */
-static int pk11_library_init(ENGINE *e)
-	{
-	CK_C_GetFunctionList p;
-	CK_RV rv = CKR_OK;
-	CK_INFO info;
-	CK_ULONG ul_state_len;
-	int any_slot_found;
-	int i;
-
-	if (e != pk11_engine)
-		{
-		pk11_engine_free();
-		pk11_engine = e;
-		}
-
-	/*
-	 * pk11_library_initialized is set to 0 in pk11_finish() which is called
-	 * from ENGINE_finish(). However, if there is still at least one
-	 * existing functional reference to the engine (see engine(3) for more
-	 * information), pk11_finish() is skipped. For example, this can happen
-	 * if an application forgets to clear one cipher context. In case of a
-	 * fork() when the application is finishing the engine so that it can be
-	 * reinitialized in the child, forgotten functional reference causes
-	 * pk11_library_initialized to stay 1. In that case we need the PID
-	 * check so that we properly initialize the engine again.
-	 */
-	if (pk11_library_initialized)
-		{
-		if (pk11_pid == getpid())
-			{
-			return (1);
-			}
-		else
-			{
-			global_session = CK_INVALID_HANDLE;
-			/*
-			 * free the locks first to prevent memory leak in case
-			 * the application calls fork() without finishing the
-			 * engine first.
-			 */
-			pk11_free_all_locks();
-			}
-		}
-
-	/*
-	 * If initialization of the locks fails pk11_init_all_locks()
-	 * will do the cleanup.
-	 */
-	if (!pk11_init_all_locks())
-		goto err;
-	for (i = 0; i < OP_MAX; i++)
-		session_cache[i].head = NULL;
-	/*
-	 * Initialize active lists. We only use active lists
-	 * for asymmetric ciphers.
-	 */
-	for (i = 0; i < OP_MAX; i++)
-		active_list[i] = NULL;
-
-	/* Attempt to load PKCS#11 library. */
-	if (!pk11_dso)
-		{
-		pk11_dso = DSO_load(NULL, get_PK11_LIBNAME(), NULL, 0);
-		if (pk11_dso == NULL)
-			{
-			PK11err(PK11_F_LOAD, PK11_R_DSO_FAILURE);
-			goto err;
-			}
-		}
-
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-	if (check_hw_mechanisms() == 0)
-		goto err;
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-
-	/* get the C_GetFunctionList function from the loaded library */
-	p = (CK_C_GetFunctionList)DSO_bind_func(pk11_dso,
-		PK11_GET_FUNCTION_LIST);
-	if (!p)
-		{
-		PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
-		goto err;
-		}
-
-	/* get the full function list from the loaded library */
-	rv = p(&pFuncList);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_Initialize(NULL_PTR);
-	if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
-		{
-		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_INITIALIZE, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_GetInfo(&info);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_GETINFO, rv);
-		goto err;
-		}
-
-	if (pk11_choose_slots(&any_slot_found) == 0)
-		goto err;
-
-	/*
-	 * The library we use, set in def_PK11_LIBNAME, may not offer any
-	 * slot(s). In that case, we must not proceed but we must not return an
-	 * error. The reason is that applications that try to set up the PKCS#11
-	 * engine don't exit on error during the engine initialization just
-	 * because no slot was present.
-	 */
-	if (any_slot_found == 0)
-		return (1);
-
-	if (global_session == CK_INVALID_HANDLE)
-		{
-		/* Open the global_session for the new process */
-		rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
-			NULL_PTR, NULL_PTR, &global_session);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_LIBRARY_INIT,
-			    PK11_R_OPENSESSION, rv);
-			goto err;
-			}
-		}
-
-	/*
-	 * Disable digest if C_GetOperationState is not supported since
-	 * this function is required by OpenSSL digest copy function
-	 */
-	if (pFuncList->C_GetOperationState(global_session, NULL, &ul_state_len)
-			== CKR_FUNCTION_NOT_SUPPORTED) {
-		DEBUG_SLOT_SEL("%s: C_GetOperationState() not supported, "
-		    "setting digest_count to 0\n", PK11_DBG);
-		digest_count = 0;
-	}
-
-	pk11_library_initialized = CK_TRUE;
-	pk11_pid = getpid();
-
-	if (!pk11_atfork_initialized)
-		{
-		if (pthread_atfork(pk11_fork_prepare, pk11_fork_parent,
-		    pk11_fork_child) != 0)
-			{
-			PK11err(PK11_F_LIBRARY_INIT, PK11_R_ATFORK_FAILED);
-			goto err;
-			}
-		pk11_atfork_initialized = CK_TRUE;
-		}
-
-	return (1);
-
-err:
-	return (0);
-	}
-
-/* Destructor (complements the "ENGINE_pk11()" constructor) */
-/* ARGSUSED */
-static int pk11_destroy(ENGINE *e)
-	{
-	int rtn = 1;
-
-	free_PK11_LIBNAME();
-	ERR_unload_pk11_strings();
-	if (pk11_library_initialized == CK_TRUE)
-		rtn = pk11_finish(e);
-
-	return (rtn);
-	}
-
-/*
- * Termination function to clean up the session, the token, and the pk11
- * library.
- */
-/* ARGSUSED */
-static int pk11_finish(ENGINE *e)
-	{
-	int i;
-
-	/*
-	 * Make sure, right engine instance is being destroyed.
-	 * Engine e may be the wrong instance if
-	 * 	1) either someone calls ENGINE_load_pk11 twice
-	 * 	2) or last ref. to an already finished engine is being destroyed
-	 */
-	if (e != pk11_engine)
-		goto err;
-
-	if (pk11_dso == NULL)
-		{
-		PK11err(PK11_F_FINISH, PK11_R_NOT_LOADED);
-		goto err;
-		}
-
-	OPENSSL_assert(pFuncList != NULL);
-
-	if (pk11_free_all_sessions() == 0)
-		goto err;
-
-	/* free all active lists */
-	for (i = 0; i < OP_MAX; i++)
-		pk11_free_active_list(i);
-
-	/* Global session is not present when there are no slots. */
-	if (global_session != CK_INVALID_HANDLE)
-		{
-		pFuncList->C_CloseSession(global_session);
-		global_session = CK_INVALID_HANDLE;
-		}
-
-	/*
-	 * Since we are part of a library (libcrypto.so), calling this function
-	 * may have side-effects.
-	 */
-#if 0
-	pFuncList->C_Finalize(NULL);
-#endif
-	if (!DSO_free(pk11_dso))
-		{
-		PK11err(PK11_F_FINISH, PK11_R_DSO_FAILURE);
-		goto err;
-		}
-	pk11_dso = NULL;
-	pFuncList = NULL;
-	pk11_library_initialized = CK_FALSE;
-	pk11_pid = 0;
-	pk11_engine_free();
-	/*
-	 * There is no way how to unregister atfork handlers (other than
-	 * unloading the library) so we just free the locks. For this reason
-	 * the atfork handlers check if the engine is initialized and bail out
-	 * immediately if not. This is necessary in case a process finishes
-	 * the engine before calling fork().
-	 */
-	pk11_free_all_locks();
-
-	return (1);
-
-err:
-	return (0);
-	}
-
-/* Standard engine interface function to set the dynamic library path */
-/* ARGSUSED */
-static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)())
-	{
-	int initialized = ((pk11_dso == NULL) ? 0 : 1);
-
-	switch (cmd)
-		{
-	case PK11_CMD_SO_PATH:
-		if (p == NULL)
-			{
-			PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
-			return (0);
-			}
-
-		if (initialized)
-			{
-			PK11err(PK11_F_CTRL, PK11_R_ALREADY_LOADED);
-			return (0);
-			}
-
-		return (set_PK11_LIBNAME((const char *)p));
-	default:
-		break;
-		}
-
-	PK11err(PK11_F_CTRL, PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED);
-
-	return (0);
-	}
-
-
-/* Required function by the engine random interface. It does nothing here */
-static void pk11_rand_cleanup(void)
-	{
-	return;
-	}
-
-/* ARGSUSED */
-static void pk11_rand_add(const void *buf, int num, double add)
-	{
-	PK11_SESSION *sp;
-
-	if ((sp = pk11_get_session(OP_RAND)) == NULL)
-		return;
-
-	/*
-	 * Ignore any errors (e.g. CKR_RANDOM_SEED_NOT_SUPPORTED) since
-	 * the calling functions do not care anyway
-	 */
-	pFuncList->C_SeedRandom(sp->session, (unsigned char *) buf, num);
-	pk11_return_session(sp, OP_RAND);
-
-	return;
-	}
-
-static void pk11_rand_seed(const void *buf, int num)
-	{
-	pk11_rand_add(buf, num, 0);
-	}
-
-static int pk11_rand_bytes(unsigned char *buf, int num)
-	{
-	CK_RV rv;
-	PK11_SESSION *sp;
-
-	if ((sp = pk11_get_session(OP_RAND)) == NULL)
-		return (0);
-
-	rv = pFuncList->C_GenerateRandom(sp->session, buf, num);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_RAND_BYTES, PK11_R_GENERATERANDOM, rv);
-		pk11_return_session(sp, OP_RAND);
-		return (0);
-		}
-
-	pk11_return_session(sp, OP_RAND);
-	return (1);
-	}
-
-/* Required function by the engine random interface. It does nothing here */
-static int pk11_rand_status(void)
-	{
-	return (1);
-	}
-
-/* Free all BIGNUM structures from PK11_SESSION. */
-static void pk11_free_nums(PK11_SESSION *sp, PK11_OPTYPE optype)
-	{
-	switch (optype)
-		{
-#ifndef	OPENSSL_NO_RSA
-		case OP_RSA:
-			if (sp->opdata_rsa_n_num != NULL)
-				{
-				BN_free(sp->opdata_rsa_n_num);
-				sp->opdata_rsa_n_num = NULL;
-				}
-			if (sp->opdata_rsa_e_num != NULL)
-				{
-				BN_free(sp->opdata_rsa_e_num);
-				sp->opdata_rsa_e_num = NULL;
-				}
-			if (sp->opdata_rsa_d_num != NULL)
-				{
-				BN_free(sp->opdata_rsa_d_num);
-				sp->opdata_rsa_d_num = NULL;
-				}
-			break;
-#endif
-#ifndef	OPENSSL_NO_DSA
-		case OP_DSA:
-			if (sp->opdata_dsa_pub_num != NULL)
-				{
-				BN_free(sp->opdata_dsa_pub_num);
-				sp->opdata_dsa_pub_num = NULL;
-				}
-			if (sp->opdata_dsa_priv_num != NULL)
-				{
-				BN_free(sp->opdata_dsa_priv_num);
-				sp->opdata_dsa_priv_num = NULL;
-				}
-			break;
-#endif
-#ifndef	OPENSSL_NO_DH
-		case OP_DH:
-			if (sp->opdata_dh_priv_num != NULL)
-				{
-				BN_free(sp->opdata_dh_priv_num);
-				sp->opdata_dh_priv_num = NULL;
-				}
-			break;
-#endif
-		default:
-			break;
-		}
-	}
-
-/*
- * Get new PK11_SESSION structure ready for use. Every process must have
- * its own freelist of PK11_SESSION structures so handle fork() here
- * by destroying the old and creating new freelist.
- * The returned PK11_SESSION structure is disconnected from the freelist.
- */
-PK11_SESSION *
-pk11_get_session(PK11_OPTYPE optype)
-	{
-	PK11_SESSION *sp = NULL, *sp1, *freelist;
-	pthread_mutex_t *freelist_lock;
-	static pid_t pid = 0;
-	pid_t new_pid;
-	CK_RV rv;
-
-	switch (optype)
-		{
-		case OP_RSA:
-		case OP_DSA:
-		case OP_DH:
-		case OP_RAND:
-		case OP_DIGEST:
-		case OP_CIPHER:
-			freelist_lock = session_cache[optype].lock;
-			break;
-		default:
-			PK11err(PK11_F_GET_SESSION,
-				PK11_R_INVALID_OPERATION_TYPE);
-			return (NULL);
-		}
-	(void) pthread_mutex_lock(freelist_lock);
-
-	/*
-	 * Will use it to find out if we forked. We cannot use the PID field in
-	 * the session structure because we could get a newly allocated session
-	 * here, with no PID information.
-	 */
-	if (pid == 0)
-		pid = getpid();
-
-	freelist = session_cache[optype].head;
-	sp = freelist;
-
-	/*
-	 * If the free list is empty, allocate new uninitialized (filled
-	 * with zeroes) PK11_SESSION structure otherwise return first
-	 * structure from the freelist.
-	 */
-	if (sp == NULL)
-		{
-		if ((sp = OPENSSL_malloc(sizeof (PK11_SESSION))) == NULL)
-			{
-			PK11err(PK11_F_GET_SESSION,
-				PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-		(void) memset(sp, 0, sizeof (PK11_SESSION));
-
-		/*
-		 * It is a new session so it will look like a cache miss to the
-		 * code below. So, we must not try to to destroy its members so
-		 * mark them as unused.
-		 */
-		sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
-		sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
-		}
-	else
-		freelist = sp->next;
-
-	/*
-	 * Check whether we have forked. In that case, we must get rid of all
-	 * inherited sessions and start allocating new ones.
-	 */
-	if (pid != (new_pid = getpid()))
-		{
-		pid = new_pid;
-
-		/*
-		 * We are a new process and thus need to free any inherited
-		 * PK11_SESSION objects aside from the first session (sp) which
-		 * is the only PK11_SESSION structure we will reuse (for the
-		 * head of the list).
-		 */
-		while ((sp1 = freelist) != NULL)
-			{
-			freelist = sp1->next;
-			/*
-			 * NOTE: we do not want to call pk11_free_all_sessions()
-			 * here because it would close underlying PKCS#11
-			 * sessions and destroy all objects.
-			 */
-			pk11_free_nums(sp1, optype);
-			OPENSSL_free(sp1);
-			}
-
-		/* we have to free the active list as well. */
-		pk11_free_active_list(optype);
-
-		/* Initialize the process */
-		rv = pFuncList->C_Initialize(NULL_PTR);
-		if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
-			{
-			PK11err_add_data(PK11_F_GET_SESSION, PK11_R_INITIALIZE,
-			    rv);
-			OPENSSL_free(sp);
-			sp = NULL;
-			goto err;
-			}
-
-		/*
-		 * Choose slot here since the slot table is different on this
-		 * process. If we are here then we must have found at least one
-		 * usable slot before so we don't need to check any_slot_found.
-		 * See pk11_library_init()'s usage of this function for more
-		 * information.
-		 */
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-		if (check_hw_mechanisms() == 0)
-			goto err;
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-		if (pk11_choose_slots(NULL) == 0)
-			goto err;
-
-		/* Open the global_session for the new process */
-		rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
-			NULL_PTR, NULL_PTR, &global_session);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_GET_SESSION, PK11_R_OPENSESSION,
-			    rv);
-			OPENSSL_free(sp);
-			sp = NULL;
-			goto err;
-			}
-
-		/*
-		 * It is an inherited session from our parent so it needs
-		 * re-initialization.
-		 */
-		if (pk11_setup_session(sp, optype) == 0)
-			{
-			OPENSSL_free(sp);
-			sp = NULL;
-			goto err;
-			}
-		if (pk11_token_relogin(sp->session) == 0)
-			{
-			/*
-			 * We will keep the session in the cache list and let
-			 * the caller cope with the situation.
-			 */
-			freelist = sp;
-			sp = NULL;
-			goto err;
-			}
-		}
-
-	if (sp->pid == 0)
-		{
-		/* It is a new session and needs initialization. */
-		if (pk11_setup_session(sp, optype) == 0)
-			{
-			OPENSSL_free(sp);
-			sp = NULL;
-			}
-		}
-
-	/* set new head for the list of PK11_SESSION objects */
-	session_cache[optype].head = freelist;
-
-err:
-	if (sp != NULL)
-		sp->next = NULL;
-
-	(void) pthread_mutex_unlock(freelist_lock);
-
-	return (sp);
-	}
-
-
-void
-pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype)
-	{
-	pthread_mutex_t *freelist_lock;
-	PK11_SESSION *freelist;
-
-	/*
-	 * If this is a session from the parent it will be taken care of and
-	 * freed in pk11_get_session() as part of the post-fork clean up the
-	 * next time we will ask for a new session.
-	 */
-	if (sp == NULL || sp->pid != getpid())
-		return;
-
-	switch (optype)
-		{
-		case OP_RSA:
-		case OP_DSA:
-		case OP_DH:
-		case OP_RAND:
-		case OP_DIGEST:
-		case OP_CIPHER:
-			freelist_lock = session_cache[optype].lock;
-			break;
-		default:
-			PK11err(PK11_F_RETURN_SESSION,
-				PK11_R_INVALID_OPERATION_TYPE);
-			return;
-		}
-
-	(void) pthread_mutex_lock(freelist_lock);
-	freelist = session_cache[optype].head;
-	sp->next = freelist;
-	session_cache[optype].head = sp;
-	(void) pthread_mutex_unlock(freelist_lock);
-	}
-
-
-/* Destroy all objects. This function is called when the engine is finished */
-static int pk11_free_all_sessions()
-	{
-	int ret = 1;
-	int type;
-
-#ifndef OPENSSL_NO_RSA
-	(void) pk11_destroy_rsa_key_objects(NULL);
-#endif	/* OPENSSL_NO_RSA */
-#ifndef OPENSSL_NO_DSA
-	(void) pk11_destroy_dsa_key_objects(NULL);
-#endif	/* OPENSSL_NO_DSA */
-#ifndef OPENSSL_NO_DH
-	(void) pk11_destroy_dh_key_objects(NULL);
-#endif	/* OPENSSL_NO_DH */
-	(void) pk11_destroy_cipher_key_objects(NULL);
-
-	/*
-	 * We try to release as much as we can but any error means that we will
-	 * return 0 on exit.
-	 */
-	for (type = 0; type < OP_MAX; type++)
-		{
-		if (pk11_free_session_list(type) == 0)
-			ret = 0;
-		}
-
-	return (ret);
-	}
-
-/*
- * Destroy session structures from the linked list specified. Free as many
- * sessions as possible but any failure in C_CloseSession() means that we
- * return an error on return.
- */
-static int pk11_free_session_list(PK11_OPTYPE optype)
-	{
-	CK_RV rv;
-	PK11_SESSION *sp = NULL;
-	PK11_SESSION *freelist = NULL;
-	pid_t mypid = getpid();
-	pthread_mutex_t *freelist_lock;
-	int ret = 1;
-
-	switch (optype)
-		{
-		case OP_RSA:
-		case OP_DSA:
-		case OP_DH:
-		case OP_RAND:
-		case OP_DIGEST:
-		case OP_CIPHER:
-			freelist_lock = session_cache[optype].lock;
-			break;
-		default:
-			PK11err(PK11_F_FREE_ALL_SESSIONS,
-				PK11_R_INVALID_OPERATION_TYPE);
-			return (0);
-		}
-
-	(void) pthread_mutex_lock(freelist_lock);
-	freelist = session_cache[optype].head;
-	while ((sp = freelist) != NULL)
-		{
-		if (sp->session != CK_INVALID_HANDLE && sp->pid == mypid)
-			{
-			rv = pFuncList->C_CloseSession(sp->session);
-			if (rv != CKR_OK)
-				{
-				PK11err_add_data(PK11_F_FREE_ALL_SESSIONS,
-					PK11_R_CLOSESESSION, rv);
-				ret = 0;
-				}
-			}
-		freelist = sp->next;
-		pk11_free_nums(sp, optype);
-		OPENSSL_free(sp);
-		}
-
-	(void) pthread_mutex_unlock(freelist_lock);
-	return (ret);
-	}
-
-
-static int
-pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype)
-	{
-	CK_RV rv;
-	CK_SLOT_ID myslot;
-
-	switch (optype)
-		{
-		case OP_RSA:
-		case OP_DSA:
-		case OP_DH:
-			myslot = pubkey_SLOTID;
-			break;
-		case OP_RAND:
-			myslot = rand_SLOTID;
-			break;
-		case OP_DIGEST:
-		case OP_CIPHER:
-			myslot = SLOTID;
-			break;
-		default:
-			PK11err(PK11_F_SETUP_SESSION,
-			    PK11_R_INVALID_OPERATION_TYPE);
-			return (0);
-		}
-
-	sp->session = CK_INVALID_HANDLE;
-	DEBUG_SLOT_SEL("%s: myslot=%d optype=%d\n", PK11_DBG, myslot, optype);
-	rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
-		NULL_PTR, NULL_PTR, &sp->session);
-	if (rv == CKR_CRYPTOKI_NOT_INITIALIZED)
-		{
-		/*
-		 * We are probably a child process so force the
-		 * reinitialize of the session
-		 */
-		pk11_library_initialized = CK_FALSE;
-		if (!pk11_library_init(NULL))
-			return (0);
-		rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
-			NULL_PTR, NULL_PTR, &sp->session);
-		}
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION, rv);
-		return (0);
-		}
-
-	sp->pid = getpid();
-
-	switch (optype)
-		{
-#ifndef OPENSSL_NO_RSA
-		case OP_RSA:
-			sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
-			sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
-			sp->opdata_rsa_pub = NULL;
-			sp->opdata_rsa_n_num = NULL;
-			sp->opdata_rsa_e_num = NULL;
-			sp->opdata_rsa_priv = NULL;
-			sp->opdata_rsa_d_num = NULL;
-			break;
-#endif	/* OPENSSL_NO_RSA */
-#ifndef OPENSSL_NO_DSA
-		case OP_DSA:
-			sp->opdata_dsa_pub_key = CK_INVALID_HANDLE;
-			sp->opdata_dsa_priv_key = CK_INVALID_HANDLE;
-			sp->opdata_dsa_pub = NULL;
-			sp->opdata_dsa_pub_num = NULL;
-			sp->opdata_dsa_priv = NULL;
-			sp->opdata_dsa_priv_num = NULL;
-			break;
-#endif	/* OPENSSL_NO_DSA */
-#ifndef OPENSSL_NO_DH
-		case OP_DH:
-			sp->opdata_dh_key = CK_INVALID_HANDLE;
-			sp->opdata_dh = NULL;
-			sp->opdata_dh_priv_num = NULL;
-			break;
-#endif	/* OPENSSL_NO_DH */
-		case OP_CIPHER:
-			sp->opdata_cipher_key = CK_INVALID_HANDLE;
-			sp->opdata_encrypt = -1;
-			break;
-		}
-
-	/*
-	 * We always initialize the session as containing a non-persistent
-	 * object. The key load functions set it to persistent if that is so.
-	 */
-	sp->persistent = CK_FALSE;
-	return (1);
-	}
-
-#ifndef OPENSSL_NO_RSA
-/*
- * Destroy all non-NULL RSA parameters. For the RSA keys by reference code,
- * public components 'n'/'e' are the key components we use to check for the
- * cache hit even for the private keys. So, no matter whether we are destroying
- * a public or a private key, we always free what we can.
- */
-static void
-destroy_all_rsa_params(PK11_SESSION *sp)
-	{
-	if (sp->opdata_rsa_n_num != NULL)
-		{
-		BN_free(sp->opdata_rsa_n_num);
-		sp->opdata_rsa_n_num = NULL;
-		}
-	if (sp->opdata_rsa_e_num != NULL)
-		{
-		BN_free(sp->opdata_rsa_e_num);
-		sp->opdata_rsa_e_num = NULL;
-		}
-	if (sp->opdata_rsa_d_num != NULL)
-		{
-		BN_free(sp->opdata_rsa_d_num);
-		sp->opdata_rsa_d_num = NULL;
-		}
-	}
-
-/* Destroy RSA public key from single session. */
-int
-pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
-	{
-	int ret = 0;
-
-	if (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE)
-		{
-		TRY_OBJ_DESTROY(sp, sp->opdata_rsa_pub_key,
-		    ret, uselock, OP_RSA);
-		sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
-		sp->opdata_rsa_pub = NULL;
-		destroy_all_rsa_params(sp);
-		}
-
-	return (ret);
-	}
-
-/* Destroy RSA private key from single session. */
-int
-pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
-	{
-	int ret = 0;
-
-	if (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE)
-		{
-		TRY_OBJ_DESTROY(sp, sp->opdata_rsa_priv_key,
-		    ret, uselock, OP_RSA);
-		sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
-		sp->opdata_rsa_priv = NULL;
-		destroy_all_rsa_params(sp);
-		}
-
-	return (ret);
-	}
-
-/*
- * Destroy RSA key object wrapper. If session is NULL, try to destroy all
- * objects in the free list.
- */
-int
-pk11_destroy_rsa_key_objects(PK11_SESSION *session)
-	{
-	int ret = 1;
-	PK11_SESSION *sp = NULL;
-	PK11_SESSION *local_free_session;
-	CK_BBOOL uselock = CK_TRUE;
-
-	if (session != NULL)
-		local_free_session = session;
-	else
-		{
-		(void) pthread_mutex_lock(session_cache[OP_RSA].lock);
-		local_free_session = session_cache[OP_RSA].head;
-		uselock = CK_FALSE;
-		}
-
-	/*
-	 * go through the list of sessions and delete key objects
-	 */
-	while ((sp = local_free_session) != NULL)
-		{
-		local_free_session = sp->next;
-
-		/*
-		 * Do not terminate list traversal if one of the
-		 * destroy operations fails.
-		 */
-		if (pk11_destroy_rsa_object_pub(sp, uselock) == 0)
-			{
-			ret = 0;
-			continue;
-			}
-		if (pk11_destroy_rsa_object_priv(sp, uselock) == 0)
-			{
-			ret = 0;
-			continue;
-			}
-		}
-
-	if (session == NULL)
-		(void) pthread_mutex_unlock(session_cache[OP_RSA].lock);
-
-	return (ret);
-	}
-#endif	/* OPENSSL_NO_RSA */
-
-#ifndef OPENSSL_NO_DSA
-/* Destroy DSA public key from single session. */
-int
-pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
-	{
-	int ret = 0;
-
-	if (sp->opdata_dsa_pub_key != CK_INVALID_HANDLE)
-		{
-		TRY_OBJ_DESTROY(sp, sp->opdata_dsa_pub_key,
-		    ret, uselock, OP_DSA);
-		sp->opdata_dsa_pub_key = CK_INVALID_HANDLE;
-		sp->opdata_dsa_pub = NULL;
-		if (sp->opdata_dsa_pub_num != NULL)
-			{
-			BN_free(sp->opdata_dsa_pub_num);
-			sp->opdata_dsa_pub_num = NULL;
-			}
-		}
-
-	return (ret);
-	}
-
-/* Destroy DSA private key from single session. */
-int
-pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
-	{
-	int ret = 0;
-
-	if (sp->opdata_dsa_priv_key != CK_INVALID_HANDLE)
-		{
-		TRY_OBJ_DESTROY(sp, sp->opdata_dsa_priv_key,
-		    ret, uselock, OP_DSA);
-		sp->opdata_dsa_priv_key = CK_INVALID_HANDLE;
-		sp->opdata_dsa_priv = NULL;
-		if (sp->opdata_dsa_priv_num != NULL)
-			{
-			BN_free(sp->opdata_dsa_priv_num);
-			sp->opdata_dsa_priv_num = NULL;
-			}
-		}
-
-	return (ret);
-	}
-
-/*
- * Destroy DSA key object wrapper. If session is NULL, try to destroy all
- * objects in the free list.
- */
-int
-pk11_destroy_dsa_key_objects(PK11_SESSION *session)
-	{
-	int ret = 1;
-	PK11_SESSION *sp = NULL;
-	PK11_SESSION *local_free_session;
-	CK_BBOOL uselock = CK_TRUE;
-
-	if (session != NULL)
-		local_free_session = session;
-	else
-		{
-		(void) pthread_mutex_lock(session_cache[OP_DSA].lock);
-		local_free_session = session_cache[OP_DSA].head;
-		uselock = CK_FALSE;
-		}
-
-	/*
-	 * go through the list of sessions and delete key objects
-	 */
-	while ((sp = local_free_session) != NULL)
-		{
-		local_free_session = sp->next;
-
-		/*
-		 * Do not terminate list traversal if one of the
-		 * destroy operations fails.
-		 */
-		if (pk11_destroy_dsa_object_pub(sp, uselock) == 0)
-			{
-			ret = 0;
-			continue;
-			}
-		if (pk11_destroy_dsa_object_priv(sp, uselock) == 0)
-			{
-			ret = 0;
-			continue;
-			}
-		}
-
-	if (session == NULL)
-		(void) pthread_mutex_unlock(session_cache[OP_DSA].lock);
-
-	return (ret);
-	}
-#endif	/* OPENSSL_NO_DSA */
-
-#ifndef OPENSSL_NO_DH
-/* Destroy DH key from single session. */
-int
-pk11_destroy_dh_object(PK11_SESSION *sp, CK_BBOOL uselock)
-	{
-	int ret = 0;
-
-	if (sp->opdata_dh_key != CK_INVALID_HANDLE)
-		{
-		TRY_OBJ_DESTROY(sp, sp->opdata_dh_key,
-		    ret, uselock, OP_DH);
-		sp->opdata_dh_key = CK_INVALID_HANDLE;
-		sp->opdata_dh = NULL;
-		if (sp->opdata_dh_priv_num != NULL)
-			{
-			BN_free(sp->opdata_dh_priv_num);
-			sp->opdata_dh_priv_num = NULL;
-			}
-		}
-
-	return (ret);
-	}
-
-/*
- * Destroy DH key object wrapper.
- *
- * arg0: pointer to PKCS#11 engine session structure
- *       if session is NULL, try to destroy all objects in the free list
- */
-int
-pk11_destroy_dh_key_objects(PK11_SESSION *session)
-	{
-	int ret = 1;
-	PK11_SESSION *sp = NULL;
-	PK11_SESSION *local_free_session;
-	CK_BBOOL uselock = CK_TRUE;
-
-	if (session != NULL)
-		local_free_session = session;
-	else
-		{
-		(void) pthread_mutex_lock(session_cache[OP_DH].lock);
-		local_free_session = session_cache[OP_DH].head;
-		uselock = CK_FALSE;
-		}
-
-	while ((sp = local_free_session) != NULL)
-		{
-		local_free_session = sp->next;
-
-		/*
-		 * Do not terminate list traversal if one of the
-		 * destroy operations fails.
-		 */
-		if (pk11_destroy_dh_object(sp, uselock) == 0)
-			{
-			ret = 0;
-			continue;
-			}
-		}
-	if (session == NULL)
-		(void) pthread_mutex_unlock(session_cache[OP_DH].lock);
-
-	return (ret);
-	}
-#endif	/* OPENSSL_NO_DH */
-
-static int
-pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
-    CK_BBOOL persistent)
-	{
-	CK_RV rv;
-
-	/*
-	 * We never try to destroy persistent objects which are the objects
-	 * stored in the keystore. Also, we always use read-only sessions so
-	 * C_DestroyObject() would be returning CKR_SESSION_READ_ONLY here.
-	 */
-	if (persistent == CK_TRUE)
-		return (1);
-
-	rv = pFuncList->C_DestroyObject(session, oh);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DESTROY_OBJECT, PK11_R_DESTROYOBJECT,
-		    rv);
-		return (0);
-		}
-
-	return (1);
-	}
-
-
-/* Symmetric ciphers and digests support functions */
-
-static int
-cipher_nid_to_pk11(int nid)
-	{
-	int i;
-
-	for (i = 0; i < PK11_CIPHER_MAX; i++)
-		if (ciphers[i].nid == nid)
-			return (ciphers[i].id);
-	return (-1);
-	}
-
-static int
-pk11_usable_ciphers(const int **nids)
-	{
-	if (cipher_count > 0)
-		*nids = cipher_nids;
-	else
-		*nids = NULL;
-	return (cipher_count);
-	}
-
-static int
-pk11_usable_digests(const int **nids)
-	{
-	if (digest_count > 0)
-		*nids = digest_nids;
-	else
-		*nids = NULL;
-	return (digest_count);
-	}
-
-/*
- * Init context for encryption or decryption using a symmetric key.
- */
-static int pk11_init_symmetric(EVP_CIPHER_CTX *ctx, PK11_CIPHER *pcipher,
-	PK11_SESSION *sp, CK_MECHANISM_PTR pmech)
-	{
-	CK_RV rv;
-	CK_AES_CTR_PARAMS ctr_params;
-
-	/*
-	 * We expect pmech->mechanism to be already set and
-	 * pParameter/ulParameterLen initialized to NULL/0 before
-	 * pk11_init_symmetric() is called.
-	 */
-	OPENSSL_assert(pmech->mechanism != NULL);
-	OPENSSL_assert(pmech->pParameter == NULL);
-	OPENSSL_assert(pmech->ulParameterLen == 0);
-
-	if (ctx->cipher->nid == NID_aes_128_ctr ||
-	    ctx->cipher->nid == NID_aes_192_ctr ||
-	    ctx->cipher->nid == NID_aes_256_ctr)
-		{
-		pmech->pParameter = (void *)(&ctr_params);
-		pmech->ulParameterLen = sizeof (ctr_params);
-		/*
-		 * For now, we are limited to the fixed length of the counter,
-		 * it covers the whole counter block. That's what RFC 4344
-		 * needs. For more information on internal structure of the
-		 * counter block, see RFC 3686. If needed in the future, we can
-		 * add code so that the counter length can be set via
-		 * ENGINE_ctrl() function.
-		 */
-		ctr_params.ulCounterBits = AES_BLOCK_SIZE * 8;
-		OPENSSL_assert(pcipher->iv_len == AES_BLOCK_SIZE);
-		(void) memcpy(ctr_params.cb, ctx->iv, AES_BLOCK_SIZE);
-		}
-	else
-		{
-		if (pcipher->iv_len > 0)
-			{
-			pmech->pParameter = (void *)ctx->iv;
-			pmech->ulParameterLen = pcipher->iv_len;
-			}
-		}
-
-	/* if we get here, the encryption needs to be reinitialized */
-	if (ctx->encrypt)
-		rv = pFuncList->C_EncryptInit(sp->session, pmech,
-			sp->opdata_cipher_key);
-	else
-		rv = pFuncList->C_DecryptInit(sp->session, pmech,
-			sp->opdata_cipher_key);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_CIPHER_INIT, ctx->encrypt ?
-		    PK11_R_ENCRYPTINIT : PK11_R_DECRYPTINIT, rv);
-		pk11_return_session(sp, OP_CIPHER);
-		return (0);
-		}
-
-	return (1);
-	}
-
-/* ARGSUSED */
-static int
-pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-    const unsigned char *iv, int enc)
-	{
-	CK_MECHANISM mech;
-	int index;
-	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
-	PK11_SESSION *sp;
-	PK11_CIPHER *p_ciph_table_row;
-
-	state->sp = NULL;
-
-	index = cipher_nid_to_pk11(ctx->cipher->nid);
-	if (index < 0 || index >= PK11_CIPHER_MAX)
-		return (0);
-
-	p_ciph_table_row = &ciphers[index];
-	/*
-	 * iv_len in the ctx->cipher structure is the maximum IV length for the
-	 * current cipher and it must be less or equal to the IV length in our
-	 * ciphers table. The key length must be in the allowed interval. From
-	 * all cipher modes that the PKCS#11 engine supports only RC4 allows a
-	 * key length to be in some range, all other NIDs have a precise key
-	 * length. Every application can define its own EVP functions so this
-	 * code serves as a sanity check.
-	 *
-	 * Note that the reason why the IV length in ctx->cipher might be
-	 * greater than the actual length is that OpenSSL uses BLOCK_CIPHER_defs
-	 * macro to define functions that return EVP structures for all DES
-	 * modes. So, even ECB modes get 8 byte IV.
-	 */
-	if (ctx->cipher->iv_len < p_ciph_table_row->iv_len ||
-	    ctx->key_len < p_ciph_table_row->min_key_len ||
-	    ctx->key_len > p_ciph_table_row->max_key_len) {
-		PK11err(PK11_F_CIPHER_INIT, PK11_R_KEY_OR_IV_LEN_PROBLEM);
-		return (0);
-	}
-
-	if ((sp = pk11_get_session(OP_CIPHER)) == NULL)
-		return (0);
-
-	/* if applicable, the mechanism parameter is used for IV */
-	mech.mechanism = p_ciph_table_row->mech_type;
-	mech.pParameter = NULL;
-	mech.ulParameterLen = 0;
-
-	/* The key object is destroyed here if it is not the current key. */
-	(void) check_new_cipher_key(sp, key, ctx->key_len);
-
-	/*
-	 * If the key is the same and the encryption is also the same, then
-	 * just reuse it. However, we must not forget to reinitialize the
-	 * context that was finalized in pk11_cipher_cleanup().
-	 */
-	if (sp->opdata_cipher_key != CK_INVALID_HANDLE &&
-	    sp->opdata_encrypt == ctx->encrypt)
-		{
-		state->sp = sp;
-		if (pk11_init_symmetric(ctx, p_ciph_table_row, sp, &mech) == 0)
-			return (0);
-
-		return (1);
-		}
-
-	/*
-	 * Check if the key has been invalidated. If so, a new key object
-	 * needs to be created.
-	 */
-	if (sp->opdata_cipher_key == CK_INVALID_HANDLE)
-		{
-		sp->opdata_cipher_key = pk11_get_cipher_key(
-			ctx, key, p_ciph_table_row->key_type, sp);
-		}
-
-	if (sp->opdata_encrypt != ctx->encrypt && sp->opdata_encrypt != -1)
-		{
-		/*
-		 * The previous encryption/decryption is different. Need to
-		 * terminate the previous * active encryption/decryption here.
-		 */
-		if (!pk11_cipher_final(sp))
-			{
-			pk11_return_session(sp, OP_CIPHER);
-			return (0);
-			}
-		}
-
-	if (sp->opdata_cipher_key == CK_INVALID_HANDLE)
-		{
-		pk11_return_session(sp, OP_CIPHER);
-		return (0);
-		}
-
-	/* now initialize the context with a new key */
-	if (pk11_init_symmetric(ctx, p_ciph_table_row, sp, &mech) == 0)
-		return (0);
-
-	sp->opdata_encrypt = ctx->encrypt;
-	state->sp = sp;
-
-	return (1);
-	}
-
-/*
- * When reusing the same key in an encryption/decryption session for a
- * decryption/encryption session, we need to close the active session
- * and recreate a new one. Note that the key is in the global session so
- * that it needs not be recreated.
- *
- * It is more appropriate to use C_En/DecryptFinish here. At the time of this
- * development, these two functions in the PKCS#11 libraries used return
- * unexpected errors when passing in 0 length output. It may be a good
- * idea to try them again if performance is a problem here and fix
- * C_En/DecryptFinial if there are bugs there causing the problem.
- */
-static int
-pk11_cipher_final(PK11_SESSION *sp)
-	{
-	CK_RV rv;
-
-	rv = pFuncList->C_CloseSession(sp->session);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_CIPHER_FINAL, PK11_R_CLOSESESSION, rv);
-		return (0);
-		}
-
-	rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
-		NULL_PTR, NULL_PTR, &sp->session);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_CIPHER_FINAL, PK11_R_OPENSESSION, rv);
-		return (0);
-		}
-
-	return (1);
-	}
-
-/*
- * An engine interface function. The calling function allocates sufficient
- * memory for the output buffer "out" to hold the results.
- */
-static int
-pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-	const unsigned char *in, size_t inl)
-	{
-	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
-	PK11_SESSION *sp;
-	CK_RV rv;
-	unsigned long outl = inl;
-
-	if (state == NULL || state->sp == NULL)
-		return (0);
-
-	sp = (PK11_SESSION *) state->sp;
-
-	if (!inl)
-		return (1);
-
-	/* RC4 is the only stream cipher we support */
-	if (ctx->cipher->nid != NID_rc4 && (inl % ctx->cipher->block_size) != 0)
-		return (0);
-
-	if (ctx->encrypt)
-		{
-		rv = pFuncList->C_EncryptUpdate(sp->session,
-			(unsigned char *)in, inl, out, &outl);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_CIPHER_DO_CIPHER,
-			    PK11_R_ENCRYPTUPDATE, rv);
-			return (0);
-			}
-		}
-	else
-		{
-		rv = pFuncList->C_DecryptUpdate(sp->session,
-			(unsigned char *)in, inl, out, &outl);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_CIPHER_DO_CIPHER,
-			    PK11_R_DECRYPTUPDATE, rv);
-			return (0);
-			}
-		}
-
-	/*
-	 * For DES_CBC, DES3_CBC, AES_CBC, and RC4, the output size is always
-	 * the same size of input.
-	 * The application has guaranteed to call the block ciphers with
-	 * correctly aligned buffers.
-	 */
-	if (inl != outl)
-		return (0);
-
-	return (1);
-	}
-
-/*
- * Return the session to the pool. Calling C_EncryptFinal() and C_DecryptFinal()
- * here is the right thing because in EVP_DecryptFinal_ex(), engine's
- * do_cipher() is not even called, and in EVP_EncryptFinal_ex() it is called but
- * the engine can't find out that it's the finalizing call. We wouldn't
- * necessarily have to finalize the context here since reinitializing it with
- * C_(Encrypt|Decrypt)Init() should be fine but for the sake of correctness,
- * let's do it. Some implementations might leak memory if the previously used
- * context is initialized without finalizing it first.
- */
-static int
-pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx)
-	{
-	CK_RV rv;
-	CK_ULONG len = EVP_MAX_BLOCK_LENGTH;
-	CK_BYTE buf[EVP_MAX_BLOCK_LENGTH];
-	PK11_CIPHER_STATE *state = ctx->cipher_data;
-
-	if (state != NULL && state->sp != NULL)
-		{
-		/*
-		 * We are not interested in the data here, we just need to get
-		 * rid of the context.
-		 */
-		if (ctx->encrypt)
-			rv = pFuncList->C_EncryptFinal(
-			    state->sp->session, buf, &len);
-		else
-			rv = pFuncList->C_DecryptFinal(
-			    state->sp->session, buf, &len);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_CIPHER_CLEANUP, ctx->encrypt ?
-			    PK11_R_ENCRYPTFINAL : PK11_R_DECRYPTFINAL, rv);
-			pk11_return_session(state->sp, OP_CIPHER);
-			return (0);
-			}
-
-		pk11_return_session(state->sp, OP_CIPHER);
-		state->sp = NULL;
-		}
-
-	return (1);
-	}
-
-/*
- * Registered by the ENGINE when used to find out how to deal with
- * a particular NID in the ENGINE. This says what we'll do at the
- * top level - note, that list is restricted by what we answer with
- */
-/* ARGSUSED */
-static int
-pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
-	const int **nids, int nid)
-	{
-	if (!cipher)
-		return (pk11_usable_ciphers(nids));
-
-	switch (nid)
-		{
-		case NID_des_ede3_cbc:
-			*cipher = &pk11_3des_cbc;
-			break;
-		case NID_des_cbc:
-			*cipher = &pk11_des_cbc;
-			break;
-		case NID_des_ede3_ecb:
-			*cipher = &pk11_3des_ecb;
-			break;
-		case NID_des_ecb:
-			*cipher = &pk11_des_ecb;
-			break;
-		case NID_aes_128_cbc:
-			*cipher = &pk11_aes_128_cbc;
-			break;
-		case NID_aes_192_cbc:
-			*cipher = &pk11_aes_192_cbc;
-			break;
-		case NID_aes_256_cbc:
-			*cipher = &pk11_aes_256_cbc;
-			break;
-		case NID_aes_128_ecb:
-			*cipher = &pk11_aes_128_ecb;
-			break;
-		case NID_aes_192_ecb:
-			*cipher = &pk11_aes_192_ecb;
-			break;
-		case NID_aes_256_ecb:
-			*cipher = &pk11_aes_256_ecb;
-			break;
-		case NID_aes_128_ctr:
-			*cipher = &pk11_aes_128_ctr;
-			break;
-		case NID_aes_192_ctr:
-			*cipher = &pk11_aes_192_ctr;
-			break;
-		case NID_aes_256_ctr:
-			*cipher = &pk11_aes_256_ctr;
-			break;
-		case NID_bf_cbc:
-			*cipher = &pk11_bf_cbc;
-			break;
-		case NID_rc4:
-			*cipher = &pk11_rc4;
-			break;
-		default:
-			*cipher = NULL;
-			break;
-		}
-	return (*cipher != NULL);
-	}
-
-/* ARGSUSED */
-static int
-pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
-	const int **nids, int nid)
-	{
-	if (!digest)
-		return (pk11_usable_digests(nids));
-
-	switch (nid)
-		{
-		case NID_md5:
-			*digest = &pk11_md5;
-			break;
-		/*
-		 * A special case. For "openssl dgst -dss1 -engine pkcs11 ...",
-		 * OpenSSL calls EVP_get_digestbyname() on "dss1" which ends up
-		 * calling pk11_engine_digests() for NID_dsa. Internally, if an
-		 * engine is not used, OpenSSL uses SHA1_Init() as expected for
-		 * DSA. So, we must return pk11_sha1() for NID_dsa as well. Note
-		 * that this must have changed between 0.9.8 and 1.0.0 since we
-		 * did not have the problem with the 0.9.8 version.
-		 */
-		case NID_sha1:
-		case NID_dsa:
-			*digest = &pk11_sha1;
-			break;
-		case NID_sha224:
-			*digest = &pk11_sha224;
-			break;
-		case NID_sha256:
-			*digest = &pk11_sha256;
-			break;
-		case NID_sha384:
-			*digest = &pk11_sha384;
-			break;
-		case NID_sha512:
-			*digest = &pk11_sha512;
-			break;
-		default:
-			*digest = NULL;
-			break;
-		}
-	return (*digest != NULL);
-	}
-
-
-/* Create a secret key object in a PKCS#11 session */
-static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
-	const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp)
-	{
-	CK_RV rv;
-	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-	CK_OBJECT_CLASS obj_key = CKO_SECRET_KEY;
-	CK_ULONG ul_key_attr_count = 6;
-
-	CK_ATTRIBUTE  a_key_template[] =
-		{
-		{CKA_CLASS, (void*) NULL, sizeof (CK_OBJECT_CLASS)},
-		{CKA_KEY_TYPE, (void*) NULL, sizeof (CK_KEY_TYPE)},
-		{CKA_TOKEN, &pk11_false, sizeof (pk11_false)},
-		{CKA_ENCRYPT, &pk11_true, sizeof (pk11_true)},
-		{CKA_DECRYPT, &pk11_true, sizeof (pk11_true)},
-		{CKA_VALUE, (void*) NULL, 0},
-		};
-
-	/*
-	 * Create secret key object in global_session. All other sessions
-	 * can use the key handles. Here is why:
-	 * OpenSSL will call EncryptInit and EncryptUpdate using a secret key.
-	 * It may then call DecryptInit and DecryptUpdate using the same key.
-	 * To use the same key object, we need to call EncryptFinal with
-	 * a 0 length message. Currently, this does not work for 3DES
-	 * mechanism. To get around this problem, we close the session and
-	 * then create a new session to use the same key object. When a session
-	 * is closed, all the object handles will be invalid. Thus, create key
-	 * objects in a global session, an individual session may be closed to
-	 * terminate the active operation.
-	 */
-	CK_SESSION_HANDLE session = global_session;
-	a_key_template[0].pValue = &obj_key;
-	a_key_template[1].pValue = &key_type;
-	a_key_template[5].pValue = (void *) key;
-	a_key_template[5].ulValueLen = (unsigned long) ctx->key_len;
-
-	rv = pFuncList->C_CreateObject(session,
-		a_key_template, ul_key_attr_count, &h_key);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_CIPHER_KEY, PK11_R_CREATEOBJECT,
-		    rv);
-		goto err;
-		}
-
-	/*
-	 * Save the key information used in this session.
-	 * The max can be saved is PK11_KEY_LEN_MAX.
-	 */
-	sp->opdata_key_len = ctx->key_len > PK11_KEY_LEN_MAX ?
-		PK11_KEY_LEN_MAX : ctx->key_len;
-	(void) memcpy(sp->opdata_key, key, sp->opdata_key_len);
-err:
-
-	return (h_key);
-	}
-
-static int
-md_nid_to_pk11(int nid)
-	{
-	int i;
-
-	for (i = 0; i < PK11_DIGEST_MAX; i++)
-		if (digests[i].nid == nid)
-			return (digests[i].id);
-	return (-1);
-	}
-
-static int
-pk11_digest_init(EVP_MD_CTX *ctx)
-	{
-	CK_RV rv;
-	CK_MECHANISM mech;
-	int index;
-	PK11_SESSION *sp;
-	PK11_DIGEST *pdp;
-	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
-
-	state->sp = NULL;
-
-	index = md_nid_to_pk11(ctx->digest->type);
-	if (index < 0 || index >= PK11_DIGEST_MAX)
-		return (0);
-
-	pdp = &digests[index];
-	if ((sp = pk11_get_session(OP_DIGEST)) == NULL)
-		return (0);
-
-	/* at present, no parameter is needed for supported digests */
-	mech.mechanism = pdp->mech_type;
-	mech.pParameter = NULL;
-	mech.ulParameterLen = 0;
-
-	rv = pFuncList->C_DigestInit(sp->session, &mech);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DIGEST_INIT, PK11_R_DIGESTINIT, rv);
-		pk11_return_session(sp, OP_DIGEST);
-		return (0);
-		}
-
-	state->sp = sp;
-
-	return (1);
-	}
-
-static int
-pk11_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
-	{
-	CK_RV rv;
-	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
-
-	/* 0 length message will cause a failure in C_DigestFinal */
-	if (count == 0)
-		return (1);
-
-	if (state == NULL || state->sp == NULL)
-		return (0);
-
-	rv = pFuncList->C_DigestUpdate(state->sp->session, (CK_BYTE *) data,
-		count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DIGEST_UPDATE, PK11_R_DIGESTUPDATE, rv);
-		pk11_return_session(state->sp, OP_DIGEST);
-		state->sp = NULL;
-		return (0);
-		}
-
-	return (1);
-	}
-
-static int
-pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
-	{
-	CK_RV rv;
-	unsigned long len;
-	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
-	len = ctx->digest->md_size;
-
-	if (state == NULL || state->sp == NULL)
-		return (0);
-
-	rv = pFuncList->C_DigestFinal(state->sp->session, md, &len);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DIGEST_FINAL, PK11_R_DIGESTFINAL, rv);
-		pk11_return_session(state->sp, OP_DIGEST);
-		state->sp = NULL;
-		return (0);
-		}
-
-	if (ctx->digest->md_size != len)
-		return (0);
-
-	/*
-	 * Final is called and digest is returned, so return the session
-	 * to the pool
-	 */
-	pk11_return_session(state->sp, OP_DIGEST);
-	state->sp = NULL;
-
-	return (1);
-	}
-
-static int
-pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
-	{
-	CK_RV rv;
-	int ret = 0;
-	PK11_CIPHER_STATE *state, *state_to;
-	CK_BYTE_PTR pstate = NULL;
-	CK_ULONG ul_state_len;
-
-	if (from->md_data == NULL || to->digest->ctx_size == 0)
-		return (1);
-
-	/* The copy-from state */
-	state = (PK11_CIPHER_STATE *) from->md_data;
-	if (state->sp == NULL)
-		goto err;
-
-	/* Initialize the copy-to state */
-	if (!pk11_digest_init(to))
-		goto err;
-	state_to = (PK11_CIPHER_STATE *) to->md_data;
-
-	/* Get the size of the operation state of the copy-from session */
-	rv = pFuncList->C_GetOperationState(state->sp->session, NULL,
-		&ul_state_len);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE,
-		    rv);
-		goto err;
-		}
-	if (ul_state_len == 0)
-		{
-		goto err;
-		}
-
-	pstate = OPENSSL_malloc(ul_state_len);
-	if (pstate == NULL)
-		{
-		PK11err(PK11_F_DIGEST_COPY, PK11_R_MALLOC_FAILURE);
-		goto err;
-		}
-
-	/* Get the operation state of the copy-from session */
-	rv = pFuncList->C_GetOperationState(state->sp->session, pstate,
-		&ul_state_len);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE,
-		    rv);
-		goto err;
-		}
-
-	/* Set the operation state of the copy-to session */
-	rv = pFuncList->C_SetOperationState(state_to->sp->session, pstate,
-		ul_state_len, 0, 0);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DIGEST_COPY,
-		    PK11_R_SET_OPERATION_STATE, rv);
-		goto err;
-		}
-
-	ret = 1;
-err:
-	if (pstate != NULL)
-		OPENSSL_free(pstate);
-
-	return (ret);
-	}
-
-/* Return any pending session state to the pool */
-static int
-pk11_digest_cleanup(EVP_MD_CTX *ctx)
-	{
-	PK11_CIPHER_STATE *state = ctx->md_data;
-	unsigned char buf[EVP_MAX_MD_SIZE];
-
-	if (state != NULL && state->sp != NULL)
-		{
-		/*
-		 * If state->sp is not NULL then pk11_digest_final() has not
-		 * been called yet. We must call it now to free any memory
-		 * that might have been allocated in the token when
-		 * pk11_digest_init() was called. pk11_digest_final()
-		 * will return the session to the cache.
-		 */
-		if (!pk11_digest_final(ctx, buf))
-			return (0);
-		}
-
-	return (1);
-	}
-
-/*
- * Check if the new key is the same as the key object in the session. If the key
- * is the same, no need to create a new key object. Otherwise, the old key
- * object needs to be destroyed and a new one will be created. Return 1 for
- * cache hit, 0 for cache miss. Note that we must check the key length first
- * otherwise we could end up reusing a different, longer key with the same
- * prefix.
- */
-static int check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key,
-	int key_len)
-	{
-	if (sp->opdata_key_len != key_len ||
-	    memcmp(sp->opdata_key, key, key_len) != 0)
-		{
-		(void) pk11_destroy_cipher_key_objects(sp);
-		return (0);
-		}
-	return (1);
-	}
-
-/* Destroy one or more secret key objects. */
-static int pk11_destroy_cipher_key_objects(PK11_SESSION *session)
-	{
-	int ret = 0;
-	PK11_SESSION *sp = NULL;
-	PK11_SESSION *local_free_session;
-
-	if (session != NULL)
-		local_free_session = session;
-	else
-		{
-		(void) pthread_mutex_lock(session_cache[OP_CIPHER].lock);
-		local_free_session = session_cache[OP_CIPHER].head;
-		}
-
-	while ((sp = local_free_session) != NULL)
-		{
-		local_free_session = sp->next;
-
-		if (sp->opdata_cipher_key != CK_INVALID_HANDLE)
-			{
-			/*
-			 * The secret key object is created in the
-			 * global_session. See pk11_get_cipher_key().
-			 */
-			if (pk11_destroy_object(global_session,
-				sp->opdata_cipher_key, CK_FALSE) == 0)
-				goto err;
-			sp->opdata_cipher_key = CK_INVALID_HANDLE;
-			}
-		}
-	ret = 1;
-err:
-
-	if (session == NULL)
-		(void) pthread_mutex_unlock(session_cache[OP_CIPHER].lock);
-
-	return (ret);
-	}
-
-
-/*
- * Public key mechanisms optionally supported
- *
- * CKM_RSA_X_509
- * CKM_RSA_PKCS
- * CKM_DSA
- *
- * The first slot that supports at least one of those mechanisms is chosen as a
- * public key slot.
- *
- * Symmetric ciphers optionally supported
- *
- * CKM_DES3_CBC
- * CKM_DES_CBC
- * CKM_AES_CBC
- * CKM_DES3_ECB
- * CKM_DES_ECB
- * CKM_AES_ECB
- * CKM_AES_CTR
- * CKM_RC4
- * CKM_BLOWFISH_CBC
- *
- * Digests optionally supported
- *
- * CKM_MD5
- * CKM_SHA_1
- * CKM_SHA224
- * CKM_SHA256
- * CKM_SHA384
- * CKM_SHA512
- *
- * The output of this function is a set of global variables indicating which
- * mechanisms from RSA, DSA, DH and RAND are present, and also two arrays of
- * mechanisms, one for symmetric ciphers and one for digests. Also, 3 global
- * variables carry information about which slot was chosen for (a) public key
- * mechanisms, (b) random operations, and (c) symmetric ciphers and digests.
- */
-static int
-pk11_choose_slots(int *any_slot_found)
-	{
-	CK_SLOT_ID_PTR pSlotList = NULL_PTR;
-	CK_ULONG ulSlotCount = 0;
-	CK_MECHANISM_INFO mech_info;
-	CK_TOKEN_INFO token_info;
-	int i;
-	CK_RV rv;
-	CK_SLOT_ID best_slot_sofar;
-	CK_BBOOL found_candidate_slot = CK_FALSE;
-	int slot_n_cipher = 0;
-	int slot_n_digest = 0;
-	CK_SLOT_ID current_slot = 0;
-	int current_slot_n_cipher = 0;
-	int current_slot_n_digest = 0;
-
-	int local_cipher_nids[PK11_CIPHER_MAX];
-	int local_digest_nids[PK11_DIGEST_MAX];
-
-	/* let's initialize the output parameter */
-	if (any_slot_found != NULL)
-		*any_slot_found = 0;
-
-	/* Get slot list for memory allocation */
-	rv = pFuncList->C_GetSlotList(CK_FALSE, NULL_PTR, &ulSlotCount);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
-		return (0);
-		}
-
-	/* it's not an error if we didn't find any providers */
-	if (ulSlotCount == 0)
-		{
-		DEBUG_SLOT_SEL("%s: no crypto providers found\n", PK11_DBG);
-		return (1);
-		}
-
-	pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
-
-	if (pSlotList == NULL)
-		{
-		PK11err(PK11_F_CHOOSE_SLOT, PK11_R_MALLOC_FAILURE);
-		return (0);
-		}
-
-	/* Get the slot list for processing */
-	rv = pFuncList->C_GetSlotList(CK_FALSE, pSlotList, &ulSlotCount);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
-		OPENSSL_free(pSlotList);
-		return (0);
-		}
-
-	DEBUG_SLOT_SEL("%s: provider: %s\n", PK11_DBG, def_PK11_LIBNAME);
-	DEBUG_SLOT_SEL("%s: number of slots: %d\n", PK11_DBG, ulSlotCount);
-
-	DEBUG_SLOT_SEL("%s: == checking rand slots ==\n", PK11_DBG);
-	for (i = 0; i < ulSlotCount; i++)
-		{
-		current_slot = pSlotList[i];
-
-		DEBUG_SLOT_SEL("%s: checking slot: %d\n", PK11_DBG, i);
-		/* Check if slot has random support. */
-		rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
-		if (rv != CKR_OK)
-			continue;
-
-		DEBUG_SLOT_SEL("%s: token label: %.32s\n", PK11_DBG,
-		    token_info.label);
-
-		if (token_info.flags & CKF_RNG)
-			{
-			DEBUG_SLOT_SEL(
-			    "%s: this token has CKF_RNG flag\n", PK11_DBG);
-			pk11_have_random = CK_TRUE;
-			rand_SLOTID = current_slot;
-			break;
-			}
-		}
-
-	DEBUG_SLOT_SEL("%s: == checking pubkey slots ==\n", PK11_DBG);
-
-	pubkey_SLOTID = pSlotList[0];
-	for (i = 0; i < ulSlotCount; i++)
-		{
-		CK_BBOOL slot_has_rsa = CK_FALSE;
-		CK_BBOOL slot_has_dsa = CK_FALSE;
-		CK_BBOOL slot_has_dh = CK_FALSE;
-		current_slot = pSlotList[i];
-
-		DEBUG_SLOT_SEL("%s: checking slot: %d\n", PK11_DBG, i);
-		rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
-		if (rv != CKR_OK)
-			continue;
-
-		DEBUG_SLOT_SEL("%s: token label: %.32s\n", PK11_DBG,
-		    token_info.label);
-
-#ifndef OPENSSL_NO_RSA
-		/*
-		 * Check if this slot is capable of signing and
-		 * verifying with CKM_RSA_PKCS.
-		 */
-		rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS,
-			&mech_info);
-
-		if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
-				(mech_info.flags & CKF_VERIFY)))
-			{
-			/*
-			 * Check if this slot is capable of encryption,
-			 * decryption, sign, and verify with CKM_RSA_X_509.
-			 */
-			rv = pFuncList->C_GetMechanismInfo(current_slot,
-			    CKM_RSA_X_509, &mech_info);
-
-			if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
-			    (mech_info.flags & CKF_VERIFY) &&
-			    (mech_info.flags & CKF_ENCRYPT) &&
-			    (mech_info.flags & CKF_VERIFY_RECOVER) &&
-			    (mech_info.flags & CKF_DECRYPT)))
-				{
-				slot_has_rsa = CK_TRUE;
-				}
-			}
-#endif	/* OPENSSL_NO_RSA */
-
-#ifndef OPENSSL_NO_DSA
-		/*
-		 * Check if this slot is capable of signing and
-		 * verifying with CKM_DSA.
-		 */
-		rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_DSA,
-			&mech_info);
-		if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
-		    (mech_info.flags & CKF_VERIFY)))
-			{
-			slot_has_dsa = CK_TRUE;
-			}
-
-#endif	/* OPENSSL_NO_DSA */
-
-#ifndef OPENSSL_NO_DH
-		/*
-		 * Check if this slot is capable of DH key generataion and
-		 * derivation.
-		 */
-		rv = pFuncList->C_GetMechanismInfo(current_slot,
-		    CKM_DH_PKCS_KEY_PAIR_GEN, &mech_info);
-
-		if (rv == CKR_OK && (mech_info.flags & CKF_GENERATE_KEY_PAIR))
-			{
-			rv = pFuncList->C_GetMechanismInfo(current_slot,
-				CKM_DH_PKCS_DERIVE, &mech_info);
-			if (rv == CKR_OK && (mech_info.flags & CKF_DERIVE))
-				{
-				slot_has_dh = CK_TRUE;
-				}
-			}
-#endif	/* OPENSSL_NO_DH */
-
-		if (!found_candidate_slot &&
-		    (slot_has_rsa || slot_has_dsa || slot_has_dh))
-			{
-			DEBUG_SLOT_SEL(
-			    "%s: potential slot: %d\n", PK11_DBG, current_slot);
-			best_slot_sofar = current_slot;
-			pk11_have_rsa = slot_has_rsa;
-			pk11_have_dsa = slot_has_dsa;
-			pk11_have_dh = slot_has_dh;
-			found_candidate_slot = CK_TRUE;
-			/*
-			 * Cache the flags for later use. We might need those if
-			 * RSA keys by reference feature is used.
-			 */
-			pubkey_token_flags = token_info.flags;
-			DEBUG_SLOT_SEL(
-			    "%s: setting found_candidate_slot to CK_TRUE\n",
-			    PK11_DBG);
-			DEBUG_SLOT_SEL("%s: best slot so far: %d\n", PK11_DBG,
-			    best_slot_sofar);
-			DEBUG_SLOT_SEL("%s: pubkey flags changed to "
-			    "%lu.\n", PK11_DBG, pubkey_token_flags);
-			}
-		else
-			{
-			DEBUG_SLOT_SEL("%s: no rsa/dsa/dh\n", PK11_DBG);
-			}
-		} /* for */
-
-	if (found_candidate_slot == CK_TRUE)
-		{
-		pubkey_SLOTID = best_slot_sofar;
-		}
-
-	found_candidate_slot = CK_FALSE;
-	best_slot_sofar = 0;
-
-	DEBUG_SLOT_SEL("%s: == checking cipher/digest ==\n", PK11_DBG);
-
-	SLOTID = pSlotList[0];
-	for (i = 0; i < ulSlotCount; i++)
-		{
-		DEBUG_SLOT_SEL("%s: checking slot: %d\n", PK11_DBG, i);
-
-		current_slot = pSlotList[i];
-		current_slot_n_cipher = 0;
-		current_slot_n_digest = 0;
-		(void) memset(local_cipher_nids, 0, sizeof (local_cipher_nids));
-		(void) memset(local_digest_nids, 0, sizeof (local_digest_nids));
-
-		pk11_find_symmetric_ciphers(pFuncList, current_slot,
-		    &current_slot_n_cipher, local_cipher_nids);
-
-		pk11_find_digests(pFuncList, current_slot,
-		    &current_slot_n_digest, local_digest_nids);
-
-		DEBUG_SLOT_SEL("%s: current_slot_n_cipher %d\n", PK11_DBG,
-			current_slot_n_cipher);
-		DEBUG_SLOT_SEL("%s: current_slot_n_digest %d\n", PK11_DBG,
-			current_slot_n_digest);
-		DEBUG_SLOT_SEL("%s: best cipher/digest slot so far: %d\n",
-			PK11_DBG, best_slot_sofar);
-
-		/*
-		 * If the current slot supports more ciphers/digests than
-		 * the previous best one we change the current best to this one,
-		 * otherwise leave it where it is.
-		 */
-		if ((current_slot_n_cipher + current_slot_n_digest) >
-		    (slot_n_cipher + slot_n_digest))
-			{
-			DEBUG_SLOT_SEL("%s: changing best slot to %d\n",
-				PK11_DBG, current_slot);
-			best_slot_sofar = SLOTID = current_slot;
-			cipher_count = slot_n_cipher = current_slot_n_cipher;
-			digest_count = slot_n_digest = current_slot_n_digest;
-			(void) memcpy(cipher_nids, local_cipher_nids,
-			    sizeof (local_cipher_nids));
-			(void) memcpy(digest_nids, local_digest_nids,
-			    sizeof (local_digest_nids));
-			}
-		}
-
-	DEBUG_SLOT_SEL("%s: chosen pubkey slot: %d\n", PK11_DBG, pubkey_SLOTID);
-	DEBUG_SLOT_SEL("%s: chosen rand slot: %d\n", PK11_DBG, rand_SLOTID);
-	DEBUG_SLOT_SEL("%s: chosen cipher/digest slot: %d\n", PK11_DBG, SLOTID);
-	DEBUG_SLOT_SEL("%s: pk11_have_rsa %d\n", PK11_DBG, pk11_have_rsa);
-	DEBUG_SLOT_SEL("%s: pk11_have_dsa %d\n", PK11_DBG, pk11_have_dsa);
-	DEBUG_SLOT_SEL("%s: pk11_have_dh %d\n", PK11_DBG, pk11_have_dh);
-	DEBUG_SLOT_SEL("%s: pk11_have_random %d\n", PK11_DBG, pk11_have_random);
-	DEBUG_SLOT_SEL("%s: cipher_count %d\n", PK11_DBG, cipher_count);
-	DEBUG_SLOT_SEL("%s: digest_count %d\n", PK11_DBG, digest_count);
-
-	if (pSlotList != NULL)
-		OPENSSL_free(pSlotList);
-
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-	OPENSSL_free(hw_cnids);
-	OPENSSL_free(hw_dnids);
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-
-	if (any_slot_found != NULL)
-		*any_slot_found = 1;
-	return (1);
-	}
-
-static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR pflist,
-    int slot_id, int *current_slot_n_cipher, int *local_cipher_nids,
-    PK11_CIPHER *cipher)
-	{
-	CK_MECHANISM_INFO mech_info;
-	CK_RV rv;
-
-	DEBUG_SLOT_SEL("%s: checking mech: %x", PK11_DBG, cipher->mech_type);
-	rv = pflist->C_GetMechanismInfo(slot_id, cipher->mech_type, &mech_info);
-
-	if (rv != CKR_OK)
-		{
-		DEBUG_SLOT_SEL(" not found\n");
-		return;
-		}
-
-	if ((mech_info.flags & CKF_ENCRYPT) &&
-	    (mech_info.flags & CKF_DECRYPT))
-		{
-		if (mech_info.ulMinKeySize > cipher->min_key_len ||
-		    mech_info.ulMaxKeySize < cipher->max_key_len)
-			{
-			DEBUG_SLOT_SEL(" engine key size range <%i-%i> does not"
-			    " match mech range <%lu-%lu>\n",
-			    cipher->min_key_len, cipher->max_key_len,
-			    mech_info.ulMinKeySize, mech_info.ulMaxKeySize);
-			return;
-			}
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-		if (nid_in_table(cipher->nid, hw_cnids))
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-			{
-			DEBUG_SLOT_SEL(" usable\n");
-			local_cipher_nids[(*current_slot_n_cipher)++] =
-			    cipher->nid;
-			}
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-		else
-			{
-			DEBUG_SLOT_SEL(
-			    " rejected, software implementation only\n");
-			}
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-		}
-	else
-		{
-		DEBUG_SLOT_SEL(" unusable\n");
-		}
-
-	return;
-	}
-
-static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
-    int *current_slot_n_digest, int *local_digest_nids, PK11_DIGEST *digest)
-	{
-	CK_MECHANISM_INFO mech_info;
-	CK_RV rv;
-
-	DEBUG_SLOT_SEL("%s: checking mech: %x", PK11_DBG, digest->mech_type);
-	rv = pflist->C_GetMechanismInfo(slot_id, digest->mech_type, &mech_info);
-
-	if (rv != CKR_OK)
-		{
-		DEBUG_SLOT_SEL(" not found\n");
-		return;
-		}
-
-	if (mech_info.flags & CKF_DIGEST)
-		{
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-		if (nid_in_table(digest->nid, hw_dnids))
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-			{
-			DEBUG_SLOT_SEL(" usable\n");
-			local_digest_nids[(*current_slot_n_digest)++] =
-			    digest->nid;
-			}
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-		else
-			{
-			DEBUG_SLOT_SEL(
-			    " rejected, software implementation only\n");
-			}
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-		}
-	else
-		{
-		DEBUG_SLOT_SEL(" unusable\n");
-		}
-
-	return;
-	}
-
-/* Find what symmetric ciphers this slot supports. */
-static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
-    CK_SLOT_ID current_slot, int *current_slot_n_cipher, int *local_cipher_nids)
-	{
-	int i;
-
-	for (i = 0; i < PK11_CIPHER_MAX; ++i)
-		{
-		pk11_get_symmetric_cipher(pflist, current_slot,
-		    current_slot_n_cipher, local_cipher_nids, &ciphers[i]);
-		}
-	}
-
-/* Find what digest algorithms this slot supports. */
-static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
-    CK_SLOT_ID current_slot, int *current_slot_n_digest, int *local_digest_nids)
-	{
-	int i;
-
-	for (i = 0; i < PK11_DIGEST_MAX; ++i)
-		{
-		pk11_get_digest(pflist, current_slot, current_slot_n_digest,
-		    local_digest_nids, &digests[i]);
-		}
-	}
-
-#ifdef	SOLARIS_HW_SLOT_SELECTION
-/*
- * It would be great if we could use pkcs11_kernel directly since this library
- * offers hardware slots only. That's the easiest way to achieve the situation
- * where we use the hardware accelerators when present and OpenSSL native code
- * otherwise. That presumes the fact that OpenSSL native code is faster than the
- * code in the soft token. It's a logical assumption - Crypto Framework has some
- * inherent overhead so going there for the software implementation of a
- * mechanism should be logically slower in contrast to the OpenSSL native code,
- * presuming that both implementations are of similar speed. For example, the
- * soft token for AES is roughly three times slower than OpenSSL for 64 byte
- * blocks and still 20% slower for 8KB blocks. So, if we want to ship products
- * that use the PKCS#11 engine by default, we must somehow avoid that regression
- * on machines without hardware acceleration. That's why switching to the
- * pkcs11_kernel library seems like a very good idea.
- *
- * The problem is that OpenSSL built with SunStudio is roughly 2x slower for
- * asymmetric operations (RSA/DSA/DH) than the soft token built with the same
- * compiler. That means that if we switched to pkcs11_kernel from the libpkcs11
- * library, we would have had a performance regression on machines without
- * hardware acceleration for asymmetric operations for all applications that use
- * the PKCS#11 engine. There is one such application - Apache web server since
- * it's shipped configured to use the PKCS#11 engine by default. Having said
- * that, we can't switch to the pkcs11_kernel library now and have to come with
- * a solution that, on non-accelerated machines, uses the OpenSSL native code
- * for all symmetric ciphers and digests while it uses the soft token for
- * asymmetric operations.
- *
- * This is the idea: dlopen() pkcs11_kernel directly and find out what
- * mechanisms are there. We don't care about duplications (more slots can
- * support the same mechanism), we just want to know what mechanisms can be
- * possibly supported in hardware on that particular machine. As said before,
- * pkcs11_kernel will show you hardware providers only.
- *
- * Then, we rely on the fact that since we use libpkcs11 library we will find
- * the metaslot. When we go through the metaslot's mechanisms for symmetric
- * ciphers and digests, we check that any found mechanism is in the table
- * created using the pkcs11_kernel library. So, as a result we have two arrays
- * of mechanisms that were advertised as supported in hardware which was the
- * goal of that whole exercise. Thus, we can use libpkcs11 but avoid soft token
- * code for symmetric ciphers and digests. See pk11_choose_slots() for more
- * information.
- *
- * This is Solaris specific code, if SOLARIS_HW_SLOT_SELECTION is not defined
- * the code won't be used.
- */
-#if defined(__sparcv9) || defined(__x86_64) || defined(__amd64)
-static const char pkcs11_kernel[] = "/usr/lib/security/64/pkcs11_kernel.so.1";
-#else
-static const char pkcs11_kernel[] = "/usr/lib/security/pkcs11_kernel.so.1";
-#endif
-
-/*
- * Check hardware capabilities of the machines. The output are two lists,
- * hw_cnids and hw_dnids, that contain hardware mechanisms found in all hardware
- * providers together. They are not sorted and may contain duplicate mechanisms.
- */
-static int check_hw_mechanisms(void)
-	{
-	int i;
-	CK_RV rv;
-	void *handle;
-	CK_C_GetFunctionList p;
-	CK_TOKEN_INFO token_info;
-	CK_ULONG ulSlotCount = 0;
-	int n_cipher = 0, n_digest = 0;
-	CK_FUNCTION_LIST_PTR pflist = NULL;
-	CK_SLOT_ID_PTR pSlotList = NULL_PTR;
-	int *tmp_hw_cnids = NULL, *tmp_hw_dnids = NULL;
-	int hw_ctable_size, hw_dtable_size;
-
-	DEBUG_SLOT_SEL("%s: SOLARIS_HW_SLOT_SELECTION code running\n",
-	    PK11_DBG);
-	/*
-	 * Use RTLD_GROUP to limit the pkcs11_kernel provider to its own
-	 * symbols, which prevents it from mistakenly accessing C_* functions
-	 * from the top-level PKCS#11 library.
-	 */
-	if ((handle = dlopen(pkcs11_kernel, RTLD_LAZY | RTLD_GROUP)) == NULL)
-		{
-		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
-		goto err;
-		}
-
-	if ((p = (CK_C_GetFunctionList)dlsym(handle,
-	    PK11_GET_FUNCTION_LIST)) == NULL)
-		{
-		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
-		goto err;
-		}
-
-	/* get the full function list from the loaded library */
-	if (p(&pflist) != CKR_OK)
-		{
-		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
-		goto err;
-		}
-
-	rv = pflist->C_Initialize(NULL_PTR);
-	if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
-		{
-		PK11err_add_data(PK11_F_CHECK_HW_MECHANISMS,
-		    PK11_R_INITIALIZE, rv);
-		goto err;
-		}
-
-	if (pflist->C_GetSlotList(0, NULL_PTR, &ulSlotCount) != CKR_OK)
-		{
-		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_GETSLOTLIST);
-		goto err;
-		}
-
-	/* no slots, set the hw mechanism tables as empty */
-	if (ulSlotCount == 0)
-		{
-		DEBUG_SLOT_SEL("%s: no hardware mechanisms found\n", PK11_DBG);
-		hw_cnids = OPENSSL_malloc(sizeof (int));
-		hw_dnids = OPENSSL_malloc(sizeof (int));
-		if (hw_cnids == NULL || hw_dnids == NULL)
-			{
-			PK11err(PK11_F_CHECK_HW_MECHANISMS,
-			    PK11_R_MALLOC_FAILURE);
-			return (0);
-			}
-		/* this means empty tables */
-		hw_cnids[0] = NID_undef;
-		hw_dnids[0] = NID_undef;
-		return (1);
-		}
-
-	pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
-	if (pSlotList == NULL)
-		{
-		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_MALLOC_FAILURE);
-		goto err;
-		}
-
-	/* Get the slot list for processing */
-	if (pflist->C_GetSlotList(0, pSlotList, &ulSlotCount) != CKR_OK)
-		{
-		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_GETSLOTLIST);
-		goto err;
-		}
-
-	/*
-	 * We don't care about duplicate mechanisms in multiple slots and also
-	 * reserve one slot for the terminal NID_undef which we use to stop the
-	 * search.
-	 */
-	hw_ctable_size = ulSlotCount * PK11_CIPHER_MAX + 1;
-	hw_dtable_size = ulSlotCount * PK11_DIGEST_MAX + 1;
-	tmp_hw_cnids = OPENSSL_malloc(hw_ctable_size * sizeof (int));
-	tmp_hw_dnids = OPENSSL_malloc(hw_dtable_size * sizeof (int));
-	if (tmp_hw_cnids == NULL || tmp_hw_dnids == NULL)
-		{
-		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_MALLOC_FAILURE);
-		goto err;
-		}
-
-	/*
-	 * Do not use memset since we should not rely on the fact that NID_undef
-	 * is zero now.
-	 */
-	for (i = 0; i < hw_ctable_size; ++i)
-		tmp_hw_cnids[i] = NID_undef;
-	for (i = 0; i < hw_dtable_size; ++i)
-		tmp_hw_dnids[i] = NID_undef;
-
-	DEBUG_SLOT_SEL("%s: provider: %s\n", PK11_DBG, pkcs11_kernel);
-	DEBUG_SLOT_SEL("%s: found %d hardware slots\n", PK11_DBG, ulSlotCount);
-	DEBUG_SLOT_SEL("%s: now looking for mechs supported in hw\n",
-	    PK11_DBG);
-
-	for (i = 0; i < ulSlotCount; i++)
-		{
-		if (pflist->C_GetTokenInfo(pSlotList[i], &token_info) != CKR_OK)
-			continue;
-
-		DEBUG_SLOT_SEL("%s: token label: %.32s\n", PK11_DBG,
-		    token_info.label);
-
-		/*
-		 * We are filling the hw mech tables here. Global tables are
-		 * still NULL so all mechanisms are put into tmp tables.
-		 */
-		pk11_find_symmetric_ciphers(pflist, pSlotList[i],
-		    &n_cipher, tmp_hw_cnids);
-		pk11_find_digests(pflist, pSlotList[i],
-		    &n_digest, tmp_hw_dnids);
-		}
-
-	/*
-	 * Since we are part of a library (libcrypto.so), calling this function
-	 * may have side-effects. Also, C_Finalize() is triggered by
-	 * dlclose(3C).
-	 */
-#if 0
-	pflist->C_Finalize(NULL);
-#endif
-	OPENSSL_free(pSlotList);
-	(void) dlclose(handle);
-	hw_cnids = tmp_hw_cnids;
-	hw_dnids = tmp_hw_dnids;
-
-	DEBUG_SLOT_SEL("%s: hw mechs check complete\n", PK11_DBG);
-	return (1);
-
-err:
-	if (pSlotList != NULL)
-		OPENSSL_free(pSlotList);
-	if (tmp_hw_cnids != NULL)
-		OPENSSL_free(tmp_hw_cnids);
-	if (tmp_hw_dnids != NULL)
-		OPENSSL_free(tmp_hw_dnids);
-
-	return (0);
-	}
-
-/*
- * Check presence of a NID in the table of NIDs unless the mechanism is
- * supported directly in a CPU instruction set. The table may be NULL (i.e.,
- * non-existent).
- */
-static int nid_in_table(int nid, int *nid_table)
-	{
-	int i = 0;
-
-	/*
-	 * Special case first. NULL means that we are initializing a new table.
-	 */
-	if (nid_table == NULL)
-		return (1);
-
-#if defined(__x86)
-	/*
-	 * On Intel, if we have AES-NI instruction set we route AES to the
-	 * Crypto Framework. Intel CPUs do not have other instruction sets for
-	 * HW crypto acceleration so we check the HW NID table for any other
-	 * mechanism.
-	 */
-	if (hw_aes_instruction_set_present() == 1)
-		{
-		switch (nid)
-			{
-			case NID_aes_128_ecb:
-			case NID_aes_192_ecb:
-			case NID_aes_256_ecb:
-			case NID_aes_128_cbc:
-			case NID_aes_192_cbc:
-			case NID_aes_256_cbc:
-			case NID_aes_128_ctr:
-			case NID_aes_192_ctr:
-			case NID_aes_256_ctr:
-				return (1);
-			}
-		}
-#elif defined(__sparc)
-	if (hw_aes_instruction_set_present() == 1)
-		return (1);
-#endif
-
-	/* The table is never full, there is always at least one NID_undef. */
-	while (nid_table[i] != NID_undef)
-		{
-		if (nid_table[i++] == nid)
-			{
-			DEBUG_SLOT_SEL(" (NID %d in hw table, idx %d)", nid, i);
-			return (1);
-			}
-		}
-
-	return (0);
-	}
-
-/* Do we have an AES instruction set? */
-static int
-hw_aes_instruction_set_present(void)
-	{
-	static int present = -1;
-
-	if (present == -1)
-		{
-		uint_t ui = 0;
-
-		(void) getisax(&ui, 1);
-
-#if defined(__amd64) || defined(__i386)
-		present = (ui & (AV_386_AES)) > 0;
-#elif defined(__sparc)
-		present = (ui & (AV_SPARC_AES|AV_SPARC_FJAES)) > 0;
-#endif
-		}
-
-	return (present);
-	}
-
-#endif	/* SOLARIS_HW_SLOT_SELECTION */
-
-#endif	/* OPENSSL_NO_HW_PK11 */
-#endif	/* OPENSSL_NO_HW */
--- a/components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11.h	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,257 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* crypto/engine/e_pk11.h */
-/*
- * This product includes software developed by the OpenSSL Project for
- * use in the OpenSSL Toolkit (http://www.openssl.org/).
- *
- * This project also referenced hw_pkcs11-0.9.7b.patch written by
- * Afchine Madjlessi.
- */
-/*
- * ====================================================================
- * 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
- *    [email protected].
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * ([email protected]).  This product includes software written by Tim
- * Hudson ([email protected]).
- *
- */
-
-#ifndef	E_PK11_H
-#define	E_PK11_H
-
-#include "e_pk11_err.h"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-/* max byte length of a symmetric key we support */
-#define	PK11_KEY_LEN_MAX			32
-
-/*
- * This structure encapsulates all reusable information for a PKCS#11
- * session. A list of these objects is created on behalf of the
- * calling application using an on-demand method. Each operation
- * type (see PK11_OPTYPE below) has its own per-process list.
- * Each of the lists is basically a cache for faster PKCS#11 object
- * access to avoid expensive C_Find{,Init,Final}Object() calls.
- *
- * When a new request comes in, an object will be taken from the list
- * (if there is one) or a new one is created to handle the request
- * (if the list is empty). See pk11_get_session() on how it is done.
- */
-typedef struct PK11_st_SESSION
-	{
-	struct PK11_st_SESSION	*next;
-	CK_SESSION_HANDLE	session;	/* PK11 session handle */
-	pid_t			pid;		/* Current process ID */
-	CK_BBOOL		persistent;	/* is that a keystore object? */
-	union
-		{
-#ifndef OPENSSL_NO_RSA
-		struct
-			{
-			CK_OBJECT_HANDLE	rsa_pub_key; /* pub handle */
-			CK_OBJECT_HANDLE	rsa_priv_key; /* priv handle */
-			RSA			*rsa_pub; /* pub key addr */
-			BIGNUM			*rsa_n_num; /* pub modulus */
-			BIGNUM			*rsa_e_num; /* pub exponent */
-			RSA			*rsa_priv; /* priv key addr */
-			BIGNUM			*rsa_d_num; /* priv exponent */
-			} u_RSA;
-#endif /* OPENSSL_NO_RSA */
-#ifndef OPENSSL_NO_DSA
-		struct
-			{
-			CK_OBJECT_HANDLE	dsa_pub_key; /* pub handle */
-			CK_OBJECT_HANDLE	dsa_priv_key; /* priv handle */
-			DSA			*dsa_pub; /* pub key addr */
-			BIGNUM			*dsa_pub_num; /* pub key */
-			DSA			*dsa_priv; /* priv key addr */
-			BIGNUM			*dsa_priv_num; /* priv key */
-			} u_DSA;
-#endif /* OPENSSL_NO_DSA */
-#ifndef OPENSSL_NO_DH
-		struct
-			{
-			CK_OBJECT_HANDLE	dh_key; /* key handle */
-			DH			*dh; /* dh key addr */
-			BIGNUM			*dh_priv_num; /* priv dh key */
-			} u_DH;
-#endif /* OPENSSL_NO_DH */
-		struct
-			{
-			CK_OBJECT_HANDLE	cipher_key; /* key handle */
-			unsigned char		key[PK11_KEY_LEN_MAX];
-			int			key_len; /* priv key len */
-			int			encrypt; /* 1/0 enc/decr */
-			} u_cipher;
-		} opdata_u;
-	} PK11_SESSION;
-
-#define	opdata_rsa_pub_key	opdata_u.u_RSA.rsa_pub_key
-#define	opdata_rsa_priv_key	opdata_u.u_RSA.rsa_priv_key
-#define	opdata_rsa_pub		opdata_u.u_RSA.rsa_pub
-#define	opdata_rsa_priv		opdata_u.u_RSA.rsa_priv
-#define	opdata_rsa_n_num	opdata_u.u_RSA.rsa_n_num
-#define	opdata_rsa_e_num	opdata_u.u_RSA.rsa_e_num
-#define	opdata_rsa_d_num	opdata_u.u_RSA.rsa_d_num
-#define	opdata_dsa_pub_key	opdata_u.u_DSA.dsa_pub_key
-#define	opdata_dsa_priv_key	opdata_u.u_DSA.dsa_priv_key
-#define	opdata_dsa_pub		opdata_u.u_DSA.dsa_pub
-#define	opdata_dsa_pub_num	opdata_u.u_DSA.dsa_pub_num
-#define	opdata_dsa_priv		opdata_u.u_DSA.dsa_priv
-#define	opdata_dsa_priv_num	opdata_u.u_DSA.dsa_priv_num
-#define	opdata_dh_key		opdata_u.u_DH.dh_key
-#define	opdata_dh		opdata_u.u_DH.dh
-#define	opdata_dh_priv_num	opdata_u.u_DH.dh_priv_num
-#define	opdata_cipher_key	opdata_u.u_cipher.cipher_key
-#define	opdata_key		opdata_u.u_cipher.key
-#define	opdata_key_len		opdata_u.u_cipher.key_len
-#define	opdata_encrypt		opdata_u.u_cipher.encrypt
-
-/*
- * We have 3 different groups of operation types:
- *   1) asymmetric operations
- *   2) random operations
- *   3) symmetric and digest operations
- *
- * This division into groups stems from the fact that it's common that hardware
- * providers may support operations from one group only. For example, hardware
- * providers on UltraSPARC T2, n2rng(7d), ncp(7d), and n2cp(7d), each support
- * only a single group of operations.
- *
- * For every group a different slot can be chosen. That means that we must have
- * at least 3 different lists of cached PKCS#11 sessions since sessions from
- * different groups may be initialized in different slots.
- *
- * To provide locking granularity in multithreaded environment, the groups are
- * further split into types with each type having a separate session cache.
- */
-typedef enum PK11_OPTYPE_ENUM
-	{
-	OP_RAND,
-	OP_RSA,
-	OP_DSA,
-	OP_DH,
-	OP_CIPHER,
-	OP_DIGEST,
-	OP_MAX
-	} PK11_OPTYPE;
-
-/*
- * This structure contains the heads of the lists forming the object caches
- * and locks associated with the lists.
- */
-typedef struct PK11_st_CACHE
-	{
-	PK11_SESSION *head;
-	pthread_mutex_t *lock;
-	} PK11_CACHE;
-
-/* structure for tracking handles of asymmetric key objects */
-typedef struct PK11_active_st
-	{
-	CK_OBJECT_HANDLE h;
-	unsigned int refcnt;
-	struct PK11_active_st *prev;
-	struct PK11_active_st *next;
-	} PK11_active;
-
-extern pthread_mutex_t *find_lock[];
-extern PK11_active *active_list[];
-/*
- * These variables are specific for the RSA keys by reference code. See
- * e_pk11_pub.c for explanation.
- */
-extern char *passphrasedialog;
-extern CK_FLAGS pubkey_token_flags;
-
-#define	LOCK_OBJSTORE(alg_type)	\
-	(void) pthread_mutex_lock(find_lock[alg_type])
-#define	UNLOCK_OBJSTORE(alg_type)	\
-	(void) pthread_mutex_unlock(find_lock[alg_type])
-
-extern PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
-extern void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
-
-#ifndef OPENSSL_NO_RSA
-extern int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
-extern int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
-extern int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
-extern EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *pubkey_file,
-	UI_METHOD *ui_method, void *callback_data);
-extern EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
-	UI_METHOD *ui_method, void *callback_data);
-extern RSA_METHOD *PK11_RSA(void);
-#endif /* OPENSSL_NO_RSA */
-#ifndef OPENSSL_NO_DSA
-extern int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
-extern int pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
-extern int pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
-extern DSA_METHOD *PK11_DSA(void);
-#endif /* OPENSSL_NO_DSA */
-#ifndef OPENSSL_NO_DH
-extern int pk11_destroy_dh_key_objects(PK11_SESSION *session);
-extern int pk11_destroy_dh_object(PK11_SESSION *sp, CK_BBOOL uselock);
-extern DH_METHOD *PK11_DH(void);
-#endif /* OPENSSL_NO_DH */
-
-extern int pk11_engine_pkey_methods(ENGINE *e, EVP_PKEY_METHOD **pmeth,
-    const int **nids, int nid);
-
-extern CK_FUNCTION_LIST_PTR pFuncList;
-
-#ifdef	__cplusplus
-}
-#endif
-#endif /* E_PK11_H */
--- a/components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11_err.c	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,306 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* crypto/engine/e_pk11_err.c */
-/*
- * This product includes software developed by the OpenSSL Project for
- * use in the OpenSSL Toolkit (http://www.openssl.org/).
- *
- * This project also referenced hw_pkcs11-0.9.7b.patch written by
- * Afchine Madjlessi.
- */
-/*
- * ====================================================================
- * 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
- *    [email protected].
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * ([email protected]).  This product includes software written by Tim
- * Hudson ([email protected]).
- *
- */
-
-#include <stdio.h>
-#include <openssl/err.h>
-#include "e_pk11_err.h"
-
-/* BEGIN ERROR CODES */
-#ifndef OPENSSL_NO_ERR
-static ERR_STRING_DATA pk11_str_functs[]=
-{
-{ ERR_PACK(0, PK11_F_INIT, 0),			"PK11_INIT"},
-{ ERR_PACK(0, PK11_F_FINISH, 0),		"PK11_FINISH"},
-{ ERR_PACK(0, PK11_F_DESTROY, 0),		"PK11_DESTROY"},
-{ ERR_PACK(0, PK11_F_CTRL, 0),			"PK11_CTRL"},
-{ ERR_PACK(0, PK11_F_RSA_INIT, 0),		"PK11_RSA_INIT"},
-{ ERR_PACK(0, PK11_F_RSA_FINISH, 0),		"PK11_RSA_FINISH"},
-{ ERR_PACK(0, PK11_F_GET_PUB_RSA_KEY, 0),	"PK11_GET_PUB_RSA_KEY"},
-{ ERR_PACK(0, PK11_F_GET_PRIV_RSA_KEY, 0),	"PK11_GET_PRIV_RSA_KEY"},
-{ ERR_PACK(0, PK11_F_RSA_GEN_KEY, 0),		"PK11_RSA_GEN_KEY"},
-{ ERR_PACK(0, PK11_F_RSA_PUB_ENC, 0),		"PK11_RSA_PUB_ENC"},
-{ ERR_PACK(0, PK11_F_RSA_PRIV_ENC, 0),		"PK11_RSA_PRIV_ENC"},
-{ ERR_PACK(0, PK11_F_RSA_PUB_DEC, 0),		"PK11_RSA_PUB_DEC"},
-{ ERR_PACK(0, PK11_F_RSA_PRIV_DEC, 0),		"PK11_RSA_PRIV_DEC"},
-{ ERR_PACK(0, PK11_F_RSA_SIGN, 0),		"PK11_RSA_SIGN"},
-{ ERR_PACK(0, PK11_F_RSA_VERIFY, 0),		"PK11_RSA_VERIFY"},
-{ ERR_PACK(0, PK11_F_RAND_ADD, 0),		"PK11_RAND_ADD"},
-{ ERR_PACK(0, PK11_F_RAND_BYTES, 0),		"PK11_RAND_BYTES"},
-{ ERR_PACK(0, PK11_F_GET_SESSION, 0),		"PK11_GET_SESSION"},
-{ ERR_PACK(0, PK11_F_FREE_SESSION, 0),		"PK11_FREE_SESSION"},
-{ ERR_PACK(0, PK11_F_LOAD_PUBKEY, 0),		"PK11_LOAD_PUBKEY"},
-{ ERR_PACK(0, PK11_F_LOAD_PRIVKEY, 0),		"PK11_LOAD_PRIV_KEY"},
-{ ERR_PACK(0, PK11_F_RSA_PUB_ENC_LOW, 0),	"PK11_RSA_PUB_ENC_LOW"},
-{ ERR_PACK(0, PK11_F_RSA_PRIV_ENC_LOW, 0),	"PK11_RSA_PRIV_ENC_LOW"},
-{ ERR_PACK(0, PK11_F_RSA_PUB_DEC_LOW, 0),	"PK11_RSA_PUB_DEC_LOW"},
-{ ERR_PACK(0, PK11_F_RSA_PRIV_DEC_LOW, 0),	"PK11_RSA_PRIV_DEC_LOW"},
-{ ERR_PACK(0, PK11_F_DSA_SIGN, 0),		"PK11_DSA_SIGN"},
-{ ERR_PACK(0, PK11_F_DSA_VERIFY, 0),		"PK11_DSA_VERIFY"},
-{ ERR_PACK(0, PK11_F_DSA_INIT, 0),		"PK11_DSA_INIT"},
-{ ERR_PACK(0, PK11_F_DSA_FINISH, 0),		"PK11_DSA_FINISH"},
-{ ERR_PACK(0, PK11_F_GET_PUB_DSA_KEY, 0),	"PK11_GET_PUB_DSA_KEY"},
-{ ERR_PACK(0, PK11_F_GET_PRIV_DSA_KEY, 0),	"PK11_GET_PRIV_DSA_KEY"},
-{ ERR_PACK(0, PK11_F_DH_INIT, 0),		"PK11_DH_INIT"},
-{ ERR_PACK(0, PK11_F_DH_FINISH, 0),		"PK11_DH_FINISH"},
-{ ERR_PACK(0, PK11_F_MOD_EXP_DH, 0),		"PK11_MOD_EXP_DH"},
-{ ERR_PACK(0, PK11_F_GET_DH_KEY, 0),		"PK11_GET_DH_KEY"},
-{ ERR_PACK(0, PK11_F_FREE_ALL_SESSIONS, 0),	"PK11_FREE_ALL_SESSIONS"},
-{ ERR_PACK(0, PK11_F_SETUP_SESSION, 0),		"PK11_SETUP_SESSION"},
-{ ERR_PACK(0, PK11_F_DESTROY_OBJECT, 0),	"PK11_DESTROY_OBJECT"},
-{ ERR_PACK(0, PK11_F_CIPHER_INIT, 0),		"PK11_CIPHER_INIT"},
-{ ERR_PACK(0, PK11_F_CIPHER_DO_CIPHER, 0),	"PK11_CIPHER_DO_CIPHER"},
-{ ERR_PACK(0, PK11_F_GET_CIPHER_KEY, 0),	"PK11_GET_CIPHER_KEY"},
-{ ERR_PACK(0, PK11_F_DIGEST_INIT, 0),		"PK11_DIGEST_INIT"},
-{ ERR_PACK(0, PK11_F_DIGEST_UPDATE, 0),		"PK11_DIGEST_UPDATE"},
-{ ERR_PACK(0, PK11_F_DIGEST_FINAL, 0),		"PK11_DIGEST_FINAL"},
-{ ERR_PACK(0, PK11_F_CHOOSE_SLOT, 0),		"PK11_CHOOSE_SLOT"},
-{ ERR_PACK(0, PK11_F_CIPHER_FINAL, 0),		"PK11_CIPHER_FINAL"},
-{ ERR_PACK(0, PK11_F_LIBRARY_INIT, 0),		"PK11_LIBRARY_INIT"},
-{ ERR_PACK(0, PK11_F_LOAD, 0),			"ENGINE_LOAD_PK11"},
-{ ERR_PACK(0, PK11_F_DH_GEN_KEY, 0),		"PK11_DH_GEN_KEY"},
-{ ERR_PACK(0, PK11_F_DH_COMP_KEY, 0),		"PK11_DH_COMP_KEY"},
-{ ERR_PACK(0, PK11_F_DIGEST_COPY, 0),		"PK11_DIGEST_COPY"},
-{ ERR_PACK(0, PK11_F_CIPHER_CLEANUP, 0),	"PK11_CIPHER_CLEANUP"},
-{ ERR_PACK(0, PK11_F_ACTIVE_ADD, 0),		"PK11_ACTIVE_ADD"},
-{ ERR_PACK(0, PK11_F_ACTIVE_DELETE, 0),		"PK11_ACTIVE_DELETE"},
-{ ERR_PACK(0, PK11_F_CHECK_HW_MECHANISMS, 0),	"PK11_CHECK_HW_MECHANISMS"},
-{ ERR_PACK(0, PK11_F_INIT_SYMMETRIC, 0),	"PK11_INIT_SYMMETRIC"},
-{ ERR_PACK(0, PK11_F_ADD_AES_CTR_NIDS, 0),	"PK11_ADD_AES_CTR_NIDS"},
-{ ERR_PACK(0, PK11_F_INIT_ALL_LOCKS, 0),	"PK11_INIT_ALL_LOCKS"},
-{ ERR_PACK(0, PK11_F_RETURN_SESSION, 0),	"PK11_RETURN_SESSION"},
-{ ERR_PACK(0, PK11_F_GET_PIN, 0),		"PK11_GET_PIN"},
-{ ERR_PACK(0, PK11_F_FIND_ONE_OBJECT, 0),	"PK11_FIND_ONE_OBJECT"},
-{ ERR_PACK(0, PK11_F_CHECK_TOKEN_ATTRS, 0),	"PK11_CHECK_TOKEN_ATTRS"},
-{ ERR_PACK(0, PK11_F_CACHE_PIN, 0),		"PK11_CACHE_PIN"},
-{ ERR_PACK(0, PK11_F_MLOCK_PIN_IN_MEMORY, 0),	"PK11_MLOCK_PIN_IN_MEMORY"},
-{ ERR_PACK(0, PK11_F_TOKEN_LOGIN, 0),		"PK11_TOKEN_LOGIN"},
-{ ERR_PACK(0, PK11_F_TOKEN_RELOGIN, 0),		"PK11_TOKEN_RELOGIN"},
-{ ERR_PACK(0, PK11_F_RUN_ASKPASS, 0),		"PK11_F_RUN_ASKPASS"},
-{ 0, NULL}
-};
-
-static ERR_STRING_DATA pk11_str_reasons[]=
-{
-{ PK11_R_ALREADY_LOADED,		"PKCS#11 DSO already loaded"},
-{ PK11_R_DSO_FAILURE,			"unable to load PKCS#11 DSO"},
-{ PK11_R_NOT_LOADED,			"PKCS#11 DSO not loaded"},
-{ PK11_R_PASSED_NULL_PARAMETER,		"null parameter passed"},
-{ PK11_R_COMMAND_NOT_IMPLEMENTED,	"command not implemented"},
-{ PK11_R_INITIALIZE,			"C_Initialize failed"},
-{ PK11_R_FINALIZE,			"C_Finalize failed"},
-{ PK11_R_GETINFO,			"C_GetInfo faile"},
-{ PK11_R_GETSLOTLIST,			"C_GetSlotList failed"},
-{ PK11_R_NO_MODULUS_OR_NO_EXPONENT,	"no modulus or no exponent"},
-{ PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID,	"attr sensitive or invalid"},
-{ PK11_R_GETATTRIBUTVALUE,		"C_GetAttributeValue failed"},
-{ PK11_R_NO_MODULUS,			"no modulus"},
-{ PK11_R_NO_EXPONENT,			"no exponent"},
-{ PK11_R_FINDOBJECTSINIT,		"C_FindObjectsInit failed"},
-{ PK11_R_FINDOBJECTS,			"C_FindObjects failed"},
-{ PK11_R_FINDOBJECTSFINAL,		"C_FindObjectsFinal failed"},
-{ PK11_R_CREATEOBJECT,			"C_CreateObject failed"},
-{ PK11_R_DESTROYOBJECT,			"C_DestroyObject failed"},
-{ PK11_R_OPENSESSION,			"C_OpenSession failed"},
-{ PK11_R_CLOSESESSION,			"C_CloseSession failed"},
-{ PK11_R_ENCRYPTINIT,			"C_EncryptInit failed"},
-{ PK11_R_ENCRYPT,			"C_Encrypt failed"},
-{ PK11_R_SIGNINIT,			"C_SignInit failed"},
-{ PK11_R_SIGN,				"C_Sign failed"},
-{ PK11_R_DECRYPTINIT,			"C_DecryptInit failed"},
-{ PK11_R_DECRYPT,			"C_Decrypt failed"},
-{ PK11_R_VERIFYINIT,			"C_VerifyRecover failed"},
-{ PK11_R_VERIFY,			"C_Verify failed"},
-{ PK11_R_VERIFYRECOVERINIT,		"C_VerifyRecoverInit failed"},
-{ PK11_R_VERIFYRECOVER,			"C_VerifyRecover failed"},
-{ PK11_R_GEN_KEY,			"C_GenerateKeyPair failed"},
-{ PK11_R_SEEDRANDOM,			"C_SeedRandom failed"},
-{ PK11_R_GENERATERANDOM,		"C_GenerateRandom failed"},
-{ PK11_R_INVALID_MESSAGE_LENGTH,	"invalid message length"},
-{ PK11_R_UNKNOWN_ALGORITHM_TYPE,	"unknown algorithm type"},
-{ PK11_R_UNKNOWN_ASN1_OBJECT_ID,	"unknown asn1 onject id"},
-{ PK11_R_UNKNOWN_PADDING_TYPE,		"unknown padding type"},
-{ PK11_R_PADDING_CHECK_FAILED,		"padding check failed"},
-{ PK11_R_DIGEST_TOO_BIG,		"digest too big"},
-{ PK11_R_MALLOC_FAILURE,		"malloc failure"},
-{ PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED,	"ctl command not implemented"},
-{ PK11_R_DATA_GREATER_THAN_MOD_LEN,	"data is bigger than mod"},
-{ PK11_R_DATA_TOO_LARGE_FOR_MODULUS,	"data is too larger for mod"},
-{ PK11_R_MISSING_KEY_COMPONENT,		"a dsa component is missing"},
-{ PK11_R_INVALID_SIGNATURE_LENGTH,	"invalid signature length"},
-{ PK11_R_INVALID_DSA_SIGNATURE_R,	"missing r in dsa verify"},
-{ PK11_R_INVALID_DSA_SIGNATURE_S,	"missing s in dsa verify"},
-{ PK11_R_INCONSISTENT_KEY,		"inconsistent key type"},
-{ PK11_R_ENCRYPTUPDATE,			"C_EncryptUpdate failed"},
-{ PK11_R_DECRYPTUPDATE,			"C_DecryptUpdate failed"},
-{ PK11_R_DIGESTINIT,			"C_DigestInit failed"},
-{ PK11_R_DIGESTUPDATE,			"C_DigestUpdate failed"},
-{ PK11_R_DIGESTFINAL,			"C_DigestFinal failed"},
-{ PK11_R_ENCRYPTFINAL,			"C_EncryptFinal failed"},
-{ PK11_R_DECRYPTFINAL,			"C_DecryptFinal failed"},
-{ PK11_R_NO_PRNG_SUPPORT,		"Slot does not support PRNG"},
-{ PK11_R_GETTOKENINFO,			"C_GetTokenInfo failed"},
-{ PK11_R_DERIVEKEY,			"C_DeriveKey failed"},
-{ PK11_R_GET_OPERATION_STATE,		"C_GetOperationState failed"},
-{ PK11_R_SET_OPERATION_STATE,		"C_SetOperationState failed"},
-{ PK11_R_INVALID_HANDLE,		"invalid PKCS#11 object handle"},
-{ PK11_R_KEY_OR_IV_LEN_PROBLEM,		"IV or key length incorrect"},
-{ PK11_R_INVALID_OPERATION_TYPE,	"invalid operation type"},
-{ PK11_R_ADD_NID_FAILED,		"failed to add NID" },
-{ PK11_R_ATFORK_FAILED,			"atfork failed" },
-{ PK11_R_TOKEN_LOGIN_FAILED,		"C_Login failed on token" },
-{ PK11_R_MORE_THAN_ONE_OBJECT_FOUND,	"more than one object found" },
-{ PK11_R_INVALID_PKCS11_URI,		"pkcs11 URI provided is invalid" },
-{ PK11_R_COULD_NOT_READ_PIN,		"could not read PIN from terminal" },
-{ PK11_R_PIN_NOT_READ_FROM_COMMAND,	"PIN not read from external command" },
-{ PK11_R_COULD_NOT_OPEN_COMMAND,	"could not popen dialog command" },
-{ PK11_R_PIPE_FAILED,			"pipe failed" },
-{ PK11_R_BAD_PASSPHRASE_SPEC,		"bad passphrasedialog specification" },
-{ PK11_R_TOKEN_NOT_INITIALIZED,		"token not initialized" },
-{ PK11_R_TOKEN_PIN_NOT_SET,		"token PIN required but not set" },
-{ PK11_R_TOKEN_PIN_NOT_PROVIDED,	"token PIN required but not provided" },
-{ PK11_R_MISSING_OBJECT_LABEL,		"missing mandatory 'object' keyword" },
-{ PK11_R_TOKEN_ATTRS_DO_NOT_MATCH,	"token attrs provided do not match" },
-{ PK11_R_PRIV_KEY_NOT_FOUND,		"private key not found in keystore" },
-{ PK11_R_NO_OBJECT_FOUND,		"specified object not found" },
-{ PK11_R_PIN_CACHING_POLICY_INVALID,	"PIN set but caching policy invalid" },
-{ PK11_R_SYSCONF_FAILED,		"sysconf failed" },
-{ PK11_R_MMAP_FAILED,			"mmap failed" },
-{ PK11_R_PRIV_PROC_LOCK_MEMORY_MISSING,	"PROC_LOCK_MEMORY privilege missing" },
-{ PK11_R_MLOCK_FAILED,			"mlock failed" },
-{ PK11_R_FORK_FAILED,			"fork failed" },
-{ 0,	NULL}
-};
-#endif	/* OPENSSL_NO_ERR */
-
-static int pk11_lib_error_code = 0;
-static int pk11_error_init = 1;
-
-#ifdef PK11_ENGINE_LIB_NAME
-static ERR_STRING_DATA pk11_engine_lib_name[] =
-{
-{0, PK11_ENGINE_LIB_NAME},
-{0, NULL}
-};
-#endif
-
-static void
-ERR_load_pk11_strings(void)
-	{
-	if (pk11_lib_error_code == 0)
-		pk11_lib_error_code = ERR_get_next_error_library();
-
-	if (pk11_error_init)
-		{
-		pk11_error_init = 0;
-#ifndef OPENSSL_NO_ERR
-		ERR_load_strings(pk11_lib_error_code, pk11_str_functs);
-		ERR_load_strings(pk11_lib_error_code, pk11_str_reasons);
-#endif
-
-#ifdef PK11_ENGINE_LIB_NAME
-		pk11_engine_lib_name->error =
-		    ERR_PACK(pk11_lib_error_code, 0, 0);
-		ERR_load_strings(0, pk11_engine_lib_name);
-#endif
-		}
-}
-
-static void
-ERR_unload_pk11_strings(void)
-	{
-	if (pk11_error_init == 0)
-		{
-#ifndef OPENSSL_NO_ERR
-		ERR_unload_strings(pk11_lib_error_code, pk11_str_functs);
-		ERR_unload_strings(pk11_lib_error_code, pk11_str_reasons);
-#endif
-
-#ifdef PK11_ENGINE_LIB_NAME
-		ERR_unload_strings(0, pk11_engine_lib_name);
-#endif
-
-		pk11_error_init = 1;
-		}
-}
-
-void
-ERR_pk11_error(int function, int reason, char *file, int line)
-{
-	if (pk11_lib_error_code == 0)
-		pk11_lib_error_code = ERR_get_next_error_library();
-	ERR_PUT_error(pk11_lib_error_code, function, reason, file, line);
-}
-
-void
-PK11err_add_data(int function, int reason, CK_RV rv)
-{
-	char tmp_buf[20];
-
-	PK11err(function, reason);
-	(void) snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
-	ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
-}
--- a/components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11_err.h	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,242 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- */
-
-/*
- * This product includes software developed by the OpenSSL Project for
- * use in the OpenSSL Toolkit (http://www.openssl.org/).
- *
- * This project also referenced hw_pkcs11-0.9.7b.patch written by
- * Afchine Madjlessi.
- */
-/*
- * ====================================================================
- * 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
- *    [email protected].
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * ([email protected]).  This product includes software written by Tim
- * Hudson ([email protected]).
- *
- */
-
-#ifndef	E_PK11_ERR_H
-#define	E_PK11_ERR_H
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-void ERR_pk11_error(int function, int reason, char *file, int line);
-void PK11err_add_data(int function, int reason, CK_RV rv);
-#define	PK11err(f, r)	ERR_pk11_error((f), (r), __FILE__, __LINE__)
-
-/* Error codes for the PK11 functions. */
-
-/* Function codes. */
-
-#define	PK11_F_INIT 				100
-#define	PK11_F_FINISH				101
-#define	PK11_F_DESTROY 				102
-#define	PK11_F_CTRL 				103
-#define	PK11_F_RSA_INIT 			104
-#define	PK11_F_RSA_FINISH 			105
-#define	PK11_F_GET_PUB_RSA_KEY 			106
-#define	PK11_F_GET_PRIV_RSA_KEY 		107
-#define	PK11_F_RSA_GEN_KEY 			108
-#define	PK11_F_RSA_PUB_ENC 			109
-#define	PK11_F_RSA_PRIV_ENC 			110
-#define	PK11_F_RSA_PUB_DEC 			111
-#define	PK11_F_RSA_PRIV_DEC 			112
-#define	PK11_F_RSA_SIGN 			113
-#define	PK11_F_RSA_VERIFY 			114
-#define	PK11_F_RAND_ADD 			115
-#define	PK11_F_RAND_BYTES 			116
-#define	PK11_F_GET_SESSION 			117
-#define	PK11_F_FREE_SESSION 			118
-#define	PK11_F_LOAD_PUBKEY 			119
-#define	PK11_F_LOAD_PRIVKEY 			120
-#define	PK11_F_RSA_PUB_ENC_LOW 			121
-#define	PK11_F_RSA_PRIV_ENC_LOW 		122
-#define	PK11_F_RSA_PUB_DEC_LOW 			123
-#define	PK11_F_RSA_PRIV_DEC_LOW 		124
-#define	PK11_F_DSA_SIGN				125
-#define	PK11_F_DSA_VERIFY			126
-#define	PK11_F_DSA_INIT				127
-#define	PK11_F_DSA_FINISH			128
-#define	PK11_F_GET_PUB_DSA_KEY			129
-#define	PK11_F_GET_PRIV_DSA_KEY 		130
-#define	PK11_F_DH_INIT 				131
-#define	PK11_F_DH_FINISH 			132
-#define	PK11_F_MOD_EXP_DH 			133
-#define	PK11_F_GET_DH_KEY 			134
-#define	PK11_F_FREE_ALL_SESSIONS		135
-#define	PK11_F_SETUP_SESSION			136
-#define	PK11_F_DESTROY_OBJECT			137
-#define	PK11_F_CIPHER_INIT			138
-#define	PK11_F_CIPHER_DO_CIPHER			139
-#define	PK11_F_GET_CIPHER_KEY			140
-#define	PK11_F_DIGEST_INIT			141
-#define	PK11_F_DIGEST_UPDATE			142
-#define	PK11_F_DIGEST_FINAL			143
-#define	PK11_F_CHOOSE_SLOT			144
-#define	PK11_F_CIPHER_FINAL			145
-#define	PK11_F_LIBRARY_INIT 			146
-#define	PK11_F_LOAD 				147
-#define	PK11_F_DH_GEN_KEY			148
-#define	PK11_F_DH_COMP_KEY 			149
-#define	PK11_F_DIGEST_COPY 			150
-#define	PK11_F_CIPHER_CLEANUP			151
-#define	PK11_F_ACTIVE_ADD			152
-#define	PK11_F_ACTIVE_DELETE			153
-#define	PK11_F_CHECK_HW_MECHANISMS		154
-#define	PK11_F_INIT_SYMMETRIC			155
-#define	PK11_F_ADD_AES_CTR_NIDS			156
-#define	PK11_F_INIT_ALL_LOCKS			157
-#define	PK11_F_RETURN_SESSION			158
-#define	PK11_F_GET_PIN				159
-#define	PK11_F_FIND_ONE_OBJECT 			160
-#define	PK11_F_CHECK_TOKEN_ATTRS 		161
-#define	PK11_F_CACHE_PIN			162
-#define	PK11_F_MLOCK_PIN_IN_MEMORY		163
-#define	PK11_F_TOKEN_LOGIN 			164
-#define	PK11_F_TOKEN_RELOGIN 			165
-#define	PK11_F_RUN_ASKPASS 			166
-
-/* Reason codes. */
-#define	PK11_R_ALREADY_LOADED 			100
-#define	PK11_R_DSO_FAILURE 			101
-#define	PK11_R_NOT_LOADED 			102
-#define	PK11_R_PASSED_NULL_PARAMETER 		103
-#define	PK11_R_COMMAND_NOT_IMPLEMENTED 		104
-#define	PK11_R_INITIALIZE 			105
-#define	PK11_R_FINALIZE 			106
-#define	PK11_R_GETINFO 				107
-#define	PK11_R_GETSLOTLIST 			108
-#define	PK11_R_NO_MODULUS_OR_NO_EXPONENT 	109
-#define	PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID 	110
-#define	PK11_R_GETATTRIBUTVALUE 		111
-#define	PK11_R_NO_MODULUS 			112
-#define	PK11_R_NO_EXPONENT 			113
-#define	PK11_R_FINDOBJECTSINIT 			114
-#define	PK11_R_FINDOBJECTS 			115
-#define	PK11_R_FINDOBJECTSFINAL 		116
-#define	PK11_R_CREATEOBJECT 			118
-#define	PK11_R_DESTROYOBJECT 			119
-#define	PK11_R_OPENSESSION 			120
-#define	PK11_R_CLOSESESSION 			121
-#define	PK11_R_ENCRYPTINIT 			122
-#define	PK11_R_ENCRYPT 				123
-#define	PK11_R_SIGNINIT 			124
-#define	PK11_R_SIGN 				125
-#define	PK11_R_DECRYPTINIT 			126
-#define	PK11_R_DECRYPT 				127
-#define	PK11_R_VERIFYINIT 			128
-#define	PK11_R_VERIFY 				129
-#define	PK11_R_VERIFYRECOVERINIT 		130
-#define	PK11_R_VERIFYRECOVER 			131
-#define	PK11_R_GEN_KEY 				132
-#define	PK11_R_SEEDRANDOM 			133
-#define	PK11_R_GENERATERANDOM 			134
-#define	PK11_R_INVALID_MESSAGE_LENGTH 		135
-#define	PK11_R_UNKNOWN_ALGORITHM_TYPE 		136
-#define	PK11_R_UNKNOWN_ASN1_OBJECT_ID 		137
-#define	PK11_R_UNKNOWN_PADDING_TYPE 		138
-#define	PK11_R_PADDING_CHECK_FAILED 		139
-#define	PK11_R_DIGEST_TOO_BIG 			140
-#define	PK11_R_MALLOC_FAILURE 			141
-#define	PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED 	142
-#define	PK11_R_DATA_GREATER_THAN_MOD_LEN 	143
-#define	PK11_R_DATA_TOO_LARGE_FOR_MODULUS 	144
-#define	PK11_R_MISSING_KEY_COMPONENT		145
-#define	PK11_R_INVALID_SIGNATURE_LENGTH		146
-#define	PK11_R_INVALID_DSA_SIGNATURE_R		147
-#define	PK11_R_INVALID_DSA_SIGNATURE_S		148
-#define	PK11_R_INCONSISTENT_KEY			149
-#define	PK11_R_ENCRYPTUPDATE			150
-#define	PK11_R_DECRYPTUPDATE			151
-#define	PK11_R_DIGESTINIT			152
-#define	PK11_R_DIGESTUPDATE			153
-#define	PK11_R_DIGESTFINAL			154
-#define	PK11_R_ENCRYPTFINAL			155
-#define	PK11_R_DECRYPTFINAL			156
-#define	PK11_R_NO_PRNG_SUPPORT			157
-#define	PK11_R_GETTOKENINFO			158
-#define	PK11_R_DERIVEKEY			159
-#define	PK11_R_GET_OPERATION_STATE		160
-#define	PK11_R_SET_OPERATION_STATE		161
-#define	PK11_R_INVALID_HANDLE			162
-#define	PK11_R_KEY_OR_IV_LEN_PROBLEM		163
-#define	PK11_R_INVALID_OPERATION_TYPE		164
-#define	PK11_R_ADD_NID_FAILED			165
-#define	PK11_R_ATFORK_FAILED			166
-#define	PK11_R_TOKEN_LOGIN_FAILED		167
-#define	PK11_R_MORE_THAN_ONE_OBJECT_FOUND	168
-#define	PK11_R_INVALID_PKCS11_URI		169
-#define	PK11_R_COULD_NOT_READ_PIN		170
-#define	PK11_R_COULD_NOT_OPEN_COMMAND		171
-#define	PK11_R_PIPE_FAILED			172
-#define	PK11_R_PIN_NOT_READ_FROM_COMMAND	173
-#define	PK11_R_BAD_PASSPHRASE_SPEC		174
-#define	PK11_R_TOKEN_NOT_INITIALIZED		175
-#define	PK11_R_TOKEN_PIN_NOT_SET		176
-#define	PK11_R_TOKEN_PIN_NOT_PROVIDED		177
-#define	PK11_R_MISSING_OBJECT_LABEL		178
-#define	PK11_R_TOKEN_ATTRS_DO_NOT_MATCH		179
-#define	PK11_R_PRIV_KEY_NOT_FOUND		180
-#define	PK11_R_NO_OBJECT_FOUND			181
-#define	PK11_R_PIN_CACHING_POLICY_INVALID	182
-#define	PK11_R_SYSCONF_FAILED			183
-#define	PK11_R_MMAP_FAILED			183
-#define	PK11_R_PRIV_PROC_LOCK_MEMORY_MISSING	184
-#define	PK11_R_MLOCK_FAILED			185
-#define	PK11_R_FORK_FAILED			186
-
-#ifdef	__cplusplus
-}
-#endif
-#endif /* E_PK11_ERR_H */
--- a/components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11_pub.c	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3273 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* crypto/engine/e_pk11_pub.c */
-/*
- * This product includes software developed by the OpenSSL Project for
- * use in the OpenSSL Toolkit (http://www.openssl.org/).
- *
- * This project also referenced hw_pkcs11-0.9.7b.patch written by
- * Afchine Madjlessi.
- */
-/*
- * ====================================================================
- * 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
- *    [email protected].
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * ([email protected]).  This product includes software written by Tim
- * Hudson ([email protected]).
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <strings.h>
-
-#include <openssl/e_os2.h>
-#include <openssl/crypto.h>
-#include <openssl/engine.h>
-#include <openssl/dso.h>
-#include <openssl/err.h>
-#include <openssl/bn.h>
-#include <openssl/pem.h>
-#ifndef OPENSSL_NO_RSA
-#include <openssl/rsa.h>
-#endif /* OPENSSL_NO_RSA */
-#ifndef OPENSSL_NO_DSA
-#include <openssl/dsa.h>
-#endif /* OPENSSL_NO_DSA */
-#ifndef OPENSSL_NO_DH
-#include <openssl/dh.h>
-#endif /* OPENSSL_NO_DH */
-#include <openssl/rand.h>
-#include <openssl/objects.h>
-#include <openssl/x509.h>
-#include <pthread.h>
-#include <libgen.h>
-
-#ifndef OPENSSL_NO_HW
-#ifndef OPENSSL_NO_HW_PK11
-
-#include <security/cryptoki.h>
-#include <security/pkcs11.h>
-#include "e_pk11.h"
-#include "e_pk11_uri.h"
-
-static CK_BBOOL pk11_login_done = CK_FALSE;
-extern CK_SLOT_ID pubkey_SLOTID;
-
-/*
- * During the reinitialization after a detected fork we will try to login to the
- * token using the passphrasedialog keyword that we inherit from the parent.
- */
-char *passphrasedialog;
-
-#ifndef OPENSSL_NO_RSA
-/* RSA stuff */
-static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa, int padding);
-static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa, int padding);
-static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa, int padding);
-static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa, int padding);
-static int pk11_RSA_init(RSA *rsa);
-static int pk11_RSA_finish(RSA *rsa);
-static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
-	unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
-static int pk11_RSA_verify(int dtype, const unsigned char *m,
-	unsigned int m_len, const unsigned char *sigbuf, unsigned int siglen,
-	const RSA *rsa);
-EVP_PKEY *pk11_load_privkey(ENGINE*, const char *privkey_id,
-	UI_METHOD *ui_method, void *callback_data);
-EVP_PKEY *pk11_load_pubkey(ENGINE*, const char *pubkey_id,
-	UI_METHOD *ui_method, void *callback_data);
-
-static int pk11_RSA_public_encrypt_low(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa);
-static int pk11_RSA_private_encrypt_low(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa);
-static int pk11_RSA_public_decrypt_low(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa);
-static int pk11_RSA_private_decrypt_low(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa);
-
-static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA* rsa, PK11_SESSION *sp);
-static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa, PK11_SESSION *sp);
-
-static int pk11_check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa);
-static int pk11_check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa);
-#endif
-
-/* DSA stuff */
-#ifndef OPENSSL_NO_DSA
-static int pk11_DSA_init(DSA *dsa);
-static int pk11_DSA_finish(DSA *dsa);
-static DSA_SIG *pk11_dsa_do_sign(const unsigned char *dgst, int dlen,
-	DSA *dsa);
-static int pk11_dsa_do_verify(const unsigned char *dgst, int dgst_len,
-	DSA_SIG *sig, DSA *dsa);
-
-static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa, DSA **key_ptr,
-	BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session);
-static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa, DSA **key_ptr,
-	BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session);
-
-static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa);
-static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa);
-#endif
-
-/* DH stuff */
-#ifndef OPENSSL_NO_DH
-static int pk11_DH_init(DH *dh);
-static int pk11_DH_finish(DH *dh);
-static int pk11_DH_generate_key(DH *dh);
-static int pk11_DH_compute_key(unsigned char *key,
-	const BIGNUM *pub_key, DH *dh);
-
-static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh, DH **key_ptr,
-	BIGNUM **priv_key, CK_SESSION_HANDLE session);
-
-static int check_new_dh_key(PK11_SESSION *sp, DH *dh);
-#endif
-
-static int find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
-	CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey);
-static int init_template_value(BIGNUM *bn, CK_VOID_PTR *pValue,
-	CK_ULONG *ulValueLen);
-static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn);
-
-static int pk11_pkey_meth_nids[] = {NID_dsa};
-
-/* Read mode string to be used for fopen() */
-#if SOLARIS_OPENSSL
-static char *read_mode_flags = "rF";
-#else
-static char *read_mode_flags = "r";
-#endif
-
-/*
- * Increment existing or create a new reference for an asymmetric key PKCS#11
- * object handle in the active object list. If the operation fails, unlock (if
- * locked), set error variable and jump to the specified label. We use this list
- * so that we can track how many references to the PKCS#11 objects are used from
- * all our sessions structures. If we are replacing an object reference in the
- * session structure and the ref count for the reference being replaced gets to
- * 0 we know that we can safely free the object itself via C_ObjectDestroy().
- * See also TRY_OBJ_DESTROY.
- */
-#define	KEY_HANDLE_REFHOLD(key_handle, alg_type, unlock, var, label)	\
-	{								\
-	if (pk11_active_add(key_handle, alg_type) < 0)			\
-		{							\
-		var = CK_TRUE;						\
-		if (unlock)						\
-			UNLOCK_OBJSTORE(alg_type);			\
-		goto label;						\
-		}							\
-	}
-
-/*
- * Find active list entry according to object handle and return pointer to the
- * entry otherwise return NULL.
- *
- * This function presumes it is called with lock protecting the active list
- * held.
- */
-static PK11_active *pk11_active_find(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
-	{
-	PK11_active *entry;
-
-	for (entry = active_list[type]; entry != NULL; entry = entry->next)
-		if (entry->h == h)
-			return (entry);
-
-	return (NULL);
-	}
-
-/*
- * Search for an entry in the active list using PKCS#11 object handle as a
- * search key and return refcnt of the found/created entry or -1 in case of
- * failure.
- *
- * This function presumes it is called with lock protecting the active list
- * held.
- */
-int
-pk11_active_add(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
-	{
-	PK11_active *entry = NULL;
-
-	if (h == CK_INVALID_HANDLE)
-		{
-		PK11err(PK11_F_ACTIVE_ADD, PK11_R_INVALID_HANDLE);
-		return (-1);
-		}
-
-	/* search for entry in the active list */
-	if ((entry = pk11_active_find(h, type)) != NULL)
-		entry->refcnt++;
-	else
-		{
-		/* not found, create new entry and add it to the list */
-		entry = OPENSSL_malloc(sizeof (PK11_active));
-		if (entry == NULL)
-			{
-			PK11err(PK11_F_ACTIVE_ADD, PK11_R_MALLOC_FAILURE);
-			return (-1);
-			}
-		entry->h = h;
-		entry->refcnt = 1;
-		entry->prev = NULL;
-		entry->next = NULL;
-		/* connect the newly created entry to the list */
-		if (active_list[type] == NULL)
-			active_list[type] = entry;
-		else /* make the entry first in the list */
-			{
-			entry->next = active_list[type];
-			active_list[type]->prev = entry;
-			active_list[type] = entry;
-			}
-		}
-
-	return (entry->refcnt);
-	}
-
-/*
- * Remove active list entry from the list and free it.
- *
- * This function presumes it is called with lock protecting the active list
- * held.
- */
-void
-pk11_active_remove(PK11_active *entry, PK11_OPTYPE type)
-	{
-	PK11_active *prev_entry;
-
-	/* remove the entry from the list and free it */
-	if ((prev_entry = entry->prev) != NULL)
-		{
-		prev_entry->next = entry->next;
-		if (entry->next != NULL)
-			entry->next->prev = prev_entry;
-		}
-	else
-		{
-		active_list[type] = entry->next;
-		/* we were the first but not the only one */
-		if (entry->next != NULL)
-			entry->next->prev = NULL;
-		}
-
-	/* sanitization */
-	entry->h = CK_INVALID_HANDLE;
-	entry->prev = NULL;
-	entry->next = NULL;
-	OPENSSL_free(entry);
-	}
-
-/* Free all entries from the active list. */
-void
-pk11_free_active_list(PK11_OPTYPE type)
-	{
-	PK11_active *entry;
-
-	/* only for asymmetric types since only they have C_Find* locks. */
-	switch (type)
-		{
-		case OP_RSA:
-		case OP_DSA:
-		case OP_DH:
-			break;
-		default:
-			return;
-		}
-
-	/* see find_lock array definition for more info on object locking */
-	LOCK_OBJSTORE(type);
-	while ((entry = active_list[type]) != NULL)
-		pk11_active_remove(entry, type);
-	UNLOCK_OBJSTORE(type);
-	}
-
-/*
- * Search for active list entry associated with given PKCS#11 object handle,
- * decrement its refcnt and if it drops to 0, disconnect the entry and free it.
- *
- * Return 1 if the PKCS#11 object associated with the entry has no references,
- * return 0 if there is at least one reference, -1 on error.
- *
- * This function presumes it is called with lock protecting the active list
- * held.
- */
-int
-pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
-	{
-	PK11_active *entry = NULL;
-
-	if ((entry = pk11_active_find(h, type)) == NULL)
-		{
-		PK11err(PK11_F_ACTIVE_DELETE, PK11_R_INVALID_HANDLE);
-		return (-1);
-		}
-
-	OPENSSL_assert(entry->refcnt > 0);
-	entry->refcnt--;
-	if (entry->refcnt == 0)
-		{
-		pk11_active_remove(entry, type);
-		return (1);
-		}
-
-	return (0);
-	}
-
-#ifndef OPENSSL_NO_RSA
-/* Our internal RSA_METHOD that we provide pointers to */
-static RSA_METHOD pk11_rsa =
-	{
-	"PKCS#11 RSA method",
-	pk11_RSA_public_encrypt,		/* rsa_pub_encrypt */
-	pk11_RSA_public_decrypt,		/* rsa_pub_decrypt */
-	pk11_RSA_private_encrypt,		/* rsa_priv_encrypt */
-	pk11_RSA_private_decrypt,		/* rsa_priv_decrypt */
-	NULL,					/* rsa_mod_exp */
-	NULL,					/* bn_mod_exp */
-	pk11_RSA_init,				/* init */
-	pk11_RSA_finish,			/* finish */
-	RSA_FLAG_SIGN_VER,			/* flags */
-	NULL,					/* app_data */
-	pk11_RSA_sign,				/* rsa_sign */
-	pk11_RSA_verify,			/* rsa_verify */
-	/* Internal rsa_keygen will be used if this is NULL. */
-	NULL					/* rsa_keygen */
-	};
-
-RSA_METHOD *
-PK11_RSA(void)
-	{
-	return (&pk11_rsa);
-	}
-#endif
-
-#ifndef OPENSSL_NO_DSA
-/* Our internal DSA_METHOD that we provide pointers to */
-static DSA_METHOD pk11_dsa =
-	{
-	"PKCS#11 DSA method",
-	pk11_dsa_do_sign, 	/* dsa_do_sign */
-	NULL, 			/* dsa_sign_setup */
-	pk11_dsa_do_verify, 	/* dsa_do_verify */
-	NULL,			/* dsa_mod_exp */
-	NULL, 			/* bn_mod_exp */
-	pk11_DSA_init, 		/* init */
-	pk11_DSA_finish, 	/* finish */
-	0, 			/* flags */
-	NULL 			/* app_data */
-	};
-
-DSA_METHOD *
-PK11_DSA(void)
-	{
-	return (&pk11_dsa);
-	}
-#endif
-
-#ifndef OPENSSL_NO_DH
-/*
- * PKCS #11 V2.20, section 11.2 specifies that the number of bytes needed for
- * output buffer may somewhat exceed the precise number of bytes needed, but
- * should not exceed it by a large amount. That may be caused, for example, by
- * rounding it up to multiple of X in the underlying bignum library. 8 should be
- * enough.
- */
-#define	DH_BUF_RESERVE	8
-
-/* Our internal DH_METHOD that we provide pointers to */
-static DH_METHOD pk11_dh =
-	{
-	"PKCS#11 DH method",
-	pk11_DH_generate_key,	/* generate_key */
-	pk11_DH_compute_key,	/* compute_key */
-	NULL,			/* bn_mod_exp */
-	pk11_DH_init,		/* init */
-	pk11_DH_finish,		/* finish */
-	0,			/* flags */
-	NULL,			/* app_data */
-	NULL			/* generate_params */
-	};
-
-DH_METHOD *
-PK11_DH(void)
-	{
-	return (&pk11_dh);
-	}
-#endif
-
-/* Size of an SSL signature: MD5+SHA1 */
-#define	SSL_SIG_LENGTH		36
-
-/* Lengths of DSA data and signature */
-#define	DSA_DATA_LEN		20
-#define	DSA_SIGNATURE_LEN	40
-
-#ifndef OPENSSL_NO_RSA
-/*
- * Similar to OpenSSL to take advantage of the paddings. The goal is to
- * support all paddings in this engine although PK11 library does not
- * support all the paddings used in OpenSSL.
- * The input errors should have been checked in the padding functions.
- */
-static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
-		unsigned char *to, RSA *rsa, int padding)
-	{
-	int i, num = 0, r = -1;
-	unsigned char *buf = NULL;
-
-	num = BN_num_bytes(rsa->n);
-	if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
-		{
-		PK11err(PK11_F_RSA_PUB_ENC, PK11_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:
-		PK11err(PK11_F_RSA_PUB_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
-		goto err;
-		}
-	if (i <= 0) goto err;
-
-	/* PK11 functions are called here */
-	r = pk11_RSA_public_encrypt_low(num, buf, to, rsa);
-err:
-	if (buf != NULL)
-		{
-		OPENSSL_cleanse(buf, num);
-		OPENSSL_free(buf);
-		}
-	return (r);
-	}
-
-
-/*
- * Similar to Openssl to take advantage of the paddings. The input errors
- * should be caught in the padding functions
- */
-static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa, int padding)
-	{
-	int i, num = 0, r = -1;
-	unsigned char *buf = NULL;
-
-	num = BN_num_bytes(rsa->n);
-	if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
-		{
-		PK11err(PK11_F_RSA_PRIV_ENC, PK11_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_NO_PADDING:
-		i = RSA_padding_add_none(buf, num, from, flen);
-		break;
-	case RSA_SSLV23_PADDING:
-	default:
-		PK11err(PK11_F_RSA_PRIV_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
-		goto err;
-		}
-	if (i <= 0) goto err;
-
-	/* PK11 functions are called here */
-	r = pk11_RSA_private_encrypt_low(num, buf, to, rsa);
-err:
-	if (buf != NULL)
-		{
-		OPENSSL_cleanse(buf, num);
-		OPENSSL_free(buf);
-		}
-	return (r);
-	}
-
-/* Similar to OpenSSL code. Input errors are also checked here */
-static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa, int padding)
-	{
-	BIGNUM f;
-	int j, num = 0, r = -1;
-	unsigned char *p;
-	unsigned char *buf = NULL;
-
-	BN_init(&f);
-
-	num = BN_num_bytes(rsa->n);
-
-	if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
-		{
-		PK11err(PK11_F_RSA_PRIV_DEC, PK11_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)
-		{
-		PK11err(PK11_F_RSA_PRIV_DEC,
-			PK11_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)
-		{
-		PK11err(PK11_F_RSA_PRIV_DEC,
-			PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
-		goto err;
-		}
-
-	/* PK11 functions are called here */
-	r = pk11_RSA_private_decrypt_low(flen, from, buf, rsa);
-
-	/*
-	 * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
-	 * Needs to skip these 0's paddings here.
-	 */
-	for (j = 0; j < r; j++)
-		if (buf[j] != 0)
-			break;
-
-	p = buf + j;
-	j = r - j;  /* j is only used with no-padding mode */
-
-	switch (padding)
-		{
-	case RSA_PKCS1_PADDING:
-		r = RSA_padding_check_PKCS1_type_2(to, num, p, j, num);
-		break;
-#ifndef OPENSSL_NO_SHA
-	case RSA_PKCS1_OAEP_PADDING:
-		r = RSA_padding_check_PKCS1_OAEP(to, num, p, j, num, NULL, 0);
-		break;
-#endif
-	case RSA_SSLV23_PADDING:
-		r = RSA_padding_check_SSLv23(to, num, p, j, num);
-		break;
-	case RSA_NO_PADDING:
-		r = RSA_padding_check_none(to, num, p, j, num);
-		break;
-	default:
-		PK11err(PK11_F_RSA_PRIV_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
-		goto err;
-		}
-	if (r < 0)
-		PK11err(PK11_F_RSA_PRIV_DEC, PK11_R_PADDING_CHECK_FAILED);
-
-err:
-	BN_clear_free(&f);
-	if (buf != NULL)
-		{
-		OPENSSL_cleanse(buf, num);
-		OPENSSL_free(buf);
-		}
-	return (r);
-	}
-
-/* Similar to OpenSSL code. Input errors are also checked here */
-static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
-	unsigned char *to, RSA *rsa, int padding)
-	{
-	BIGNUM f;
-	int i, num = 0, r = -1;
-	unsigned char *p;
-	unsigned char *buf = NULL;
-
-	BN_init(&f);
-	num = BN_num_bytes(rsa->n);
-	buf = (unsigned char *)OPENSSL_malloc(num);
-	if (buf == NULL)
-		{
-		PK11err(PK11_F_RSA_PUB_DEC, PK11_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)
-		{
-		PK11err(PK11_F_RSA_PUB_DEC, PK11_R_DATA_GREATER_THAN_MOD_LEN);
-		goto err;
-		}
-
-	if (BN_bin2bn(from, flen, &f) == NULL)
-		goto err;
-
-	if (BN_ucmp(&f, rsa->n) >= 0)
-		{
-		PK11err(PK11_F_RSA_PUB_DEC,
-			PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
-		goto err;
-		}
-
-	/* PK11 functions are called here */
-	r = pk11_RSA_public_decrypt_low(flen, from, buf, rsa);
-
-	/*
-	 * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
-	 * Needs to skip these 0's here
-	 */
-	for (i = 0; i < r; i++)
-		if (buf[i] != 0)
-			break;
-
-	p = buf + i;
-	i = r - i;  /* i is only used with no-padding mode */
-
-	switch (padding)
-		{
-	case RSA_PKCS1_PADDING:
-		r = RSA_padding_check_PKCS1_type_1(to, num, p, i, num);
-		break;
-	case RSA_NO_PADDING:
-		r = RSA_padding_check_none(to, num, p, i, num);
-		break;
-	default:
-		PK11err(PK11_F_RSA_PUB_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
-		goto err;
-		}
-	if (r < 0)
-		PK11err(PK11_F_RSA_PUB_DEC, PK11_R_PADDING_CHECK_FAILED);
-
-err:
-	BN_clear_free(&f);
-	if (buf != NULL)
-		{
-		OPENSSL_cleanse(buf, num);
-		OPENSSL_free(buf);
-		}
-	return (r);
-	}
-
-/*
- * This function implements RSA public encryption using C_EncryptInit and
- * C_Encrypt pk11 interfaces. Note that the CKM_RSA_X_509 is used here.
- * The calling function allocated sufficient memory in "to" to store results.
- */
-static int pk11_RSA_public_encrypt_low(int flen,
-	const unsigned char *from, unsigned char *to, RSA *rsa)
-	{
-	CK_ULONG bytes_encrypted = flen;
-	int retval = -1;
-	CK_RV rv;
-	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
-	CK_MECHANISM *p_mech = &mech_rsa;
-	CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
-	PK11_SESSION *sp;
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		return (-1);
-
-	(void) pk11_check_new_rsa_key_pub(sp, rsa);
-
-	h_pub_key = sp->opdata_rsa_pub_key;
-	if (h_pub_key == CK_INVALID_HANDLE)
-		h_pub_key = sp->opdata_rsa_pub_key =
-			pk11_get_public_rsa_key(rsa, sp);
-
-	if (h_pub_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_EncryptInit(sp->session, p_mech,
-			h_pub_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
-			    PK11_R_ENCRYPTINIT, rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-
-		rv = pFuncList->C_Encrypt(sp->session,
-			(unsigned char *)from, flen, to, &bytes_encrypted);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
-			    PK11_R_ENCRYPT, rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-		retval = bytes_encrypted;
-		}
-
-	pk11_return_session(sp, OP_RSA);
-	return (retval);
-	}
-
-
-/*
- * This function implements RSA private encryption using C_SignInit and
- * C_Sign pk11 APIs. Note that CKM_RSA_X_509 is used here.
- * The calling function allocated sufficient memory in "to" to store results.
- */
-static int pk11_RSA_private_encrypt_low(int flen,
-	const unsigned char *from, unsigned char *to, RSA *rsa)
-	{
-	CK_ULONG ul_sig_len = flen;
-	int retval = -1;
-	CK_RV rv;
-	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
-	CK_MECHANISM *p_mech = &mech_rsa;
-	CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
-	PK11_SESSION *sp;
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		return (-1);
-
-	(void) pk11_check_new_rsa_key_priv(sp, rsa);
-
-	h_priv_key = sp->opdata_rsa_priv_key;
-	if (h_priv_key == CK_INVALID_HANDLE)
-		h_priv_key = sp->opdata_rsa_priv_key =
-			pk11_get_private_rsa_key(rsa, sp);
-
-	if (h_priv_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_SignInit(sp->session, p_mech,
-			h_priv_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW,
-			    PK11_R_SIGNINIT, rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-
-		rv = pFuncList->C_Sign(sp->session,
-			(unsigned char *)from, flen, to, &ul_sig_len);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW, PK11_R_SIGN,
-			    rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-
-		retval = ul_sig_len;
-		}
-
-	pk11_return_session(sp, OP_RSA);
-	return (retval);
-	}
-
-
-/*
- * This function implements RSA private decryption using C_DecryptInit and
- * C_Decrypt pk11 APIs. Note that CKM_RSA_X_509 mechanism is used here.
- * The calling function allocated sufficient memory in "to" to store results.
- */
-static int pk11_RSA_private_decrypt_low(int flen,
-	const unsigned char *from, unsigned char *to, RSA *rsa)
-	{
-	CK_ULONG bytes_decrypted = flen;
-	int retval = -1;
-	CK_RV rv;
-	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
-	CK_MECHANISM *p_mech = &mech_rsa;
-	CK_OBJECT_HANDLE h_priv_key;
-	PK11_SESSION *sp;
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		return (-1);
-
-	(void) pk11_check_new_rsa_key_priv(sp, rsa);
-
-	h_priv_key = sp->opdata_rsa_priv_key;
-	if (h_priv_key == CK_INVALID_HANDLE)
-		h_priv_key = sp->opdata_rsa_priv_key =
-			pk11_get_private_rsa_key(rsa, sp);
-
-	if (h_priv_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_DecryptInit(sp->session, p_mech,
-			h_priv_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
-				PK11_R_DECRYPTINIT, rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-
-		rv = pFuncList->C_Decrypt(sp->session,
-			(unsigned char *)from, flen, to, &bytes_decrypted);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
-			    PK11_R_DECRYPT, rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-		retval = bytes_decrypted;
-		}
-
-	pk11_return_session(sp, OP_RSA);
-	return (retval);
-	}
-
-
-/*
- * This function implements RSA public decryption using C_VerifyRecoverInit
- * and C_VerifyRecover pk11 APIs. Note that CKM_RSA_X_509 is used here.
- * The calling function allocated sufficient memory in "to" to store results.
- */
-static int pk11_RSA_public_decrypt_low(int flen,
-	const unsigned char *from, unsigned char *to, RSA *rsa)
-	{
-	CK_ULONG bytes_decrypted = flen;
-	int retval = -1;
-	CK_RV rv;
-	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
-	CK_MECHANISM *p_mech = &mech_rsa;
-	CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
-	PK11_SESSION *sp;
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		return (-1);
-
-	(void) pk11_check_new_rsa_key_pub(sp, rsa);
-
-	h_pub_key = sp->opdata_rsa_pub_key;
-	if (h_pub_key == CK_INVALID_HANDLE)
-		h_pub_key = sp->opdata_rsa_pub_key =
-			pk11_get_public_rsa_key(rsa, sp);
-
-	if (h_pub_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_VerifyRecoverInit(sp->session,
-			p_mech, h_pub_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
-				PK11_R_VERIFYRECOVERINIT, rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-
-		rv = pFuncList->C_VerifyRecover(sp->session,
-			(unsigned char *)from, flen, to, &bytes_decrypted);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
-			    PK11_R_VERIFYRECOVER, rv);
-			pk11_return_session(sp, OP_RSA);
-			return (-1);
-			}
-		retval = bytes_decrypted;
-		}
-
-	pk11_return_session(sp, OP_RSA);
-	return (retval);
-	}
-
-static int pk11_RSA_init(RSA *rsa)
-	{
-	/*
-	 * This flag in the RSA_METHOD enables the new rsa_sign,
-	 * rsa_verify functions. See rsa.h for details.
-	 */
-	rsa->flags |= RSA_FLAG_SIGN_VER;
-
-	return (1);
-	}
-
-static int pk11_RSA_finish(RSA *rsa)
-	{
-	/*
-	 * Since we are overloading OpenSSL's native RSA_eay_finish() we need
-	 * to do the same as in the original function, i.e. to free bignum
-	 * structures.
-	 */
-	if (rsa->_method_mod_n != NULL)
-		BN_MONT_CTX_free(rsa->_method_mod_n);
-	if (rsa->_method_mod_p != NULL)
-		BN_MONT_CTX_free(rsa->_method_mod_p);
-	if (rsa->_method_mod_q != NULL)
-		BN_MONT_CTX_free(rsa->_method_mod_q);
-
-	return (1);
-	}
-
-/*
- * Standard engine interface function. Majority codes here are from
- * rsa/rsa_sign.c. We replaced the decrypt function call by C_Sign of PKCS#11.
- * See more details in rsa/rsa_sign.c
- */
-static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
-	unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
-	{
-	X509_SIG sig;
-	ASN1_TYPE parameter;
-	int i, j;
-	unsigned char *p, *s = NULL;
-	X509_ALGOR algor;
-	ASN1_OCTET_STRING digest;
-	CK_RV rv;
-	CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
-	CK_MECHANISM *p_mech = &mech_rsa;
-	CK_OBJECT_HANDLE h_priv_key;
-	PK11_SESSION *sp = NULL;
-	int ret = 0;
-	unsigned long ulsiglen;
-
-	/* Encode the digest */
-	/* Special case: SSL signature, just check the length */
-	if (type == NID_md5_sha1)
-		{
-		if (m_len != SSL_SIG_LENGTH)
-			{
-			PK11err(PK11_F_RSA_SIGN,
-				PK11_R_INVALID_MESSAGE_LENGTH);
-			goto err;
-			}
-		i = SSL_SIG_LENGTH;
-		s = (unsigned char *)m;
-		}
-	else
-		{
-		sig.algor = &algor;
-		sig.algor->algorithm = OBJ_nid2obj(type);
-		if (sig.algor->algorithm == NULL)
-			{
-			PK11err(PK11_F_RSA_SIGN,
-				PK11_R_UNKNOWN_ALGORITHM_TYPE);
-			goto err;
-			}
-		if (sig.algor->algorithm->length == 0)
-			{
-			PK11err(PK11_F_RSA_SIGN,
-				PK11_R_UNKNOWN_ASN1_OBJECT_ID);
-			goto err;
-			}
-		parameter.type = V_ASN1_NULL;
-		parameter.value.ptr = NULL;
-		sig.algor->parameter = &parameter;
-
-		sig.digest = &digest;
-		sig.digest->data = (unsigned char *)m;
-		sig.digest->length = m_len;
-
-		i = i2d_X509_SIG(&sig, NULL);
-		}
-
-	j = RSA_size(rsa);
-	if ((i - RSA_PKCS1_PADDING) > j)
-		{
-		PK11err(PK11_F_RSA_SIGN, PK11_R_DIGEST_TOO_BIG);
-		goto err;
-		}
-
-	if (type != NID_md5_sha1)
-		{
-		s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
-		if (s == NULL)
-			{
-			PK11err(PK11_F_RSA_SIGN, PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-		p = s;
-		(void) i2d_X509_SIG(&sig, &p);
-		}
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		goto err;
-
-	(void) pk11_check_new_rsa_key_priv(sp, rsa);
-
-	h_priv_key = sp->opdata_rsa_priv_key;
-	if (h_priv_key == CK_INVALID_HANDLE)
-		h_priv_key = sp->opdata_rsa_priv_key =
-			pk11_get_private_rsa_key((RSA *)rsa, sp);
-
-	if (h_priv_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGNINIT, rv);
-			goto err;
-			}
-
-		ulsiglen = j;
-		rv = pFuncList->C_Sign(sp->session, s, i, sigret,
-			(CK_ULONG_PTR) &ulsiglen);
-		*siglen = ulsiglen;
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGN, rv);
-			goto err;
-			}
-		ret = 1;
-		}
-
-err:
-	if (type != NID_md5_sha1)
-		{
-		(void) memset(s, 0, (unsigned int)(j + 1));
-		OPENSSL_free(s);
-		}
-
-	pk11_return_session(sp, OP_RSA);
-	return (ret);
-	}
-
-static int pk11_RSA_verify(int type, const unsigned char *m,
-	unsigned int m_len, const unsigned char *sigbuf, unsigned int siglen,
-	const RSA *rsa)
-	{
-	X509_SIG sig;
-	ASN1_TYPE parameter;
-	int i, j;
-	unsigned char *p, *s = NULL;
-	X509_ALGOR algor;
-	ASN1_OCTET_STRING digest;
-	CK_RV rv;
-	CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
-	CK_MECHANISM *p_mech = &mech_rsa;
-	CK_OBJECT_HANDLE h_pub_key;
-	PK11_SESSION *sp = NULL;
-	int ret = 0;
-
-	/* Encode the digest	*/
-	/* Special case: SSL signature, just check the length */
-	if (type == NID_md5_sha1)
-		{
-		if (m_len != SSL_SIG_LENGTH)
-			{
-			PK11err(PK11_F_RSA_VERIFY,
-				PK11_R_INVALID_MESSAGE_LENGTH);
-			goto err;
-			}
-		i = SSL_SIG_LENGTH;
-		s = (unsigned char *)m;
-		}
-	else
-		{
-		sig.algor = &algor;
-		sig.algor->algorithm = OBJ_nid2obj(type);
-		if (sig.algor->algorithm == NULL)
-			{
-			PK11err(PK11_F_RSA_VERIFY,
-				PK11_R_UNKNOWN_ALGORITHM_TYPE);
-			goto err;
-			}
-		if (sig.algor->algorithm->length == 0)
-			{
-			PK11err(PK11_F_RSA_VERIFY,
-				PK11_R_UNKNOWN_ASN1_OBJECT_ID);
-			goto err;
-			}
-		parameter.type = V_ASN1_NULL;
-		parameter.value.ptr = NULL;
-		sig.algor->parameter = &parameter;
-		sig.digest = &digest;
-		sig.digest->data = (unsigned char *)m;
-		sig.digest->length = m_len;
-		i = i2d_X509_SIG(&sig, NULL);
-		}
-
-	j = RSA_size(rsa);
-	if ((i - RSA_PKCS1_PADDING) > j)
-		{
-		PK11err(PK11_F_RSA_VERIFY, PK11_R_DIGEST_TOO_BIG);
-		goto err;
-		}
-
-	if (type != NID_md5_sha1)
-		{
-		s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
-		if (s == NULL)
-			{
-			PK11err(PK11_F_RSA_VERIFY, PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-		p = s;
-		(void) i2d_X509_SIG(&sig, &p);
-		}
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		goto err;
-
-	(void) pk11_check_new_rsa_key_pub(sp, rsa);
-
-	h_pub_key = sp->opdata_rsa_pub_key;
-	if (h_pub_key == CK_INVALID_HANDLE)
-		h_pub_key = sp->opdata_rsa_pub_key =
-			pk11_get_public_rsa_key((RSA *)rsa, sp);
-
-	if (h_pub_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_VerifyInit(sp->session, p_mech,
-			h_pub_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFYINIT,
-			    rv);
-			goto err;
-			}
-		rv = pFuncList->C_Verify(sp->session, s, i,
-			(CK_BYTE_PTR)sigbuf, (CK_ULONG)siglen);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFY, rv);
-			goto err;
-			}
-		ret = 1;
-		}
-
-err:
-	if (type != NID_md5_sha1)
-		{
-		(void) memset(s, 0, (unsigned int)siglen);
-		OPENSSL_free(s);
-		}
-
-	pk11_return_session(sp, OP_RSA);
-	return (ret);
-	}
-
-#define	MAXATTR	1024
-/*
- * Load RSA private key from a file or get its PKCS#11 handle if stored in the
- * PKCS#11 token.
- */
-/* ARGSUSED */
-EVP_PKEY *pk11_load_privkey(ENGINE* e, const char *privkey_id,
-	UI_METHOD *ui_method, void *callback_data)
-	{
-	EVP_PKEY *pkey = NULL;
-	FILE *privkey;
-	CK_OBJECT_HANDLE  h_priv_key = CK_INVALID_HANDLE;
-	RSA *rsa = NULL;
-	PK11_SESSION *sp;
-	/* Anything else below is needed for the key by reference extension. */
-	const char *file;
-	int ret;
-	pkcs11_uri uri_struct;
-	CK_RV rv;
-	CK_BBOOL is_token = CK_TRUE;
-	CK_BBOOL rollback = CK_FALSE;
-	CK_BYTE attr_data[8][MAXATTR];
-	CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
-	CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;	/* key in keystore */
-
-	/* We look for private keys only. */
-	CK_ATTRIBUTE search_templ[] =
-		{
-		{CKA_TOKEN, &is_token, sizeof (is_token)},
-		{CKA_CLASS, &key_class, sizeof (key_class)},
-		{CKA_LABEL, NULL, 0}
-		};
-
-	/*
-	 * These public attributes are needed to initialize the OpenSSL RSA
-	 * structure with something we can use to look up the key. Note that we
-	 * never ask for private components.
-	 */
-	CK_ATTRIBUTE get_templ[] =
-		{
-		{CKA_MODULUS, (void *)attr_data[0], MAXATTR},		/* n */
-		{CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},	/* e */
-		};
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		return (NULL);
-
-	/*
-	 * The next function will decide whether we are going to access keys in
-	 * the token or read them from plain files. It all depends on what is in
-	 * the 'privkey_id' parameter.
-	 */
-	ret = pk11_process_pkcs11_uri(privkey_id, &uri_struct, &file);
-
-	if (ret == 0)
-		goto err;
-
-	/* We will try to access a key from a PKCS#11 token. */
-	if (ret == 1)
-		{
-		if (pk11_check_token_attrs(&uri_struct) == 0)
-			goto err;
-
-		search_templ[2].pValue = uri_struct.object;
-		search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
-
-		if (pk11_token_login(sp->session, &pk11_login_done,
-		    &uri_struct, CK_TRUE) == 0)
-			goto err;
-
-		/*
-		 * Now let's try to find the key in the token. It is a failure
-		 * if we can't find it.
-		 */
-		if (find_one_object(OP_RSA, sp->session, search_templ, 3,
-		    &ks_key) == 0)
-			goto err;
-
-		/*
-		 * Free the structure now. Note that we use uri_struct's field
-		 * directly in the template so we cannot free it until the find
-		 * is done.
-		 */
-		pk11_free_pkcs11_uri(&uri_struct, 0);
-
-		/*
-		 * We might have a cache hit which we could confirm according to
-		 * the 'n'/'e' params, RSA public pointer as NULL, and non-NULL
-		 * RSA private pointer. However, it is easier just to recreate
-		 * everything. We expect the keys to be loaded once and used
-		 * many times. We do not check the return value because even in
-		 * case of failure the sp structure will have both key pointer
-		 * and object handle cleaned and pk11_destroy_object() reports
-		 * the failure to the OpenSSL error message buffer.
-		 */
-		(void) pk11_destroy_rsa_object_priv(sp, CK_TRUE);
-
-		sp->opdata_rsa_priv_key = ks_key;
-		/* This object shall not be deleted on a cache miss. */
-		sp->persistent = CK_TRUE;
-
-		if ((rsa = sp->opdata_rsa_priv = RSA_new_method(e)) == NULL)
-			goto err;
-
-		if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
-		    get_templ, 2)) != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_LOAD_PRIVKEY,
-			    PK11_R_GETATTRIBUTVALUE, rv);
-			goto err;
-			}
-
-		/*
-		 * Cache the RSA private structure pointer. We do not use it now
-		 * for key-by-ref keys but let's do it for consistency reasons.
-		 */
-		sp->opdata_rsa_priv = rsa;
-
-		/*
-		 * We do not use pk11_get_private_rsa_key() here so we must take
-		 * care of handle management ourselves.
-		 */
-		KEY_HANDLE_REFHOLD(ks_key, OP_RSA, CK_FALSE, rollback, err);
-
-		/*
-		 * Those are the sensitive components we do not want to export
-		 * from the token at all: rsa->(d|p|q|dmp1|dmq1|iqmp).
-		 */
-		attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
-		attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
-		/*
-		 * Must have 'n'/'e' components in the session structure as
-		 * well. They serve as a public look-up key for the private key
-		 * in the keystore.
-		 */
-		attr_to_BN(&get_templ[0], attr_data[0], &sp->opdata_rsa_n_num);
-		attr_to_BN(&get_templ[1], attr_data[1], &sp->opdata_rsa_e_num);
-
-		if ((pkey = EVP_PKEY_new()) == NULL)
-			goto err;
-
-		if (EVP_PKEY_set1_RSA(pkey, rsa) == 0)
-			goto err;
-		}
-	else
-		if ((privkey = fopen(file, read_mode_flags)) != NULL)
-			{
-			pkey = PEM_read_PrivateKey(privkey, NULL, NULL, NULL);
-			(void) fclose(privkey);
-			if (pkey != NULL)
-				{
-				rsa = EVP_PKEY_get1_RSA(pkey);
-				if (rsa != NULL)
-					{
-					(void) pk11_check_new_rsa_key_priv(sp,
-					    rsa);
-
-					h_priv_key = sp->opdata_rsa_priv_key =
-					    pk11_get_private_rsa_key(rsa, sp);
-					if (h_priv_key == CK_INVALID_HANDLE)
-						goto err;
-					}
-				else
-					goto err;
-				}
-			}
-
-	pk11_return_session(sp, OP_RSA);
-	return (pkey);
-err:
-	if (rsa != NULL)
-		RSA_free(rsa);
-	if (pkey != NULL)
-		{
-		EVP_PKEY_free(pkey);
-		pkey = NULL;
-		}
-	return (pkey);
-	}
-
-/* Load RSA public key from a file or load it from the PKCS#11 token. */
-/* ARGSUSED */
-EVP_PKEY *pk11_load_pubkey(ENGINE* e, const char *pubkey_id,
-	UI_METHOD *ui_method, void *callback_data)
-	{
-	EVP_PKEY *pkey = NULL;
-	FILE *pubkey;
-	CK_OBJECT_HANDLE  h_pub_key = CK_INVALID_HANDLE;
-	RSA *rsa = NULL;
-	PK11_SESSION *sp;
-	/* everything else below needed for key by reference extension */
-	int ret;
-	const char *file;
-	pkcs11_uri uri_struct;
-	CK_RV rv;
-	CK_BBOOL is_token = CK_TRUE;
-	CK_BYTE attr_data[2][MAXATTR];
-	CK_OBJECT_CLASS key_class = CKO_PUBLIC_KEY;
-	CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;	/* key in keystore */
-
-	CK_ATTRIBUTE search_templ[] =
-		{
-		{CKA_TOKEN, &is_token, sizeof (is_token)},
-		{CKA_CLASS, &key_class, sizeof (key_class)},
-		{CKA_LABEL, NULL, 0}
-		};
-
-	/*
-	 * These public attributes are needed to initialize OpenSSL RSA
-	 * structure with something we can use to look up the key.
-	 */
-	CK_ATTRIBUTE get_templ[] =
-		{
-		{CKA_MODULUS, (void *)attr_data[0], MAXATTR},		/* n */
-		{CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},	/* e */
-		};
-
-	if ((sp = pk11_get_session(OP_RSA)) == NULL)
-		return (NULL);
-
-	ret = pk11_process_pkcs11_uri(pubkey_id, &uri_struct, &file);
-
-	if (ret == 0)
-		goto err;
-
-	if (ret == 1)
-		{
-		if (pk11_check_token_attrs(&uri_struct) == 0)
-			goto err;
-
-		search_templ[2].pValue = uri_struct.object;
-		search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
-
-		if (pk11_token_login(sp->session, &pk11_login_done,
-		    &uri_struct, CK_FALSE) == 0)
-			goto err;
-
-		if (find_one_object(OP_RSA, sp->session, search_templ, 3,
-		    &ks_key) == 0)
-			{
-			goto err;
-			}
-
-		/*
-		 * Free the structure now. Note that we use uri_struct's field
-		 * directly in the template so we can't free until find is done.
-		 */
-		pk11_free_pkcs11_uri(&uri_struct, 0);
-		/*
-		 * We load a new public key so we will create a new RSA
-		 * structure. No cache hit is possible.
-		 */
-		(void) pk11_destroy_rsa_object_pub(sp, CK_TRUE);
-		sp->opdata_rsa_pub_key = ks_key;
-
-		if ((rsa = sp->opdata_rsa_pub = RSA_new_method(e)) == NULL)
-			goto err;
-
-		if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
-		    get_templ, 2)) != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_LOAD_PUBKEY,
-			    PK11_R_GETATTRIBUTVALUE, rv);
-			goto err;
-			}
-
-		/*
-		 * Cache the RSA public structure pointer.
-		 */
-		sp->opdata_rsa_pub = rsa;
-
-		/*
-		 * These are the sensitive components we do not want to export
-		 * from the token at all: rsa->(d|p|q|dmp1|dmq1|iqmp).
-		 */
-		attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
-		attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
-
-		if ((pkey = EVP_PKEY_new()) == NULL)
-			goto err;
-
-		if (EVP_PKEY_set1_RSA(pkey, rsa) == 0)
-			goto err;
-
-		/*
-		 * Create a session object from it so that when calling
-		 * pk11_get_public_rsa_key() the next time, we can find it. The
-		 * reason why we do that is that we cannot tell from the RSA
-		 * structure (OpenSSL RSA structure does not have any room for
-		 * additional data used by the engine, for example) if it bears
-		 * a public key stored in the keystore or not so it's better if
-		 * we always have a session key. Note that this is different
-		 * from what we do for the private keystore objects but in that
-		 * case, we can tell from the RSA structure that the keystore
-		 * object is in play - the 'd' component is NULL in that case.
-		 */
-		h_pub_key = sp->opdata_rsa_pub_key =
-		    pk11_get_public_rsa_key(rsa, sp);
-		if (h_pub_key == CK_INVALID_HANDLE)
-			goto err;
-		}
-	else
-		if ((pubkey = fopen(file, read_mode_flags)) != NULL)
-			{
-			pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL);
-			(void) fclose(pubkey);
-			if (pkey != NULL)
-				{
-				rsa = EVP_PKEY_get1_RSA(pkey);
-				if (rsa != NULL)
-					{
-					/*
-					 * This will always destroy the RSA
-					 * object since we have a new RSA
-					 * structure here.
-					 */
-					(void) pk11_check_new_rsa_key_pub(sp,
-					    rsa);
-
-					h_pub_key = sp->opdata_rsa_pub_key =
-					    pk11_get_public_rsa_key(rsa, sp);
-					if (h_pub_key == CK_INVALID_HANDLE)
-						{
-						EVP_PKEY_free(pkey);
-						pkey = NULL;
-						}
-					}
-				else
-					{
-					EVP_PKEY_free(pkey);
-					pkey = NULL;
-					}
-				}
-			}
-
-	pk11_return_session(sp, OP_RSA);
-	return (pkey);
-err:
-	if (rsa != NULL)
-		RSA_free(rsa);
-	if (pkey != NULL)
-		{
-		EVP_PKEY_free(pkey);
-		pkey = NULL;
-		}
-	return (pkey);
-	}
-
-/*
- * Get a public key object in a session from a given rsa structure. If the
- * PKCS#11 session object already exists it is found, reused, and
- * the counter in the active object list incremented. If not found, a new
- * session object is created and put also onto the active object list.
- *
- * We use the session field from sp, and we cache rsa->(n|e) in
- * opdata_rsa_(n|e|d)_num, respectively.
- */
-static CK_OBJECT_HANDLE
-pk11_get_public_rsa_key(RSA* rsa, PK11_SESSION *sp)
-	{
-	CK_RV rv;
-	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-	CK_ULONG found;
-	CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
-	CK_KEY_TYPE k_type = CKK_RSA;
-	CK_ULONG ul_key_attr_count = 7;
-	CK_BBOOL rollback = CK_FALSE;
-
-	CK_ATTRIBUTE  a_key_template[] =
-		{
-		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
-		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
-		{CKA_TOKEN, &pk11_false, sizeof (pk11_false)},
-		{CKA_ENCRYPT, &pk11_true, sizeof (pk11_true)},
-		{CKA_VERIFY_RECOVER, &pk11_true, sizeof (pk11_true)},
-		{CKA_MODULUS, (void *)NULL, 0},
-		{CKA_PUBLIC_EXPONENT, (void *)NULL, 0}
-		};
-
-	int i;
-
-	a_key_template[0].pValue = &o_key;
-	a_key_template[1].pValue = &k_type;
-
-	a_key_template[5].ulValueLen = BN_num_bytes(rsa->n);
-	a_key_template[5].pValue = (CK_VOID_PTR)OPENSSL_malloc(
-		(size_t)a_key_template[5].ulValueLen);
-	if (a_key_template[5].pValue == NULL)
-		{
-		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	BN_bn2bin(rsa->n, a_key_template[5].pValue);
-
-	a_key_template[6].ulValueLen = BN_num_bytes(rsa->e);
-	a_key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
-		(size_t)a_key_template[6].ulValueLen);
-	if (a_key_template[6].pValue == NULL)
-		{
-		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	BN_bn2bin(rsa->e, a_key_template[6].pValue);
-
-	/* see find_lock array definition for more info on object locking */
-	LOCK_OBJSTORE(OP_RSA);
-
-	rv = pFuncList->C_FindObjectsInit(sp->session, a_key_template,
-		ul_key_attr_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
-		    PK11_R_FINDOBJECTSINIT, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjects(sp->session, &h_key, 1, &found);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
-		    PK11_R_FINDOBJECTS, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjectsFinal(sp->session);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
-		    PK11_R_FINDOBJECTSFINAL, rv);
-		goto err;
-		}
-
-	if (found == 0)
-		{
-		rv = pFuncList->C_CreateObject(sp->session,
-			a_key_template, ul_key_attr_count, &h_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
-			    PK11_R_CREATEOBJECT, rv);
-			goto err;
-			}
-		}
-
-	if ((sp->opdata_rsa_n_num = BN_dup(rsa->n)) == NULL)
-		{
-		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
-		rollback = CK_TRUE;
-		goto err;
-		}
-
-	if ((sp->opdata_rsa_e_num = BN_dup(rsa->e)) == NULL)
-		{
-		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
-		BN_free(sp->opdata_rsa_n_num);
-		sp->opdata_rsa_n_num = NULL;
-		rollback = CK_TRUE;
-		goto err;
-		}
-
-	/* LINTED: E_CONSTANT_CONDITION */
-	KEY_HANDLE_REFHOLD(h_key, OP_RSA, CK_FALSE, rollback, err);
-	sp->opdata_rsa_pub = rsa;
-
-err:
-	if (rollback)
-		{
-		/*
-		 * We do not care about the return value from C_DestroyObject()
-		 * since we are doing rollback.
-		 */
-		if (found == 0)
-			(void) pFuncList->C_DestroyObject(sp->session, h_key);
-		h_key = CK_INVALID_HANDLE;
-		}
-
-	UNLOCK_OBJSTORE(OP_RSA);
-
-malloc_err:
-	for (i = 5; i <= 6; i++)
-		{
-		if (a_key_template[i].pValue != NULL)
-			{
-			OPENSSL_free(a_key_template[i].pValue);
-			a_key_template[i].pValue = NULL;
-			}
-		}
-
-	return (h_key);
-	}
-
-/*
- * Function similar to pk11_get_public_rsa_key(). In addition to 'n' and 'e'
- * components, it also caches 'd' if present. Note that if RSA keys by reference
- * are used, 'd' is never extracted from the token in which case it would be
- * NULL here.
- */
-static CK_OBJECT_HANDLE
-pk11_get_private_rsa_key(RSA* rsa, PK11_SESSION *sp)
-	{
-	CK_RV rv;
-	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-	int i;
-	CK_ULONG found;
-	CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
-	CK_KEY_TYPE k_type = CKK_RSA;
-	CK_ULONG ul_key_attr_count = 14;
-	CK_BBOOL rollback = CK_FALSE;
-
-	/*
-	 * Both CKA_TOKEN and CKA_SENSITIVE have to be CK_FALSE for session keys
-	 */
-	CK_ATTRIBUTE  a_key_template[] =
-		{
-		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
-		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
-		{CKA_TOKEN, &pk11_false, sizeof (pk11_false)},
-		{CKA_SENSITIVE, &pk11_false, sizeof (pk11_false)},
-		{CKA_DECRYPT, &pk11_true, sizeof (pk11_true)},
-		{CKA_SIGN, &pk11_true, sizeof (pk11_true)},
-		{CKA_MODULUS, (void *)NULL, 0},
-		{CKA_PUBLIC_EXPONENT, (void *)NULL, 0},
-		{CKA_PRIVATE_EXPONENT, (void *)NULL, 0},
-		{CKA_PRIME_1, (void *)NULL, 0},
-		{CKA_PRIME_2, (void *)NULL, 0},
-		{CKA_EXPONENT_1, (void *)NULL, 0},
-		{CKA_EXPONENT_2, (void *)NULL, 0},
-		{CKA_COEFFICIENT, (void *)NULL, 0},
-		};
-
-	a_key_template[0].pValue = &o_key;
-	a_key_template[1].pValue = &k_type;
-
-	/* Put the private key components into the template */
-	if (init_template_value(rsa->n, &a_key_template[6].pValue,
-		&a_key_template[6].ulValueLen) == 0 ||
-	    init_template_value(rsa->e, &a_key_template[7].pValue,
-		&a_key_template[7].ulValueLen) == 0 ||
-	    init_template_value(rsa->d, &a_key_template[8].pValue,
-		&a_key_template[8].ulValueLen) == 0 ||
-	    init_template_value(rsa->p, &a_key_template[9].pValue,
-		&a_key_template[9].ulValueLen) == 0 ||
-	    init_template_value(rsa->q, &a_key_template[10].pValue,
-		&a_key_template[10].ulValueLen) == 0 ||
-	    init_template_value(rsa->dmp1, &a_key_template[11].pValue,
-		&a_key_template[11].ulValueLen) == 0 ||
-	    init_template_value(rsa->dmq1, &a_key_template[12].pValue,
-		&a_key_template[12].ulValueLen) == 0 ||
-	    init_template_value(rsa->iqmp, &a_key_template[13].pValue,
-		&a_key_template[13].ulValueLen) == 0)
-		{
-		PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	/* see find_lock array definition for more info on object locking */
-	LOCK_OBJSTORE(OP_RSA);
-
-	/*
-	 * We are getting the private key but the private 'd' component is NULL.
-	 * That means this is key by reference RSA key. In that case, we can
-	 * use only public components for searching for the private key handle.
-	 */
-	if (rsa->d == NULL)
-		{
-		ul_key_attr_count = 8;
-		/*
-		 * We will perform the search in the token, not in the existing
-		 * session keys.
-		 */
-		a_key_template[2].pValue = &pk11_true;
-		}
-
-	rv = pFuncList->C_FindObjectsInit(sp->session, a_key_template,
-		ul_key_attr_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
-		    PK11_R_FINDOBJECTSINIT, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjects(sp->session, &h_key, 1, &found);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
-		    PK11_R_FINDOBJECTS, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjectsFinal(sp->session);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
-		    PK11_R_FINDOBJECTSFINAL, rv);
-		goto err;
-		}
-
-	if (found == 0)
-		{
-		/*
-		 * We have an RSA structure with 'n'/'e' components only so we
-		 * tried to find the private key in the keystore. If it was
-		 * really a token key we have a problem. Note that for other key
-		 * types we just create a new session key using the private
-		 * components from the RSA structure.
-		 */
-		if (rsa->d == NULL)
-			{
-			PK11err(PK11_F_GET_PRIV_RSA_KEY,
-			    PK11_R_PRIV_KEY_NOT_FOUND);
-			goto err;
-			}
-
-		rv = pFuncList->C_CreateObject(sp->session,
-			a_key_template, ul_key_attr_count, &h_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
-				PK11_R_CREATEOBJECT, rv);
-			goto err;
-			}
-		}
-
-	/*
-	 * When RSA keys by reference code is used, we never extract private
-	 * components from the keystore. In that case 'd' was set to NULL and we
-	 * expect the application to properly cope with that. It is documented
-	 * in openssl(5). In general, if keys by reference are used we expect it
-	 * to be used exclusively using the high level API and then there is no
-	 * problem. If the application expects the private components to be read
-	 * from the keystore then that is not a supported way of usage.
-	 */
-	if (rsa->d != NULL)
-		{
-		if ((sp->opdata_rsa_d_num = BN_dup(rsa->d)) == NULL)
-			{
-			PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
-			rollback = CK_TRUE;
-			goto err;
-			}
-		}
-	else
-		sp->opdata_rsa_d_num = NULL;
-
-	/*
-	 * For the key by reference code, we need public components as well
-	 * since 'd' component is always NULL. For that reason, we always cache
-	 * 'n'/'e' components as well.
-	 */
-	if ((sp->opdata_rsa_n_num = BN_dup(rsa->n)) == NULL)
-		{
-		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
-		sp->opdata_rsa_n_num = NULL;
-		rollback = CK_TRUE;
-		goto err;
-		}
-	if ((sp->opdata_rsa_e_num = BN_dup(rsa->e)) == NULL)
-		{
-		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
-		BN_free(sp->opdata_rsa_n_num);
-		sp->opdata_rsa_n_num = NULL;
-		rollback = CK_TRUE;
-		goto err;
-		}
-
-	/* LINTED: E_CONSTANT_CONDITION */
-	KEY_HANDLE_REFHOLD(h_key, OP_RSA, CK_FALSE, rollback, err);
-	sp->opdata_rsa_priv = rsa;
-
-err:
-	if (rollback)
-		{
-		/*
-		 * We do not care about the return value from C_DestroyObject()
-		 * since we are doing rollback.
-		 */
-		if (found == 0)
-			(void) pFuncList->C_DestroyObject(sp->session, h_key);
-		h_key = CK_INVALID_HANDLE;
-		}
-
-	UNLOCK_OBJSTORE(OP_RSA);
-
-malloc_err:
-	/*
-	 * 6 to 13 entries in the key template are key components.
-	 * They need to be freed upon exit or error.
-	 */
-	for (i = 6; i <= 13; i++)
-		{
-		if (a_key_template[i].pValue != NULL)
-			{
-			(void) memset(a_key_template[i].pValue, 0,
-				a_key_template[i].ulValueLen);
-			OPENSSL_free(a_key_template[i].pValue);
-			a_key_template[i].pValue = NULL;
-			}
-		}
-
-	return (h_key);
-	}
-
-/*
- * Check for cache miss. Objects are cleaned only if we have a full cache miss,
- * meaning that it's a different RSA key pair. Return 1 for cache hit, 0 for
- * cache miss.
- */
-static int
-pk11_check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa)
-	{
-	/*
-	 * Provide protection against RSA structure reuse by making the
-	 * check for cache hit stronger. Only public components of RSA
-	 * key matter here so it is sufficient to compare them with values
-	 * cached in PK11_SESSION structure.
-	 *
-	 * We must check the handle as well since with key by reference, public
-	 * components 'n'/'e' are cached in private keys as well. That means we
-	 * could have a cache hit in a private key when looking for a public
-	 * key. That would not work, you cannot have one PKCS#11 object for
-	 * both data signing and verifying.
-	 */
-	if (sp->opdata_rsa_pub == rsa &&
-	    BN_cmp(sp->opdata_rsa_n_num, rsa->n) == 0 &&
-	    BN_cmp(sp->opdata_rsa_e_num, rsa->e) == 0)
-		{
-		if (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE)
-			return (1);
-		else
-			/*
-			 * No public key object yet but we have the right RSA
-			 * structure with potentially existing private key
-			 * object. We can just create a public object and move
-			 * on with this session structure.
-			 */
-			return (0);
-		}
-
-	/*
-	 * A different RSA key pair was using this session structure previously
-	 * or it's an empty structure. Destroy what we can.
-	 */
-	(void) pk11_destroy_rsa_object_pub(sp, CK_TRUE);
-	(void) pk11_destroy_rsa_object_priv(sp, CK_TRUE);
-	return (0);
-	}
-
-/*
- * Check for cache miss. Objects are cleaned only if we have a full cache miss,
- * meaning that it's a different RSA key pair. Return 1 for cache hit, 0 for
- * cache miss.
- */
-static int
-pk11_check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa)
-	{
-	/*
-	 * Provide protection against RSA structure reuse by making the
-	 * check for cache hit stronger. Comparing public exponent of RSA
-	 * key with value cached in PK11_SESSION structure should
-	 * be sufficient. Note that we want to compare the public component
-	 * since with the keys by reference mechanism, private components are
-	 * not in the RSA structure. Also, see pk11_check_new_rsa_key_pub()
-	 * about why we compare the handle as well.
-	 */
-	if (sp->opdata_rsa_priv == rsa &&
-	    BN_cmp(sp->opdata_rsa_n_num, rsa->n) == 0 &&
-	    BN_cmp(sp->opdata_rsa_e_num, rsa->e) == 0)
-		{
-		if (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE)
-			return (1);
-		else
-			/*
-			 * No private key object yet but we have the right RSA
-			 * structure with potentially existing public key
-			 * object. We can just create a private object and move
-			 * on with this session structure.
-			 */
-			return (0);
-		}
-
-	/*
-	 * A different RSA key pair was using this session structure previously
-	 * or it's an empty structure. Destroy what we can.
-	 */
-	(void) pk11_destroy_rsa_object_priv(sp, CK_TRUE);
-	(void) pk11_destroy_rsa_object_pub(sp, CK_TRUE);
-	return (0);
-	}
-#endif
-
-#ifndef OPENSSL_NO_DSA
-/* The DSA function implementation */
-/* ARGSUSED */
-static int pk11_DSA_init(DSA *dsa)
-	{
-	return (1);
-	}
-
-/* ARGSUSED */
-static int pk11_DSA_finish(DSA *dsa)
-	{
-	return (1);
-	}
-
-
-static DSA_SIG *
-pk11_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
-	{
-	BIGNUM *r = NULL, *s = NULL;
-	int i;
-	DSA_SIG *dsa_sig = NULL;
-
-	CK_RV rv;
-	CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
-	CK_MECHANISM *p_mech = &Mechanism_dsa;
-	CK_OBJECT_HANDLE h_priv_key;
-
-	/*
-	 * The signature is the concatenation of r and s,
-	 * each is 20 bytes long
-	 */
-	unsigned char sigret[DSA_SIGNATURE_LEN];
-	unsigned long siglen = DSA_SIGNATURE_LEN;
-	unsigned int siglen2 = DSA_SIGNATURE_LEN / 2;
-
-	PK11_SESSION *sp = NULL;
-
-	if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
-		{
-		PK11err(PK11_F_DSA_SIGN, PK11_R_MISSING_KEY_COMPONENT);
-		goto ret;
-		}
-
-	i = BN_num_bytes(dsa->q); /* should be 20 */
-	if (dlen > i)
-		{
-		PK11err(PK11_F_DSA_SIGN, PK11_R_INVALID_SIGNATURE_LENGTH);
-		goto ret;
-		}
-
-	if ((sp = pk11_get_session(OP_DSA)) == NULL)
-		goto ret;
-
-	(void) check_new_dsa_key_priv(sp, dsa);
-
-	h_priv_key = sp->opdata_dsa_priv_key;
-	if (h_priv_key == CK_INVALID_HANDLE)
-		h_priv_key = sp->opdata_dsa_priv_key =
-			pk11_get_private_dsa_key((DSA *)dsa,
-			    &sp->opdata_dsa_priv,
-			    &sp->opdata_dsa_priv_num, sp->session);
-
-	if (h_priv_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGNINIT, rv);
-			goto ret;
-			}
-
-			(void) memset(sigret, 0, siglen);
-			rv = pFuncList->C_Sign(sp->session,
-			    (unsigned char *) dgst, dlen, sigret,
-			    (CK_ULONG_PTR) &siglen);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGN, rv);
-			goto ret;
-			}
-		}
-
-
-	if ((s = BN_new()) == NULL)
-		{
-		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
-		goto ret;
-		}
-
-	if ((r = BN_new()) == NULL)
-		{
-		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
-		goto ret;
-		}
-
-	if ((dsa_sig = DSA_SIG_new()) == NULL)
-		{
-		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
-		goto ret;
-		}
-
-	if (BN_bin2bn(sigret, siglen2, r) == NULL ||
-	    BN_bin2bn(&sigret[siglen2], siglen2, s) == NULL)
-		{
-		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
-		goto ret;
-		}
-
-	dsa_sig->r = r;
-	dsa_sig->s = s;
-
-ret:
-	if (dsa_sig == NULL)
-		{
-		if (r != NULL)
-			BN_free(r);
-		if (s != NULL)
-			BN_free(s);
-		}
-
-	pk11_return_session(sp, OP_DSA);
-	return (dsa_sig);
-	}
-
-static int
-pk11_dsa_do_verify(const unsigned char *dgst, int dlen, DSA_SIG *sig,
-	DSA *dsa)
-	{
-	int i;
-	CK_RV rv;
-	int retval = 0;
-	CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
-	CK_MECHANISM *p_mech = &Mechanism_dsa;
-	CK_OBJECT_HANDLE h_pub_key;
-
-	unsigned char sigbuf[DSA_SIGNATURE_LEN];
-	unsigned long siglen = DSA_SIGNATURE_LEN;
-	unsigned long siglen2 = DSA_SIGNATURE_LEN/2;
-
-	PK11_SESSION *sp = NULL;
-
-	if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0)
-		{
-		PK11err(PK11_F_DSA_VERIFY,
-			PK11_R_INVALID_DSA_SIGNATURE_R);
-		goto ret;
-		}
-
-	if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0)
-		{
-		PK11err(PK11_F_DSA_VERIFY,
-			PK11_R_INVALID_DSA_SIGNATURE_S);
-		goto ret;
-		}
-
-	i = BN_num_bytes(dsa->q); /* should be 20 */
-
-	if (dlen > i)
-		{
-		PK11err(PK11_F_DSA_VERIFY,
-			PK11_R_INVALID_SIGNATURE_LENGTH);
-		goto ret;
-		}
-
-	if ((sp = pk11_get_session(OP_DSA)) == NULL)
-		goto ret;
-
-	(void) check_new_dsa_key_pub(sp, dsa);
-
-	h_pub_key = sp->opdata_dsa_pub_key;
-	if (h_pub_key == CK_INVALID_HANDLE)
-		h_pub_key = sp->opdata_dsa_pub_key =
-			pk11_get_public_dsa_key((DSA *)dsa, &sp->opdata_dsa_pub,
-			    &sp->opdata_dsa_pub_num, sp->session);
-
-	if (h_pub_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_VerifyInit(sp->session, p_mech,
-			h_pub_key);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFYINIT,
-			    rv);
-			goto ret;
-			}
-
-		/*
-		 * The representation of each of the two big numbers could
-		 * be shorter than DSA_SIGNATURE_LEN/2 bytes so we need
-		 * to act accordingly and shift if necessary.
-		 */
-		(void) memset(sigbuf, 0, siglen);
-		BN_bn2bin(sig->r, sigbuf + siglen2 - BN_num_bytes(sig->r));
-		BN_bn2bin(sig->s, &sigbuf[siglen2] + siglen2 -
-		    BN_num_bytes(sig->s));
-
-		rv = pFuncList->C_Verify(sp->session,
-			(unsigned char *) dgst, dlen, sigbuf, (CK_ULONG)siglen);
-
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFY, rv);
-			goto ret;
-			}
-		}
-
-	retval = 1;
-ret:
-
-	pk11_return_session(sp, OP_DSA);
-	return (retval);
-	}
-
-
-/*
- * Create a public key object in a session from a given dsa structure.
- * The *dsa_pub_num pointer is non-NULL for DSA public keys.
- */
-static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa,
-    DSA **key_ptr, BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session)
-	{
-	CK_RV rv;
-	CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
-	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-	CK_ULONG found;
-	CK_KEY_TYPE k_type = CKK_DSA;
-	CK_ULONG ul_key_attr_count = 8;
-	CK_BBOOL rollback = CK_FALSE;
-	int i;
-
-	CK_ATTRIBUTE  a_key_template[] =
-		{
-		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
-		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
-		{CKA_TOKEN, &pk11_false, sizeof (pk11_false)},
-		{CKA_VERIFY, &pk11_true, sizeof (pk11_true)},
-		{CKA_PRIME, (void *)NULL, 0},		/* p */
-		{CKA_SUBPRIME, (void *)NULL, 0},	/* q */
-		{CKA_BASE, (void *)NULL, 0},		/* g */
-		{CKA_VALUE, (void *)NULL, 0}		/* pub_key - y */
-		};
-
-	a_key_template[0].pValue = &o_key;
-	a_key_template[1].pValue = &k_type;
-
-	if (init_template_value(dsa->p, &a_key_template[4].pValue,
-		&a_key_template[4].ulValueLen) == 0 ||
-	    init_template_value(dsa->q, &a_key_template[5].pValue,
-		&a_key_template[5].ulValueLen) == 0 ||
-	    init_template_value(dsa->g, &a_key_template[6].pValue,
-		&a_key_template[6].ulValueLen) == 0 ||
-	    init_template_value(dsa->pub_key, &a_key_template[7].pValue,
-		&a_key_template[7].ulValueLen) == 0)
-		{
-		PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	/* see find_lock array definition for more info on object locking */
-	LOCK_OBJSTORE(OP_DSA);
-	rv = pFuncList->C_FindObjectsInit(session, a_key_template,
-		ul_key_attr_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
-		    PK11_R_FINDOBJECTSINIT, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
-		    PK11_R_FINDOBJECTS, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjectsFinal(session);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
-		    PK11_R_FINDOBJECTSFINAL, rv);
-		goto err;
-		}
-
-	if (found == 0)
-		{
-		rv = pFuncList->C_CreateObject(session,
-			a_key_template, ul_key_attr_count, &h_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
-			    PK11_R_CREATEOBJECT, rv);
-			goto err;
-			}
-		}
-
-	if (dsa_pub_num != NULL)
-		if ((*dsa_pub_num = BN_dup(dsa->pub_key)) == NULL)
-			{
-			PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
-			rollback = CK_TRUE;
-			goto err;
-			}
-
-	/* LINTED: E_CONSTANT_CONDITION */
-	KEY_HANDLE_REFHOLD(h_key, OP_DSA, CK_FALSE, rollback, err);
-	if (key_ptr != NULL)
-		*key_ptr = dsa;
-
-err:
-	if (rollback)
-		{
-		/*
-		 * We do not care about the return value from C_DestroyObject()
-		 * since we are doing rollback.
-		 */
-		if (found == 0)
-			(void) pFuncList->C_DestroyObject(session, h_key);
-		h_key = CK_INVALID_HANDLE;
-		}
-
-	UNLOCK_OBJSTORE(OP_DSA);
-
-malloc_err:
-	for (i = 4; i <= 7; i++)
-		{
-		if (a_key_template[i].pValue != NULL)
-			{
-			OPENSSL_free(a_key_template[i].pValue);
-			a_key_template[i].pValue = NULL;
-			}
-		}
-
-	return (h_key);
-	}
-
-/*
- * Create a private key object in the session from a given dsa structure
- * The *dsa_priv_num pointer is non-NULL for DSA private keys.
- */
-static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa,
-    DSA **key_ptr, BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session)
-	{
-	CK_RV rv;
-	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-	CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
-	int i;
-	CK_ULONG found;
-	CK_KEY_TYPE k_type = CKK_DSA;
-	CK_ULONG ul_key_attr_count = 9;
-	CK_BBOOL rollback = CK_FALSE;
-
-	/*
-	 * Both CKA_TOKEN and CKA_SENSITIVE have to be CK_FALSE for session keys
-	 */
-	CK_ATTRIBUTE  a_key_template[] =
-		{
-		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
-		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
-		{CKA_TOKEN, &pk11_false, sizeof (pk11_false)},
-		{CKA_SENSITIVE, &pk11_false, sizeof (pk11_false)},
-		{CKA_SIGN, &pk11_true, sizeof (pk11_true)},
-		{CKA_PRIME, (void *)NULL, 0},		/* p */
-		{CKA_SUBPRIME, (void *)NULL, 0},	/* q */
-		{CKA_BASE, (void *)NULL, 0},		/* g */
-		{CKA_VALUE, (void *)NULL, 0}		/* priv_key - x */
-		};
-
-	a_key_template[0].pValue = &o_key;
-	a_key_template[1].pValue = &k_type;
-
-	/* Put the private key components into the template */
-	if (init_template_value(dsa->p, &a_key_template[5].pValue,
-		&a_key_template[5].ulValueLen) == 0 ||
-	    init_template_value(dsa->q, &a_key_template[6].pValue,
-		&a_key_template[6].ulValueLen) == 0 ||
-	    init_template_value(dsa->g, &a_key_template[7].pValue,
-		&a_key_template[7].ulValueLen) == 0 ||
-	    init_template_value(dsa->priv_key, &a_key_template[8].pValue,
-		&a_key_template[8].ulValueLen) == 0)
-		{
-		PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	/* see find_lock array definition for more info on object locking */
-	LOCK_OBJSTORE(OP_DSA);
-	rv = pFuncList->C_FindObjectsInit(session, a_key_template,
-		ul_key_attr_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
-		    PK11_R_FINDOBJECTSINIT, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
-		    PK11_R_FINDOBJECTS, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjectsFinal(session);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
-		    PK11_R_FINDOBJECTSFINAL, rv);
-		goto err;
-		}
-
-	if (found == 0)
-		{
-		rv = pFuncList->C_CreateObject(session,
-			a_key_template, ul_key_attr_count, &h_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
-			    PK11_R_CREATEOBJECT, rv);
-			goto err;
-			}
-		}
-
-	if (dsa_priv_num != NULL)
-		if ((*dsa_priv_num = BN_dup(dsa->priv_key)) == NULL)
-			{
-			PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
-			rollback = CK_TRUE;
-			goto err;
-			}
-
-	/* LINTED: E_CONSTANT_CONDITION */
-	KEY_HANDLE_REFHOLD(h_key, OP_DSA, CK_FALSE, rollback, err);
-	if (key_ptr != NULL)
-		*key_ptr = dsa;
-
-err:
-	if (rollback)
-		{
-		/*
-		 * We do not care about the return value from C_DestroyObject()
-		 * since we are doing rollback.
-		 */
-		if (found == 0)
-			(void) pFuncList->C_DestroyObject(session, h_key);
-		h_key = CK_INVALID_HANDLE;
-		}
-
-	UNLOCK_OBJSTORE(OP_DSA);
-
-malloc_err:
-	/*
-	 * 5 to 8 entries in the key template are key components.
-	 * They need to be freed apon exit or error.
-	 */
-	for (i = 5; i <= 8; i++)
-		{
-		if (a_key_template[i].pValue != NULL)
-			{
-			(void) memset(a_key_template[i].pValue, 0,
-				a_key_template[i].ulValueLen);
-			OPENSSL_free(a_key_template[i].pValue);
-			a_key_template[i].pValue = NULL;
-			}
-		}
-
-	return (h_key);
-	}
-
-/*
- * Check for cache miss and clean the object pointer and handle
- * in such case. Return 1 for cache hit, 0 for cache miss.
- */
-static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa)
-	{
-	/*
-	 * Provide protection against DSA structure reuse by making the
-	 * check for cache hit stronger. Only public key component of DSA
-	 * key matters here so it is sufficient to compare it with value
-	 * cached in PK11_SESSION structure.
-	 */
-	if ((sp->opdata_dsa_pub != dsa) ||
-	    (BN_cmp(sp->opdata_dsa_pub_num, dsa->pub_key) != 0))
-		{
-		/*
-		 * We do not check the return value because even in case of
-		 * failure the sp structure will have both key pointer
-		 * and object handle cleaned and pk11_destroy_object()
-		 * reports the failure to the OpenSSL error message buffer.
-		 */
-		(void) pk11_destroy_dsa_object_pub(sp, CK_TRUE);
-		return (0);
-		}
-	return (1);
-	}
-
-/*
- * Check for cache miss and clean the object pointer and handle
- * in such case. Return 1 for cache hit, 0 for cache miss.
- */
-static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa)
-	{
-	/*
-	 * Provide protection against DSA structure reuse by making the
-	 * check for cache hit stronger. Only private key component of DSA
-	 * key matters here so it is sufficient to compare it with value
-	 * cached in PK11_SESSION structure.
-	 */
-	if ((sp->opdata_dsa_priv != dsa) ||
-	    (BN_cmp(sp->opdata_dsa_priv_num, dsa->priv_key) != 0))
-		{
-		/*
-		 * We do not check the return value because even in case of
-		 * failure the sp structure will have both key pointer
-		 * and object handle cleaned and pk11_destroy_object()
-		 * reports the failure to the OpenSSL error message buffer.
-		 */
-		(void) pk11_destroy_dsa_object_priv(sp, CK_TRUE);
-		return (0);
-		}
-	return (1);
-	}
-#endif
-
-
-#ifndef OPENSSL_NO_DH
-/* The DH function implementation */
-/* ARGSUSED */
-static int pk11_DH_init(DH *dh)
-	{
-	return (1);
-	}
-
-/* ARGSUSED */
-static int pk11_DH_finish(DH *dh)
-	{
-	return (1);
-	}
-
-/*
- * Generate DH key-pair.
- *
- * Warning: Unlike OpenSSL's DH_generate_key(3) we ignore dh->priv_key
- * and override it even if it is set. OpenSSL does not touch dh->priv_key
- * if set and just computes dh->pub_key. It looks like PKCS#11 standard
- * is not capable of providing this functionality. This could be a problem
- * for applications relying on OpenSSL's semantics.
- */
-static int pk11_DH_generate_key(DH *dh)
-	{
-	CK_ULONG i;
-	CK_RV rv, rv1;
-	int reuse_mem_len = 0, ret = 0;
-	PK11_SESSION *sp = NULL;
-	CK_BYTE_PTR reuse_mem;
-
-	CK_MECHANISM mechanism = {CKM_DH_PKCS_KEY_PAIR_GEN, NULL_PTR, 0};
-	CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
-	CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
-
-	CK_ULONG ul_pub_key_attr_count = 3;
-	CK_ATTRIBUTE pub_key_template[] =
-		{
-		{CKA_PRIVATE, &pk11_false, sizeof (pk11_false)},
-		{CKA_PRIME, (void *)NULL, 0},
-		{CKA_BASE, (void *)NULL, 0}
-		};
-
-	CK_ULONG ul_priv_key_attr_count = 3;
-	CK_ATTRIBUTE priv_key_template[] =
-		{
-		{CKA_PRIVATE, &pk11_false, sizeof (pk11_false)},
-		{CKA_SENSITIVE, &pk11_false, sizeof (pk11_false)},
-		{CKA_DERIVE, &pk11_true, sizeof (pk11_true)}
-		};
-
-	CK_ULONG pub_key_attr_result_count = 1;
-	CK_ATTRIBUTE pub_key_result[] =
-		{
-		{CKA_VALUE, (void *)NULL, 0}
-		};
-
-	CK_ULONG priv_key_attr_result_count = 1;
-	CK_ATTRIBUTE priv_key_result[] =
-		{
-		{CKA_VALUE, (void *)NULL, 0}
-		};
-
-	pub_key_template[1].ulValueLen = BN_num_bytes(dh->p);
-	if (pub_key_template[1].ulValueLen > 0)
-		{
-		/*
-		 * We must not increase ulValueLen by DH_BUF_RESERVE since that
-		 * could cause the same rounding problem. See definition of
-		 * DH_BUF_RESERVE above.
-		 */
-		pub_key_template[1].pValue =
-			OPENSSL_malloc(pub_key_template[1].ulValueLen +
-			DH_BUF_RESERVE);
-		if (pub_key_template[1].pValue == NULL)
-			{
-			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-
-		i = BN_bn2bin(dh->p, pub_key_template[1].pValue);
-		}
-	else
-		goto err;
-
-	pub_key_template[2].ulValueLen = BN_num_bytes(dh->g);
-	if (pub_key_template[2].ulValueLen > 0)
-		{
-		pub_key_template[2].pValue =
-			OPENSSL_malloc(pub_key_template[2].ulValueLen +
-			DH_BUF_RESERVE);
-		if (pub_key_template[2].pValue == NULL)
-			{
-			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-
-		i = BN_bn2bin(dh->g, pub_key_template[2].pValue);
-		}
-	else
-		goto err;
-
-	/*
-	 * Note: we are only using PK11_SESSION structure for getting
-	 *	 a session handle. The objects created in this function are
-	 *	 destroyed before return and thus not cached.
-	 */
-	if ((sp = pk11_get_session(OP_DH)) == NULL)
-		goto err;
-
-	rv = pFuncList->C_GenerateKeyPair(sp->session,
-	    &mechanism,
-	    pub_key_template,
-	    ul_pub_key_attr_count,
-	    priv_key_template,
-	    ul_priv_key_attr_count,
-	    &h_pub_key,
-	    &h_priv_key);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DH_GEN_KEY, PK11_R_GEN_KEY, rv);
-		goto err;
-		}
-
-	/*
-	 * Reuse the larger memory allocated. We know the larger memory
-	 * should be sufficient for reuse.
-	 */
-	if (pub_key_template[1].ulValueLen > pub_key_template[2].ulValueLen)
-		{
-		reuse_mem = pub_key_template[1].pValue;
-		reuse_mem_len = pub_key_template[1].ulValueLen + DH_BUF_RESERVE;
-		}
-	else
-		{
-		reuse_mem = pub_key_template[2].pValue;
-		reuse_mem_len = pub_key_template[2].ulValueLen + DH_BUF_RESERVE;
-		}
-
-	rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
-		pub_key_result, pub_key_attr_result_count);
-	rv1 = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
-		priv_key_result, priv_key_attr_result_count);
-
-	if (rv != CKR_OK || rv1 != CKR_OK)
-		{
-		rv = (rv != CKR_OK) ? rv : rv1;
-		PK11err_add_data(PK11_F_DH_GEN_KEY,
-		    PK11_R_GETATTRIBUTVALUE, rv);
-		goto err;
-		}
-
-	if (((CK_LONG) pub_key_result[0].ulValueLen) <= 0 ||
-		((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
-		{
-		PK11err(PK11_F_DH_GEN_KEY, PK11_R_GETATTRIBUTVALUE);
-		goto err;
-		}
-
-	/* Reuse the memory allocated */
-	pub_key_result[0].pValue = reuse_mem;
-	pub_key_result[0].ulValueLen = reuse_mem_len;
-
-	rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
-		pub_key_result, pub_key_attr_result_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DH_GEN_KEY,
-		    PK11_R_GETATTRIBUTVALUE, rv);
-		goto err;
-		}
-
-	if (pub_key_result[0].type == CKA_VALUE)
-		{
-		if (dh->pub_key == NULL)
-			if ((dh->pub_key = BN_new()) == NULL)
-				{
-				PK11err(PK11_F_DH_GEN_KEY,
-					PK11_R_MALLOC_FAILURE);
-				goto err;
-				}
-		dh->pub_key = BN_bin2bn(pub_key_result[0].pValue,
-			pub_key_result[0].ulValueLen, dh->pub_key);
-		if (dh->pub_key == NULL)
-			{
-			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-		}
-
-	/* Reuse the memory allocated */
-	priv_key_result[0].pValue = reuse_mem;
-	priv_key_result[0].ulValueLen = reuse_mem_len;
-
-	rv = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
-		priv_key_result, priv_key_attr_result_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DH_GEN_KEY,
-		    PK11_R_GETATTRIBUTVALUE, rv);
-		goto err;
-		}
-
-	if (priv_key_result[0].type == CKA_VALUE)
-		{
-		if (dh->priv_key == NULL)
-			if ((dh->priv_key = BN_new()) == NULL)
-				{
-				PK11err(PK11_F_DH_GEN_KEY,
-					PK11_R_MALLOC_FAILURE);
-				goto err;
-				}
-		dh->priv_key = BN_bin2bn(priv_key_result[0].pValue,
-			priv_key_result[0].ulValueLen, dh->priv_key);
-		if (dh->priv_key == NULL)
-			{
-			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-		}
-
-	ret = 1;
-
-err:
-
-	if (h_pub_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_DestroyObject(sp->session, h_pub_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_DH_GEN_KEY,
-			    PK11_R_DESTROYOBJECT, rv);
-			}
-		}
-
-	if (h_priv_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_DestroyObject(sp->session, h_priv_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_DH_GEN_KEY,
-			    PK11_R_DESTROYOBJECT, rv);
-			}
-		}
-
-	for (i = 1; i <= 2; i++)
-		{
-		if (pub_key_template[i].pValue != NULL)
-			{
-			OPENSSL_free(pub_key_template[i].pValue);
-			pub_key_template[i].pValue = NULL;
-			}
-		}
-
-	pk11_return_session(sp, OP_DH);
-	return (ret);
-	}
-
-static int pk11_DH_compute_key(unsigned char *key, const BIGNUM *pub_key,
-	DH *dh)
-	{
-	int i;
-	CK_MECHANISM mechanism = {CKM_DH_PKCS_DERIVE, NULL_PTR, 0};
-	CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
-	CK_KEY_TYPE key_type = CKK_GENERIC_SECRET;
-	CK_OBJECT_HANDLE h_derived_key = CK_INVALID_HANDLE;
-	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-
-	CK_ULONG ul_priv_key_attr_count = 2;
-	CK_ATTRIBUTE priv_key_template[] =
-		{
-		{CKA_CLASS, (void*) NULL, sizeof (key_class)},
-		{CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
-		};
-
-	CK_ULONG priv_key_attr_result_count = 1;
-	CK_ATTRIBUTE priv_key_result[] =
-		{
-		{CKA_VALUE, (void *)NULL, 0}
-		};
-
-	CK_RV rv;
-	int ret = -1;
-	PK11_SESSION *sp = NULL;
-
-	if (dh->priv_key == NULL)
-		goto err;
-
-	priv_key_template[0].pValue = &key_class;
-	priv_key_template[1].pValue = &key_type;
-
-	if ((sp = pk11_get_session(OP_DH)) == NULL)
-		goto err;
-
-	mechanism.ulParameterLen = BN_num_bytes(pub_key);
-	mechanism.pParameter = OPENSSL_malloc(mechanism.ulParameterLen);
-	if (mechanism.pParameter == NULL)
-		{
-		PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
-		goto err;
-		}
-	BN_bn2bin(pub_key, mechanism.pParameter);
-
-	(void) check_new_dh_key(sp, dh);
-
-	h_key = sp->opdata_dh_key;
-	if (h_key == CK_INVALID_HANDLE)
-		h_key = sp->opdata_dh_key =
-			pk11_get_dh_key((DH*) dh, &sp->opdata_dh,
-			    &sp->opdata_dh_priv_num, sp->session);
-
-	if (h_key == CK_INVALID_HANDLE)
-		{
-		PK11err(PK11_F_DH_COMP_KEY, PK11_R_CREATEOBJECT);
-		goto err;
-		}
-
-	rv = pFuncList->C_DeriveKey(sp->session,
-	    &mechanism,
-	    h_key,
-	    priv_key_template,
-	    ul_priv_key_attr_count,
-	    &h_derived_key);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_DERIVEKEY, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
-	    priv_key_result, priv_key_attr_result_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
-		    rv);
-		goto err;
-		}
-
-	if (((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
-		{
-		PK11err(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE);
-		goto err;
-		}
-	priv_key_result[0].pValue =
-		OPENSSL_malloc(priv_key_result[0].ulValueLen);
-	if (!priv_key_result[0].pValue)
-		{
-		PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
-		goto err;
-		}
-
-	rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
-		priv_key_result, priv_key_attr_result_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
-		    rv);
-		goto err;
-		}
-
-	/*
-	 * OpenSSL allocates the output buffer 'key' which is the same
-	 * length of the public key. It is long enough for the derived key
-	 */
-	if (priv_key_result[0].type == CKA_VALUE)
-		{
-		/*
-		 * CKM_DH_PKCS_DERIVE mechanism is not supposed to strip
-		 * leading zeros from a computed shared secret. However,
-		 * OpenSSL always did it so we must do the same here. The
-		 * vagueness of the spec regarding leading zero bytes was
-		 * finally cleared with TLS 1.1 (RFC 4346) saying that leading
-		 * zeros are stripped before the computed data is used as the
-		 * pre-master secret.
-		 */
-		for (i = 0; i < priv_key_result[0].ulValueLen; ++i)
-			{
-			if (((char *)priv_key_result[0].pValue)[i] != 0)
-				break;
-			}
-
-		(void) memcpy(key, ((char *)priv_key_result[0].pValue) + i,
-			priv_key_result[0].ulValueLen - i);
-		ret = priv_key_result[0].ulValueLen - i;
-		}
-
-err:
-
-	if (h_derived_key != CK_INVALID_HANDLE)
-		{
-		rv = pFuncList->C_DestroyObject(sp->session, h_derived_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_DH_COMP_KEY,
-			    PK11_R_DESTROYOBJECT, rv);
-			}
-		}
-	if (priv_key_result[0].pValue)
-		{
-		OPENSSL_free(priv_key_result[0].pValue);
-		priv_key_result[0].pValue = NULL;
-		}
-
-	if (mechanism.pParameter)
-		{
-		OPENSSL_free(mechanism.pParameter);
-		mechanism.pParameter = NULL;
-		}
-
-	pk11_return_session(sp, OP_DH);
-	return (ret);
-	}
-
-
-static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh,
-	DH **key_ptr, BIGNUM **dh_priv_num, CK_SESSION_HANDLE session)
-	{
-	CK_RV rv;
-	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-	CK_OBJECT_CLASS class = CKO_PRIVATE_KEY;
-	CK_KEY_TYPE key_type = CKK_DH;
-	CK_ULONG found;
-	CK_BBOOL rollback = CK_FALSE;
-	int i;
-
-	CK_ULONG ul_key_attr_count = 7;
-	CK_ATTRIBUTE key_template[] =
-		{
-		{CKA_CLASS, (void*) NULL, sizeof (class)},
-		{CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
-		{CKA_DERIVE, &pk11_true, sizeof (pk11_true)},
-		{CKA_PRIVATE, &pk11_false, sizeof (pk11_false)},
-		{CKA_PRIME, (void *) NULL, 0},
-		{CKA_BASE, (void *) NULL, 0},
-		{CKA_VALUE, (void *) NULL, 0},
-		};
-
-	key_template[0].pValue = &class;
-	key_template[1].pValue = &key_type;
-
-	key_template[4].ulValueLen = BN_num_bytes(dh->p);
-	key_template[4].pValue = (CK_VOID_PTR)OPENSSL_malloc(
-		(size_t)key_template[4].ulValueLen);
-	if (key_template[4].pValue == NULL)
-		{
-		PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	BN_bn2bin(dh->p, key_template[4].pValue);
-
-	key_template[5].ulValueLen = BN_num_bytes(dh->g);
-	key_template[5].pValue = (CK_VOID_PTR)OPENSSL_malloc(
-		(size_t)key_template[5].ulValueLen);
-	if (key_template[5].pValue == NULL)
-		{
-		PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	BN_bn2bin(dh->g, key_template[5].pValue);
-
-	key_template[6].ulValueLen = BN_num_bytes(dh->priv_key);
-	key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
-		(size_t)key_template[6].ulValueLen);
-	if (key_template[6].pValue == NULL)
-		{
-		PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
-		goto malloc_err;
-		}
-
-	BN_bn2bin(dh->priv_key, key_template[6].pValue);
-
-	/* see find_lock array definition for more info on object locking */
-	LOCK_OBJSTORE(OP_DH);
-	rv = pFuncList->C_FindObjectsInit(session, key_template,
-		ul_key_attr_count);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSINIT, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTS, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjectsFinal(session);
-
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSFINAL,
-		    rv);
-		goto err;
-		}
-
-	if (found == 0)
-		{
-		rv = pFuncList->C_CreateObject(session,
-			key_template, ul_key_attr_count, &h_key);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_CREATEOBJECT,
-			    rv);
-			goto err;
-			}
-		}
-
-	if (dh_priv_num != NULL)
-		if ((*dh_priv_num = BN_dup(dh->priv_key)) == NULL)
-			{
-			PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
-			rollback = CK_TRUE;
-			goto err;
-			}
-
-	/* LINTED: E_CONSTANT_CONDITION */
-	KEY_HANDLE_REFHOLD(h_key, OP_DH, CK_FALSE, rollback, err);
-	if (key_ptr != NULL)
-		*key_ptr = dh;
-
-err:
-	if (rollback)
-		{
-		/*
-		 * We do not care about the return value from C_DestroyObject()
-		 * since we are doing rollback.
-		 */
-		if (found == 0)
-			(void) pFuncList->C_DestroyObject(session, h_key);
-		h_key = CK_INVALID_HANDLE;
-		}
-
-	UNLOCK_OBJSTORE(OP_DH);
-
-malloc_err:
-	for (i = 4; i <= 6; i++)
-		{
-		if (key_template[i].pValue != NULL)
-			{
-			OPENSSL_free(key_template[i].pValue);
-			key_template[i].pValue = NULL;
-			}
-		}
-
-	return (h_key);
-	}
-
-/*
- * Check for cache miss and clean the object pointer and handle
- * in such case. Return 1 for cache hit, 0 for cache miss.
- *
- * Note: we rely on pk11_destroy_dh_key_objects() to set sp->opdata_dh
- *       to CK_INVALID_HANDLE even when it fails to destroy the object.
- */
-static int check_new_dh_key(PK11_SESSION *sp, DH *dh)
-	{
-	/*
-	 * Provide protection against DH structure reuse by making the
-	 * check for cache hit stronger. Private key component of DH key
-	 * is unique so it is sufficient to compare it with value cached
-	 * in PK11_SESSION structure.
-	 */
-	if ((sp->opdata_dh != dh) ||
-	    (BN_cmp(sp->opdata_dh_priv_num, dh->priv_key) != 0))
-		{
-		/*
-		 * We do not check the return value because even in case of
-		 * failure the sp structure will have both key pointer
-		 * and object handle cleaned and pk11_destroy_object()
-		 * reports the failure to the OpenSSL error message buffer.
-		 */
-		(void) pk11_destroy_dh_object(sp, CK_TRUE);
-		return (0);
-		}
-	return (1);
-	}
-#endif
-
-/*
- * Local function to simplify key template population
- * Return 0 -- error, 1 -- no error
- */
-static int
-init_template_value(BIGNUM *bn, CK_VOID_PTR *p_value,
-	CK_ULONG *ul_value_len)
-	{
-	CK_ULONG len;
-
-	/*
-	 * This function can be used on non-initialized BIGNUMs. It is easier to
-	 * check that here than individually in the callers.
-	 */
-	if (bn != NULL)
-		len = BN_num_bytes(bn);
-
-	if (bn == NULL || len == 0)
-		return (1);
-
-	*ul_value_len = len;
-	*p_value = (CK_VOID_PTR)OPENSSL_malloc((size_t)*ul_value_len);
-	if (*p_value == NULL)
-		return (0);
-
-	BN_bn2bin(bn, *p_value);
-
-	return (1);
-	}
-
-static void
-attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn)
-	{
-		if (attr->ulValueLen > 0)
-			*bn = BN_bin2bn(attr_data, attr->ulValueLen, NULL);
-	}
-
-/*
- * Find one object in the token. It is an error if we can not find the object or
- * if we find more objects based on the template we got.
- *
- * Returns:
- *	1 OK
- *	0 no object or more than 1 object found
- */
-static int
-find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
-    CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey)
-	{
-	CK_RV rv;
-	CK_ULONG objcnt;
-
-	LOCK_OBJSTORE(op);
-	if ((rv = pFuncList->C_FindObjectsInit(s, ptempl, nattr)) != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_FIND_ONE_OBJECT,
-		    PK11_R_FINDOBJECTSINIT, rv);
-		goto err;
-		}
-
-	rv = pFuncList->C_FindObjects(s, pkey, 1, &objcnt);
-	if (rv != CKR_OK)
-		{
-		PK11err_add_data(PK11_F_FIND_ONE_OBJECT, PK11_R_FINDOBJECTS,
-		    rv);
-		goto err;
-		}
-
-	if (objcnt > 1)
-		{
-		PK11err(PK11_F_FIND_ONE_OBJECT,
-		    PK11_R_MORE_THAN_ONE_OBJECT_FOUND);
-		goto err;
-		}
-	else
-		if (objcnt == 0)
-			{
-			PK11err(PK11_F_FIND_ONE_OBJECT, PK11_R_NO_OBJECT_FOUND);
-			goto err;
-			}
-
-	(void) pFuncList->C_FindObjectsFinal(s);
-	UNLOCK_OBJSTORE(op);
-	return (1);
-err:
-	UNLOCK_OBJSTORE(op);
-	return (0);
-	}
-
-/*
- * OpenSSL 1.0.0 introduced ENGINE API for the PKEY EVP functions. Sadly,
- * "openssl dgst -dss1 ..." now uses a new function EVP_DigestSignInit() which
- * internally needs a PKEY method for DSA even when in the engine. So, to avoid
- * a regression when moving from 0.9.8 to 1.0.0, we use an internal OpenSSL
- * structure for the DSA PKEY methods to make it work. It is a future project to
- * make it work with HW acceleration.
- *
- * Note that at the time of 1.0.0d release there is no documentation as to how
- * the PKEY EVP functions are to be implemented in an engine. There is only one
- * engine shipped with 1.0.0d that uses the PKEY EVP methods, the GOST engine.
- * It was used as an example when fixing the above mentioned regression problem.
- */
-int
-pk11_engine_pkey_methods(ENGINE *e, EVP_PKEY_METHOD **pmeth, const int **nids,
-    int nid)
-	{
-	if (pmeth == NULL)
-		{
-		*nids = pk11_pkey_meth_nids;
-		return (1);
-		}
-
-	switch (nid)
-		{
-		case NID_dsa:
-			*pmeth = (EVP_PKEY_METHOD *)EVP_PKEY_meth_find(nid);
-			return (1);
-		}
-
-	/* Error branch. */
-	*pmeth = NULL;
-	return (0);
-	}
-
-#endif	/* OPENSSL_NO_HW_PK11 */
-#endif	/* OPENSSL_NO_HW */
--- a/components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11_uri.c	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,887 +0,0 @@
-/*
- * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
- */
-
-/*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    [email protected].
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <strings.h>
-#include <libgen.h>
-#include <pthread.h>
-#include <assert.h>
-#include <errno.h>
-
-#include <openssl/crypto.h>
-
-#ifndef OPENSSL_NO_HW
-#ifndef OPENSSL_NO_HW_PK11
-
-#include <security/cryptoki.h>
-#include <security/pkcs11.h>
-#include "e_pk11.h"
-#include "e_pk11_uri.h"
-
-/*
- * The keystore used is always from the pubkey slot so we need to know which one
- * was selected so that we can get the information needed for the URI
- * processing.
- */
-extern CK_SLOT_ID pubkey_SLOTID;
-extern CK_FUNCTION_LIST_PTR pFuncList;
-
-/*
- * Cached PIN so that child can use it during the re-login. Note that we do not
- * cache the PIN by default.
- */
-static char *token_pin;
-
-static int mlock_pin_in_memory(char *pin);
-static char *run_askpass(char *dialog);
-
-/*
- * Get the PIN. Either run the command and use its standard output as a PIN to
- * fill in the PKCS11 URI structure, or read the PIN from the terminal. Using
- * the external command is of higher precedence. The memory for PIN is allocated
- * in this function and the PIN is always NULL terminated. The caller must take
- * care of freeing the memory used for the PIN. The maximum PIN length accepted
- * is PK11_MAX_PIN_LEN.
- *
- * The function is used also during the re-initialization of the engine after
- * the fork.
- *
- * The function must not be called under the protection of the mutex "uri_lock"
- * because the lock is acquired in the prefork function.
- *
- * Returns:
- *	0 in case of troubles (and sets "*pin" to NULL)
- *	1 if we got the PIN
- */
-#define	EXEC_SPEC	"exec:"
-#define	BUILTIN_SPEC	"builtin"
-int
-pk11_get_pin(char *dialog, char **pin)
-	{
-	/* Initialize as an error. */
-	*pin = NULL;
-
-	if (strcmp(dialog, BUILTIN_SPEC) == 0)
-		{
-		/* The getpassphrase() function is not MT safe. */
-		(void) pthread_mutex_lock(uri_lock);
-		/* Note that OpenSSL is not localized at all. */
-		*pin = getpassphrase("Enter token PIN: ");
-		if (*pin == NULL)
-			{
-			PK11err(PK11_F_GET_PIN, PK11_R_COULD_NOT_READ_PIN);
-			(void) pthread_mutex_unlock(uri_lock);
-			goto err;
-			}
-		else
-			{
-			char *pw;
-
-			/*
-			 * getpassphrase() uses an internal  buffer to hold the
-			 * entered password. Note that it terminates the buffer
-			 * with '\0'.
-			 */
-			if ((pw = strdup(*pin)) == NULL)
-				{
-				PK11err(PK11_F_GET_PIN, PK11_R_MALLOC_FAILURE);
-				(void) pthread_mutex_unlock(uri_lock);
-				goto err;
-				}
-			/* Zero the internal buffer to get rid of the PIN. */
-			memset(*pin, 0, strlen(*pin));
-			*pin = pw;
-			(void) pthread_mutex_unlock(uri_lock);
-			}
-		}
-	else
-		{
-		/*
-		 * This is the "exec:" case. We will get the PIN from the output
-		 * of an external command.
-		 */
-		if (strncmp(dialog, EXEC_SPEC, strlen(EXEC_SPEC)) == 0)
-			{
-			dialog += strlen(EXEC_SPEC);
-			if ((*pin = run_askpass(dialog)) == NULL)
-				goto err;
-			}
-		else
-			{
-			/*
-			 * Invalid specification in the passphrasedialog
-			 * keyword.
-			 */
-			PK11err(PK11_F_GET_PIN, PK11_R_BAD_PASSPHRASE_SPEC);
-			goto err;
-			}
-		}
-
-	return (1);
-err:
-	return (0);
-	}
-
-/*
- * Process the PKCS#11 URI and get the PIN. It uses information from the
- * passphrasedialog keyword to get the PIN. If passphrasedialog is not present
- * it is not considered an error since it depends on the token attributes
- * whether C_Login() is required. The function expects an allocated 'uri_struct'
- * structure.
- *
- * Returns:
- *	0 if URI is not valid at all, or if we could not get the PIN
- * 	1 if all is OK
- *	2 if the URI is not the PKCS#11 URI. In that case, put the string
- *	pointer to the filename to "*file". Note that the pointer just points
- *	inside of the "uristr", possibly skipping the file:// prefix if present.
- */
-int
-pk11_process_pkcs11_uri(const char *uristr, pkcs11_uri *uri_struct,
-	const char **file)
-	{
-	char *uristr2, *l1, *l2, *tok, *name;
-
-	/* Check the "file://" case. */
-	if (strncmp(uristr, FILE_URI_PREFIX, strlen(FILE_URI_PREFIX)) == 0)
-		{
-		*file = uristr + strlen(FILE_URI_PREFIX);
-		return (2);
-		}
-
-	/*  This is the "pkcs11:" case. */
-	if (strncmp(uristr, PK11_URI_PREFIX, strlen(PK11_URI_PREFIX)) != 0)
-		{
-		/* Not PKCS#11 URI at all, could be a filename. */
-		*file = (const char *)uristr;
-		return (2);
-		}
-	else
-		{
-		/* Dup the string and skip over the pkcs11: prefix then. */
-		uristr2 = strdup(uristr + strlen(PK11_URI_PREFIX));
-		if (uristr2 == NULL)
-			{
-			PK11err(PK11_F_CHECK_TOKEN_ATTRS,
-			    PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-		}
-
-	/* Initialize the structure. */
-	memset(uri_struct, 0, sizeof (*uri_struct));
-
-	/*
-	 * Using strtok_r() would silently skip over multiple semicolons. We
-	 * must check that before moving on. We must also avoid ';' as the first
-	 * and the last character in the URI.
-	 */
-	if (strstr(uristr2, ";;") != NULL || uristr2[0] == ';' ||
-	    (strlen(uristr2) > 0 && uristr2[strlen(uristr2) - 1] == ';'))
-		goto bad_uri;
-
-	tok = strtok_r(uristr2, ";", &l1);
-	for (; tok != NULL; tok = strtok_r(NULL, ";", &l1))
-		{
-		/* "tok" is not empty so there will be something in "name". */
-		name = strtok_r(tok, "=", &l2);
-		/* Check whether there is '=' at all. */
-		if (l2 == NULL)
-			goto bad_uri;
-
-		/*
-		 * Fill out the URI structure. We do not accept duplicit
-		 * attributes.
-		 */
-		if (strcmp(name, PK11_TOKEN) == 0)
-			{
-			if (uri_struct->token == NULL)
-				{
-				if ((uri_struct->token = strdup(l2)) == NULL)
-					goto no_mem;
-				}
-			else
-				goto bad_uri;
-			}
-		else if (strcmp(name, PK11_MANUF) == 0)
-			{
-			if (uri_struct->manuf == NULL)
-				{
-				if ((uri_struct->manuf = strdup(l2)) == NULL)
-					goto no_mem;
-				}
-			else
-				goto bad_uri;
-			}
-		else if (strcmp(name, PK11_SERIAL) == 0)
-			{
-			if (uri_struct->serial == NULL)
-				{
-				if ((uri_struct->serial = strdup(l2)) == NULL)
-					goto no_mem;
-				}
-			else
-				goto bad_uri;
-			}
-		else if (strcmp(name, PK11_MODEL) == 0)
-			{
-			if (uri_struct->model == NULL)
-				{
-				if ((uri_struct->model = strdup(l2)) == NULL)
-					goto no_mem;
-				}
-			else
-				goto bad_uri;
-			}
-		else if (strcmp(name, PK11_OBJECT) == 0)
-			{
-			if (uri_struct->object == NULL)
-				{
-				if ((uri_struct->object = strdup(l2)) == NULL)
-					goto no_mem;
-				}
-			else
-				goto bad_uri;
-			}
-		else if (strcmp(name, PK11_OBJECTTYPE) == 0)
-			{
-			if (uri_struct->objecttype == NULL)
-				{
-				uri_struct->objecttype = strdup(l2);
-				if (uri_struct->objecttype == NULL)
-					goto no_mem;
-				}
-			else
-				goto bad_uri;
-			}
-		else if (strcmp(name, PK11_ASKPASS) == 0)
-			{
-			if (uri_struct->askpass == NULL)
-				{
-				if ((uri_struct->askpass = strdup(l2)) == NULL)
-					goto no_mem;
-				}
-			else
-				goto bad_uri;
-			}
-		else
-			goto bad_uri;
-		}
-
-	/* The "object" token is mandatory in the PKCS#11 URI. */
-	if (uri_struct->object == NULL)
-		{
-		PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_MISSING_OBJECT_LABEL);
-		goto err;
-		}
-
-	free(uristr2);
-	return (1);
-bad_uri:
-	PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_INVALID_PKCS11_URI);
-	if (uristr2 != NULL)
-		free(uristr2);
-	return (0);
-no_mem:
-	PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_MALLOC_FAILURE);
-err:
-	pk11_free_pkcs11_uri(uri_struct, CK_FALSE);
-	if (uristr2 != NULL)
-		free(uristr2);
-	return (0);
-	}
-
-/*
- * Free the PKCS11 URI structure and anything that might be inside.
- */
-void
-pk11_free_pkcs11_uri(pkcs11_uri *uri_struct, CK_BBOOL free_uri_itself)
-	{
-	if (uri_struct->token != NULL)
-		free(uri_struct->token);
-	if (uri_struct->manuf != NULL)
-		free(uri_struct->manuf);
-	if (uri_struct->serial != NULL)
-		free(uri_struct->serial);
-	if (uri_struct->model != NULL)
-		free(uri_struct->model);
-	if (uri_struct->object != NULL)
-		free(uri_struct->object);
-	if (uri_struct->objecttype != NULL)
-		free(uri_struct->objecttype);
-	if (uri_struct->askpass != NULL)
-		free(uri_struct->askpass);
-
-	if (free_uri_itself == CK_TRUE)
-		OPENSSL_free(uri_struct);
-	}
-
-/*
- * While our keystore is always the one used by the pubkey slot (which is
- * usually the Metaslot) we must make sure that those URI attributes that
- * specify the keystore match the real attributes of our slot keystore. Note
- * that one can use the METASLOT_OBJECTSTORE_TOKEN environment variable to
- * change the Metaslot's keystore from the softtoken to something else (see
- * libpkcs11(3LIB)). The user might want to use such attributes in the PKCS#11
- * URI to make sure that the intended keystore is used.
- *
- * Returns:
- *	1 on success
- *	0 on failure
- */
-int
-pk11_check_token_attrs(pkcs11_uri *uri_struct)
-	{
-	CK_RV rv;
-	static CK_TOKEN_INFO_PTR token_info = NULL;
-
-	(void) pthread_mutex_lock(uri_lock);
-	if (token_info == NULL)
-		{
-		token_info = OPENSSL_malloc(sizeof (CK_TOKEN_INFO));
-		if (token_info == NULL)
-			{
-			PK11err(PK11_F_CHECK_TOKEN_ATTRS,
-			    PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-
-		rv = pFuncList->C_GetTokenInfo(pubkey_SLOTID, token_info);
-		if (rv != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_CHECK_TOKEN_ATTRS,
-			    PK11_R_GETTOKENINFO, rv);
-			goto err;
-			}
-		}
-
-	if (uri_struct->token != NULL)
-		if (strncmp(uri_struct->token, (char *)token_info->label,
-		    strlen(uri_struct->token) > 32 ? 32 :
-		    strlen(uri_struct->token)) != 0)
-			{
-			goto urierr;
-			}
-
-	if (uri_struct->manuf != NULL)
-		if (strncmp(uri_struct->manuf,
-		    (char *)token_info->manufacturerID,
-		    strlen(uri_struct->manuf) > 32 ? 32 :
-		    strlen(uri_struct->manuf)) != 0)
-			goto urierr;
-
-	if (uri_struct->model != NULL)
-		if (strncmp(uri_struct->model, (char *)token_info->model,
-		    strlen(uri_struct->model) > 16 ? 16 :
-		    strlen(uri_struct->model)) != 0)
-			goto urierr;
-
-	if (uri_struct->serial != NULL)
-		if (strncmp(uri_struct->serial,
-		    (char *)token_info->serialNumber,
-		    strlen(uri_struct->serial) > 16 ? 16 :
-		    strlen(uri_struct->serial)) != 0)
-			goto urierr;
-
-	(void) pthread_mutex_unlock(uri_lock);
-	return (1);
-
-urierr:
-	PK11err(PK11_F_CHECK_TOKEN_ATTRS, PK11_R_TOKEN_ATTRS_DO_NOT_MATCH);
-	/* Correct error already set above for the "err" label. */
-err:
-	(void) pthread_mutex_unlock(uri_lock);
-	return (0);
-	}
-
-/*
- * Return the process PIN caching policy. We initialize it just once so if the
- * process change OPENSSL_PKCS11_PIN_CACHING_POLICY during the operation it will
- * not have any affect on the policy.
- *
- * We assume that the "uri_lock" mutex is already locked.
- *
- * Returns the caching policy number.
- */
-int
-pk11_get_pin_caching_policy(void)
-	{
-	char *value = NULL;
-	static int policy = POLICY_NOT_INITIALIZED;
-
-	if (policy != POLICY_NOT_INITIALIZED)
-		return (policy);
-
-	value = getenv("OPENSSL_PKCS11_PIN_CACHING_POLICY");
-
-	if (value == NULL || strcmp(value, "none") == 0)
-		{
-		policy = POLICY_NONE;
-		goto done;
-		}
-
-	if (strcmp(value, "memory") == 0)
-		{
-		policy = POLICY_MEMORY;
-		goto done;
-		}
-
-	if (strcmp(value, "mlocked-memory") == 0)
-		{
-		policy = POLICY_MLOCKED_MEMORY;
-		goto done;
-		}
-
-	return (POLICY_WRONG_VALUE);
-done:
-	return (policy);
-	}
-
-/*
- * Cache the PIN in memory once. We already know that we have either "memory" or
- * "mlocked-memory" keyword correctly set.
- *
- * Returns:
- *	1 on success
- *	0 on failure
- */
-int
-pk11_cache_pin(char *pin)
-	{
-	(void) pthread_mutex_lock(uri_lock);
-	/* We set the PIN only once since all URIs must have it the same. */
-	if (token_pin != NULL)
-		goto ok;
-
-	if (pk11_get_pin_caching_policy() == POLICY_MEMORY)
-		{
-		if ((token_pin = strdup(pin)) == NULL)
-			{
-			PK11err(PK11_F_CACHE_PIN, PK11_R_MALLOC_FAILURE);
-			goto err;
-			}
-		}
-	else
-		{
-		if (pk11_get_pin_caching_policy() == POLICY_MLOCKED_MEMORY)
-			{
-			if (mlock_pin_in_memory(pin) == 0)
-				goto err;
-			}
-		}
-
-ok:
-	(void) pthread_mutex_unlock(uri_lock);
-	return (1);
-err:
-	(void) pthread_mutex_unlock(uri_lock);
-	return (0);
-	}
-
-/*
- * Cache the PIN in mlock(3C)ed memory. If mlock(3C) fails we will not resort to
- * the normal memory caching.
- *
- * Note that this function must be called under the protection of the "uri_lock"
- * mutex.
- *
- * Returns:
- *	1 on success
- *	0 on failure
- */
-static int
-mlock_pin_in_memory(char *pin)
-	{
-	void *addr = NULL;
-	long pagesize = 0;
-
-	/* mlock(3C) locks pages so we need one whole page for the PIN. */
-	if ((pagesize = sysconf(_SC_PAGESIZE)) == -1)
-		{
-		PK11err(PK11_F_MLOCK_PIN_IN_MEMORY, PK11_R_SYSCONF_FAILED);
-		goto err;
-		}
-
-	/* This will ensure we have a page aligned pointer... */
-	if ((addr = mmap(0, pagesize, PROT_READ | PROT_WRITE,
-	    MAP_PRIVATE | MAP_ANON, -1, 0)) == MAP_FAILED)
-		{
-		PK11err(PK11_F_MLOCK_PIN_IN_MEMORY, PK11_R_MMAP_FAILED);
-		goto err;
-		}
-
-	/* ...because "addr" must be page aligned here. */
-	if (mlock(addr, pagesize) == -1)
-		{
-		/*
-		 * Missing the PRIV_PROC_LOCK_MEMORY privilege might be a common
-		 * problem so distinguish this situation from other issues.
-		 */
-		if (errno == EPERM)
-			PK11err(PK11_F_MLOCK_PIN_IN_MEMORY,
-			    PK11_R_PRIV_PROC_LOCK_MEMORY_MISSING);
-		else
-			PK11err(PK11_F_MLOCK_PIN_IN_MEMORY,
-			    PK11_R_MLOCK_FAILED);
-
-		/*
-		 * We already have a problem here so there is no need to check
-		 * that we could unmap the page. The PIN is not there yet
-		 * anyway.
-		 */
-		(void) munmap(addr, pagesize);
-		goto err;
-		}
-
-	/* Copy the PIN to the mlocked memory. */
-	token_pin = (char *)addr;
-	strlcpy(token_pin, pin, PK11_MAX_PIN_LEN + 1);
-	return (1);
-err:
-	return (0);
-	}
-
-/*
- * Log in to the keystore if we are supposed to do that at all. Take care of
- * reading and caching the PIN etc. Log in only once even when called from
- * multiple threads.
- *
- * Returns:
- *	1 on success
- *	0 on failure
- */
-int
-pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
-    pkcs11_uri *uri_struct, CK_BBOOL is_private)
-	{
-	CK_RV rv;
-
-	if ((pubkey_token_flags & CKF_TOKEN_INITIALIZED) == 0)
-		{
-		PK11err(PK11_F_TOKEN_LOGIN,
-		    PK11_R_TOKEN_NOT_INITIALIZED);
-		goto err;
-		}
-
-	/*
-	 * If login is required or needed but the PIN has not been even
-	 * initialized we can bail out right now. Note that we are supposed to
-	 * always log in if we are going to access private keys. However, we may
-	 * need to log in even for accessing public keys in case that the
-	 * CKF_LOGIN_REQUIRED flag is set.
-	 */
-	if ((pubkey_token_flags & CKF_LOGIN_REQUIRED ||
-	    is_private == CK_TRUE) && ~pubkey_token_flags &
-	    CKF_USER_PIN_INITIALIZED)
-		{
-		PK11err(PK11_F_TOKEN_LOGIN, PK11_R_TOKEN_PIN_NOT_SET);
-		goto err;
-		}
-
-	/*
-	 * Note on locking: it is possible that more than one thread gets into
-	 * pk11_get_pin() so we must deal with that. We cannot avoid it since we
-	 * cannot guard fork() in there with a lock because we could end up in
-	 * a dead lock in the child. Why? Remember we are in a multithreaded
-	 * environment so we must lock all mutexes in the prefork function to
-	 * avoid a situation in which a thread that did not call fork() held a
-	 * lock, making future unlocking impossible. We lock right before
-	 * C_Login().
-	 */
-	if (pubkey_token_flags & CKF_LOGIN_REQUIRED || is_private == CK_TRUE)
-		{
-		if (*login_done == CK_FALSE &&
-		    uri_struct->askpass == NULL)
-			{
-			PK11err(PK11_F_TOKEN_LOGIN,
-			    PK11_R_TOKEN_PIN_NOT_PROVIDED);
-			goto err;
-			}
-
-		if (*login_done == CK_FALSE &&
-		    uri_struct->askpass != NULL)
-			{
-			if (pk11_get_pin(uri_struct->askpass,
-			    &uri_struct->pin) == 0)
-				{
-				PK11err(PK11_F_TOKEN_LOGIN,
-				    PK11_R_TOKEN_PIN_NOT_PROVIDED);
-				goto err;
-				}
-			}
-
-		/*
-		 * Note that what we are logging into is the keystore from
-		 * pubkey_SLOTID because we work with OP_RSA session type here.
-		 * That also means that we can work with only one keystore in
-		 * the engine.
-		 *
-		 * We must make sure we do not try to login more than once.
-		 * Also, see the comment above on locking strategy.
-		 */
-		(void) pthread_mutex_lock(uri_lock);
-		if (*login_done == CK_FALSE)
-			{
-			if ((rv = pFuncList->C_Login(session,
-			    CKU_USER, (CK_UTF8CHAR*)uri_struct->pin,
-			    strlen(uri_struct->pin))) != CKR_OK)
-				{
-				PK11err_add_data(PK11_F_TOKEN_LOGIN,
-				    PK11_R_TOKEN_LOGIN_FAILED, rv);
-				goto err_locked;
-				}
-
-			*login_done = CK_TRUE;
-
-			/*
-			 * Cache the passphrasedialog for possible child (which
-			 * would need to relogin).
-			 */
-			if (passphrasedialog == NULL &&
-			    uri_struct->askpass != NULL)
-				{
-				passphrasedialog =
-				    strdup(uri_struct->askpass);
-
-				if (passphrasedialog == NULL)
-					{
-					PK11err_add_data(PK11_F_TOKEN_LOGIN,
-					    PK11_R_MALLOC_FAILURE, rv);
-					goto err_locked;
-					}
-				}
-
-			/*
-			 * Check the PIN caching policy. Note that user might
-			 * have provided a PIN even when no PIN was required -
-			 * in that case we always remove the PIN from memory.
-			 */
-			if (pk11_get_pin_caching_policy() ==
-			    POLICY_WRONG_VALUE)
-				{
-				PK11err(PK11_F_TOKEN_LOGIN,
-				    PK11_R_PIN_CACHING_POLICY_INVALID);
-				goto err_locked;
-				}
-
-			if (pk11_get_pin_caching_policy() != POLICY_NONE)
-				if (pk11_cache_pin(uri_struct->pin) == 0)
-					goto err_locked;
-			}
-		(void) pthread_mutex_unlock(uri_lock);
-		}
-	else
-		{
-			/*
-			 * If token does not require login we take it as the
-			 * login was done.
-			 */
-			*login_done = CK_TRUE;
-		}
-
-	/*
-	 * If we raced at pk11_get_pin() we must make sure that all threads that
-	 * called pk11_get_pin() will erase the PIN from memory, not just the
-	 * one that called C_Login(). Note that if we were supposed to cache the
-	 * PIN it was already cached by now so filling "uri_struct.pin" with
-	 * zero bytes is always OK since pk11_cache_pin() makes a copy of it.
-	 */
-	if (uri_struct->pin != NULL)
-		memset(uri_struct->pin, 0, strlen(uri_struct->pin));
-
-	return (1);
-
-err_locked:
-	(void) pthread_mutex_unlock(uri_lock);
-err:
-	/* Always get rid of the PIN. */
-	if (uri_struct->pin != NULL)
-		memset(uri_struct->pin, 0, strlen(uri_struct->pin));
-	return (0);
-	}
-
-/*
- * Log in to the keystore in the child if we were logged in in the parent. There
- * are similarities in the code with pk11_token_login() but still it is quite
- * different so we need a separate function for this.
- *
- * Note that this function is called under the locked session mutex when fork is
- * detected. That means that C_Login() will be called from the child just once.
- *
- * Returns:
- *	1 on success
- *	0 on failure
- */
-int
-pk11_token_relogin(CK_SESSION_HANDLE session)
-	{
-	CK_RV rv;
-
-	/*
-	 * We are in the child so check if we should login to the token again.
-	 * Note that it is enough to log in to the token through one session
-	 * only, all already open and all future sessions can access the token
-	 * then.
-	 */
-	if (passphrasedialog != NULL)
-		{
-		char *pin = NULL;
-
-		/* If we cached the PIN then use it. */
-		if (token_pin != NULL)
-			pin = token_pin;
-		else if (pk11_get_pin(passphrasedialog, &pin) == 0)
-			goto err;
-
-		(void) pthread_mutex_lock(uri_lock);
-		if ((rv = pFuncList->C_Login(session, CKU_USER,
-		    (CK_UTF8CHAR_PTR)pin, strlen(pin))) != CKR_OK)
-			{
-			PK11err_add_data(PK11_F_TOKEN_RELOGIN,
-			    PK11_R_TOKEN_LOGIN_FAILED, rv);
-			(void) pthread_mutex_unlock(uri_lock);
-			goto err;
-			}
-		(void) pthread_mutex_unlock(uri_lock);
-
-		/* Forget the PIN now if we did not cache it before. */
-		if (pin != token_pin)
-			{
-			memset(pin, 0, strlen(pin));
-			OPENSSL_free(pin);
-			}
-		}
-
-	return (1);
-err:
-	return (0);
-	}
-
-/*
- * This function forks and runs an external command. It would be nice if we
- * could use popen(3C)/pclose(3C) for that but unfortunately we need to be able
- * to get rid of the PIN from the memory. With p(open|close) function calls we
- * cannot control the stdio's memory used for buffering and our tests showed
- * that the PIN really stays there even after pclose().
- *
- * Returns:
- *	allocated buffer on success
- *	NULL on failure
- */
-static char *
-run_askpass(char *dialog)
-	{
-	pid_t pid;
-	int n, p[2];
-	char *buf = NULL;
-
-	if (pipe(p) == -1)
-		{
-		PK11err(PK11_F_RUN_ASKPASS, PK11_R_PIPE_FAILED);
-		return (NULL);
-		}
-
-	switch (pid = fork())
-		{
-		case -1:
-			PK11err(PK11_F_RUN_ASKPASS, PK11_R_FORK_FAILED);
-			return (NULL);
-		/* child */
-		case 0:
-			/*
-			 * This should make sure that dup2() will not fail on
-			 * file descriptor shortage.
-			 */
-			close(p[0]);
-			(void) dup2(p[1], 1);
-			close(p[1]);
-			/*
-			 * Note that we cannot use PK11err() here since we are
-			 * in the child. However, parent will get read() error
-			 * so do not worry.
-			 */
-			(void) execl(dialog, basename(dialog), NULL);
-			exit(1);
-		/* parent */
-		default:
-			/* +1 is for the terminating '\0' */
-			buf = (char *)OPENSSL_malloc(PK11_MAX_PIN_LEN + 1);
-			if (buf == NULL)
-				{
-				PK11err(PK11_F_RUN_ASKPASS,
-				    PK11_R_MALLOC_FAILURE);
-				return (NULL);
-				}
-
-			close(p[1]);
-			n = read(p[0], buf, PK11_MAX_PIN_LEN);
-			if (n == -1 || n == 0)
-				{
-				PK11err(PK11_F_RUN_ASKPASS,
-				    PK11_R_PIN_NOT_READ_FROM_COMMAND);
-				OPENSSL_free(buf);
-				return (NULL);
-				}
-			buf[n] = '\0';
-
-			(void) waitpid(pid, NULL, 0);
-		}
-
-	return (buf);
-	}
-
-#endif	/* OPENSSL_NO_HW_PK11 */
-#endif	/* OPENSSL_NO_HW */
--- a/components/openssl/openssl-1.0.1/engines/pkcs11/e_pk11_uri.h	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved.
- */
-
-/*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    [email protected].
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (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	E_PK11_URI_H
-#define	E_PK11_URI_H
-
-#include <security/pkcs11t.h>
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-/* PKCS#11 URI related prefixes and attributes. */
-#define	PK11_URI_PREFIX		"pkcs11:"
-#define	FILE_URI_PREFIX		"file://"
-#define	PK11_TOKEN		"token"
-#define	PK11_MANUF		"manuf"
-#define	PK11_SERIAL		"serial"
-#define	PK11_MODEL		"model"
-#define	PK11_OBJECT		"object"
-#define	PK11_OBJECTTYPE		"objecttype"
-#define	PK11_ASKPASS		"passphrasedialog"
-
-/* PIN caching policy. */
-#define	POLICY_NOT_INITIALIZED	0
-#define	POLICY_NONE		1
-#define	POLICY_MEMORY		2
-#define	POLICY_MLOCKED_MEMORY	3
-#define	POLICY_WRONG_VALUE	4
-
-/*
- * That's what getpassphrase(3c) supports.
- */
-#define	PK11_MAX_PIN_LEN	256
-
-/* Add new attributes of the PKCS#11 URI here. */
-typedef struct pkcs11_uri_struct {
-	char	*object;	/* object label, the only mandatory info */
-	char	*objecttype;	/* (private|public|cert), currently unused */
-	char	*token;		/* token label */
-	char	*manuf;		/* manufacturer label */
-	char	*serial;	/* serial number label */
-	char	*model;		/* model label */
-	char	*askpass;	/* full path to the command to get the PIN */
-	/* Not part of the PKCS11 URI itself. */
-	char	*pin;		/* token PIN */
-} pkcs11_uri;
-
-/* For URI processing. */
-extern pthread_mutex_t *uri_lock;
-
-int pk11_get_pin(char *dialog, char **pin);
-int pk11_get_pin_caching_policy(void);
-int pk11_process_pkcs11_uri(const char *uristr, pkcs11_uri *uri_struct,
-	const char **file);
-int pk11_check_token_attrs(pkcs11_uri *uri_struct);
-void pk11_free_pkcs11_uri(pkcs11_uri *uri_struct, CK_BBOOL free_uri_itself);
-int pk11_cache_pin(char *pin);
-int pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
-	pkcs11_uri *uri_struct, CK_BBOOL is_private);
-int pk11_token_relogin(CK_SESSION_HANDLE session);
-
-#ifdef	__cplusplus
-}
-#endif
-#endif /* E_PK11_URI_H */
--- a/components/openssl/openssl-1.0.1/inline-t4/aest4-sparcv9.pl	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,902 +0,0 @@
-#!/usr/bin/env perl
-
-# ====================================================================
-# Written by David S. Miller <[email protected]> and Andy Polyakov
-# <[email protected]>. The module is licensed under 2-clause BSD
-# license. October 2012. All rights reserved.
-# ====================================================================
-
-######################################################################
-# AES for SPARC T4.
-#
-# AES round instructions complete in 3 cycles and can be issued every
-# cycle. It means that round calculations should take 4*rounds cycles,
-# because any given round instruction depends on result of *both*
-# previous instructions:
-#
-#	|0 |1 |2 |3 |4
-#	|01|01|01|
-#	   |23|23|23|
-#	            |01|01|...
-#	               |23|...
-#
-# Provided that fxor [with IV] takes 3 cycles to complete, critical
-# path length for CBC encrypt would be 3+4*rounds, or in other words
-# it should process one byte in at least (3+4*rounds)/16 cycles. This
-# estimate doesn't account for "collateral" instructions, such as
-# fetching input from memory, xor-ing it with zero-round key and
-# storing the result. Yet, *measured* performance [for data aligned
-# at 64-bit boundary!] deviates from this equation by less than 0.5%:
-#
-#		128-bit key	192-		256-
-# CBC encrypt	2.70/2.90(*)	3.20/3.40	3.70/3.90
-#			 (*) numbers after slash are for
-#			     misaligned data.
-#
-# Out-of-order execution logic managed to fully overlap "collateral"
-# instructions with those on critical path. Amazing!
-#
-# As with Intel AES-NI, question is if it's possible to improve
-# performance of parallelizeable modes by interleaving round
-# instructions. Provided round instruction latency and throughput
-# optimal interleave factor is 2. But can we expect 2x performance
-# improvement? Well, as round instructions can be issued one per
-# cycle, they don't saturate the 2-way issue pipeline and therefore
-# there is room for "collateral" calculations... Yet, 2x speed-up
-# over CBC encrypt remains unattaintable:
-#
-#		128-bit key	192-		256-
-# CBC decrypt	1.64/2.11	1.89/2.37	2.23/2.61
-# CTR		1.64/2.08(*)	1.89/2.33	2.23/2.61
-#			 (*) numbers after slash are for
-#			     misaligned data.
-#
-# Estimates based on amount of instructions under assumption that
-# round instructions are not pairable with any other instruction
-# suggest that latter is the actual case and pipeline runs
-# underutilized. It should be noted that T4 out-of-order execution
-# logic is so capable that performance gain from 2x interleave is
-# not even impressive, ~7-13% over non-interleaved code, largest
-# for 256-bit keys.
-
-# To anchor to something else, software implementation processes
-# one byte in 29 cycles with 128-bit key on same processor. Intel
-# Sandy Bridge encrypts byte in 5.07 cycles in CBC mode and decrypts
-# in 0.93, naturally with AES-NI.
-
-$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-push(@INC,"${dir}","${dir}../../perlasm");
-require "sparcv9_modes.pl";
-
-&asm_init(@ARGV);
-
-$::evp=1;	# if $evp is set to 0, script generates module with
-# AES_[en|de]crypt, AES_set_[en|de]crypt_key and AES_cbc_encrypt entry
-# points. These however are not fully compatible with openssl/aes.h,
-# because they expect AES_KEY to be aligned at 64-bit boundary. When
-# used through EVP, alignment is arranged at EVP layer. Second thing
-# that is arranged by EVP is at least 32-bit alignment of IV.
-
-######################################################################
-# single-round subroutines
-#
-{
-my ($inp,$out,$key,$rounds,$tmp,$mask)=map("%o$_",(0..5));
-
-$code=<<___;
-.text
-
-.globl	aes_t4_encrypt
-.align	32
-aes_t4_encrypt:
-	andcc		$inp, 7, %g1		! is input aligned?
-	andn		$inp, 7, $inp
-
-	ldx		[$key + 0], %g4
-	ldx		[$key + 8], %g5
-
-	ldx		[$inp + 0], %o4
-	bz,pt		%icc, 1f
-	ldx		[$inp + 8], %o5
-	ldx		[$inp + 16], $inp
-	sll		%g1, 3, %g1
-	sub		%g0, %g1, %o3
-	sllx		%o4, %g1, %o4
-	sllx		%o5, %g1, %g1
-	srlx		%o5, %o3, %o5
-	srlx		$inp, %o3, %o3
-	or		%o5, %o4, %o4
-	or		%o3, %g1, %o5
-1:
-	ld		[$key + 240], $rounds
-	ldd		[$key + 16], %f12
-	ldd		[$key + 24], %f14
-	xor		%g4, %o4, %o4
-	xor		%g5, %o5, %o5
-	movxtod		%o4, %f0
-	movxtod		%o5, %f2
-	srl		$rounds, 1, $rounds
-	ldd		[$key + 32], %f16
-	sub		$rounds, 1, $rounds
-	ldd		[$key + 40], %f18
-	add		$key, 48, $key
-
-.Lenc:
-	aes_eround01	%f12, %f0, %f2, %f4
-	aes_eround23	%f14, %f0, %f2, %f2
-	ldd		[$key + 0], %f12
-	ldd		[$key + 8], %f14
-	sub		$rounds,1,$rounds
-	aes_eround01	%f16, %f4, %f2, %f0
-	aes_eround23	%f18, %f4, %f2, %f2
-	ldd		[$key + 16], %f16
-	ldd		[$key + 24], %f18
-	brnz,pt		$rounds, .Lenc
-	add		$key, 32, $key
-
-	andcc		$out, 7, $tmp		! is output aligned?
-	aes_eround01	%f12, %f0, %f2, %f4
-	aes_eround23	%f14, %f0, %f2, %f2
-	aes_eround01_l	%f16, %f4, %f2, %f0
-	aes_eround23_l	%f18, %f4, %f2, %f2
-
-	bnz,pn		%icc, 2f
-	nop
-
-	std		%f0, [$out + 0]
-	retl
-	std		%f2, [$out + 8]
-
-2:	alignaddrl	$out, %g0, $out
-	mov		0xff, $mask
-	srl		$mask, $tmp, $mask
-
-	faligndata	%f0, %f0, %f4
-	faligndata	%f0, %f2, %f6
-	faligndata	%f2, %f2, %f8
-
-	stda		%f4, [$out + $mask]0xc0	! partial store
-	std		%f6, [$out + 8]
-	add		$out, 16, $out
-	orn		%g0, $mask, $mask
-	retl
-	stda		%f8, [$out + $mask]0xc0	! partial store
-.type	aes_t4_encrypt,#function
-.size	aes_t4_encrypt,.-aes_t4_encrypt
-
-.globl	aes_t4_decrypt
-.align	32
-aes_t4_decrypt:
-	andcc		$inp, 7, %g1		! is input aligned?
-	andn		$inp, 7, $inp
-
-	ldx		[$key + 0], %g4
-	ldx		[$key + 8], %g5
-
-	ldx		[$inp + 0], %o4
-	bz,pt		%icc, 1f
-	ldx		[$inp + 8], %o5
-	ldx		[$inp + 16], $inp
-	sll		%g1, 3, %g1
-	sub		%g0, %g1, %o3
-	sllx		%o4, %g1, %o4
-	sllx		%o5, %g1, %g1
-	srlx		%o5, %o3, %o5
-	srlx		$inp, %o3, %o3
-	or		%o5, %o4, %o4
-	or		%o3, %g1, %o5
-1:
-	ld		[$key + 240], $rounds
-	ldd		[$key + 16], %f12
-	ldd		[$key + 24], %f14
-	xor		%g4, %o4, %o4
-	xor		%g5, %o5, %o5
-	movxtod		%o4, %f0
-	movxtod		%o5, %f2
-	srl		$rounds, 1, $rounds
-	ldd		[$key + 32], %f16
-	sub		$rounds, 1, $rounds
-	ldd		[$key + 40], %f18
-	add		$key, 48, $key
-
-.Ldec:
-	aes_dround01	%f12, %f0, %f2, %f4
-	aes_dround23	%f14, %f0, %f2, %f2
-	ldd		[$key + 0], %f12
-	ldd		[$key + 8], %f14
-	sub		$rounds,1,$rounds
-	aes_dround01	%f16, %f4, %f2, %f0
-	aes_dround23	%f18, %f4, %f2, %f2
-	ldd		[$key + 16], %f16
-	ldd		[$key + 24], %f18
-	brnz,pt		$rounds, .Ldec
-	add		$key, 32, $key
-
-	andcc		$out, 7, $tmp		! is output aligned?
-	aes_dround01	%f12, %f0, %f2, %f4
-	aes_dround23	%f14, %f0, %f2, %f2
-	aes_dround01_l	%f16, %f4, %f2, %f0
-	aes_dround23_l	%f18, %f4, %f2, %f2
-
-	bnz,pn		%icc, 2f
-	nop
-
-	std		%f0, [$out + 0]
-	retl
-	std		%f2, [$out + 8]
-
-2:	alignaddrl	$out, %g0, $out
-	mov		0xff, $mask
-	srl		$mask, $tmp, $mask
-
-	faligndata	%f0, %f0, %f4
-	faligndata	%f0, %f2, %f6
-	faligndata	%f2, %f2, %f8
-
-	stda		%f4, [$out + $mask]0xc0	! partial store
-	std		%f6, [$out + 8]
-	add		$out, 16, $out
-	orn		%g0, $mask, $mask
-	retl
-	stda		%f8, [$out + $mask]0xc0	! partial store
-.type	aes_t4_decrypt,#function
-.size	aes_t4_decrypt,.-aes_t4_decrypt
-___
-}
-
-######################################################################
-# key setup subroutines
-#
-{
-my ($inp,$bits,$out,$tmp)=map("%o$_",(0..5));
-$code.=<<___;
-.globl	aes_t4_set_encrypt_key
-.align	32
-aes_t4_set_encrypt_key:
-.Lset_encrypt_key:
-	and		$inp, 7, $tmp
-	alignaddr	$inp, %g0, $inp
-	cmp		$bits, 192
-	ldd		[$inp + 0], %f0
-	bl,pt		%icc,.L128
-	ldd		[$inp + 8], %f2
-
-	be,pt		%icc,.L192
-	ldd		[$inp + 16], %f4
-	brz,pt		$tmp, .L256aligned
-	ldd		[$inp + 24], %f6
-
-	ldd		[$inp + 32], %f8
-	faligndata	%f0, %f2, %f0
-	faligndata	%f2, %f4, %f2
-	faligndata	%f4, %f6, %f4
-	faligndata	%f6, %f8, %f6
-.L256aligned:
-___
-for ($i=0; $i<6; $i++) {
-    $code.=<<___;
-	std		%f0, [$out + `32*$i+0`]
-	aes_kexpand1	%f0, %f6, $i, %f0
-	std		%f2, [$out + `32*$i+8`]
-	aes_kexpand2	%f2, %f0, %f2
-	std		%f4, [$out + `32*$i+16`]
-	aes_kexpand0	%f4, %f2, %f4
-	std		%f6, [$out + `32*$i+24`]
-	aes_kexpand2	%f6, %f4, %f6
-___
-}
-$code.=<<___;
-	std		%f0, [$out + `32*$i+0`]
-	aes_kexpand1	%f0, %f6, $i, %f0
-	std		%f2, [$out + `32*$i+8`]
-	aes_kexpand2	%f2, %f0, %f2
-	std		%f4, [$out + `32*$i+16`]
-	std		%f6, [$out + `32*$i+24`]
-	std		%f0, [$out + `32*$i+32`]
-	std		%f2, [$out + `32*$i+40`]
-
-	mov		14, $tmp
-	st		$tmp, [$out + 240]
-	retl
-	xor		%o0, %o0, %o0
-
-.align	16
-.L192:
-	brz,pt		$tmp, .L192aligned
-	nop
-
-	ldd		[$inp + 24], %f6
-	faligndata	%f0, %f2, %f0
-	faligndata	%f2, %f4, %f2
-	faligndata	%f4, %f6, %f4
-.L192aligned:
-___
-for ($i=0; $i<7; $i++) {
-    $code.=<<___;
-	std		%f0, [$out + `24*$i+0`]
-	aes_kexpand1	%f0, %f4, $i, %f0
-	std		%f2, [$out + `24*$i+8`]
-	aes_kexpand2	%f2, %f0, %f2
-	std		%f4, [$out + `24*$i+16`]
-	aes_kexpand2	%f4, %f2, %f4
-___
-}
-$code.=<<___;
-	std		%f0, [$out + `24*$i+0`]
-	aes_kexpand1	%f0, %f4, $i, %f0
-	std		%f2, [$out + `24*$i+8`]
-	aes_kexpand2	%f2, %f0, %f2
-	std		%f4, [$out + `24*$i+16`]
-	std		%f0, [$out + `24*$i+24`]
-	std		%f2, [$out + `24*$i+32`]
-
-	mov		12, $tmp
-	st		$tmp, [$out + 240]
-	retl
-	xor		%o0, %o0, %o0
-
-.align	16
-.L128:
-	brz,pt		$tmp, .L128aligned
-	nop
-
-	ldd		[$inp + 16], %f4
-	faligndata	%f0, %f2, %f0
-	faligndata	%f2, %f4, %f2
-.L128aligned:
-___
-for ($i=0; $i<10; $i++) {
-    $code.=<<___;
-	std		%f0, [$out + `16*$i+0`]
-	aes_kexpand1	%f0, %f2, $i, %f0
-	std		%f2, [$out + `16*$i+8`]
-	aes_kexpand2	%f2, %f0, %f2
-___
-}
-$code.=<<___;
-	std		%f0, [$out + `16*$i+0`]
-	std		%f2, [$out + `16*$i+8`]
-
-	mov		10, $tmp
-	st		$tmp, [$out + 240]
-	retl
-	xor		%o0, %o0, %o0
-.type	aes_t4_set_encrypt_key,#function
-.size	aes_t4_set_encrypt_key,.-aes_t4_set_encrypt_key
-
-.globl	aes_t4_set_decrypt_key
-.align	32
-aes_t4_set_decrypt_key:
-	mov		%o7, %o5
-	call		.Lset_encrypt_key
-	nop
-
-	mov		%o5, %o7
-	sll		$tmp, 4, $inp		! $tmp is number of rounds
-	add		$tmp, 2, $tmp
-	add		$out, $inp, $inp	! $inp=$out+16*rounds
-	srl		$tmp, 2, $tmp		! $tmp=(rounds+2)/4
-
-.Lkey_flip:
-	ldd		[$out + 0],  %f0
-	ldd		[$out + 8],  %f2
-	ldd		[$out + 16], %f4
-	ldd		[$out + 24], %f6
-	ldd		[$inp + 0],  %f8
-	ldd		[$inp + 8],  %f10
-	ldd		[$inp - 16], %f12
-	ldd		[$inp - 8],  %f14
-	sub		$tmp, 1, $tmp
-	std		%f0, [$inp + 0]
-	std		%f2, [$inp + 8]
-	std		%f4, [$inp - 16]
-	std		%f6, [$inp - 8]
-	std		%f8, [$out + 0]
-	std		%f10, [$out + 8]
-	std		%f12, [$out + 16]
-	std		%f14, [$out + 24]
-	add		$out, 32, $out
-	brnz		$tmp, .Lkey_flip
-	sub		$inp, 32, $inp
-
-	retl
-	xor		%o0, %o0, %o0
-.type	aes_t4_set_decrypt_key,#function
-.size	aes_t4_set_decrypt_key,.-aes_t4_set_decrypt_key
-___
-}
-
-{{{
-my ($inp,$out,$len,$key,$ivec,$enc)=map("%i$_",(0..5));
-my ($ileft,$iright,$ooff,$omask,$ivoff)=map("%l$_",(1..7));
-
-$code.=<<___;
-.align	32
-_aes128_loadkey:
-	ldx		[$key + 0], %g4
-	ldx		[$key + 8], %g5
-___
-for ($i=2; $i<22;$i++) {			# load key schedule
-    $code.=<<___;
-	ldd		[$key + `8*$i`], %f`12+2*$i`
-___
-}
-$code.=<<___;
-	retl
-	nop
-.type	_aes128_loadkey,#function
-.size	_aes128_loadkey,.-_aes128_loadkey
-_aes128_load_enckey=_aes128_loadkey
-_aes128_load_deckey=_aes128_loadkey
-
-.align	32
-_aes128_encrypt_1x:
-___
-for ($i=0; $i<4; $i++) {
-    $code.=<<___;
-	aes_eround01	%f`16+8*$i+0`, %f0, %f2, %f4
-	aes_eround23	%f`16+8*$i+2`, %f0, %f2, %f2
-	aes_eround01	%f`16+8*$i+4`, %f4, %f2, %f0
-	aes_eround23	%f`16+8*$i+6`, %f4, %f2, %f2
-___
-}
-$code.=<<___;
-	aes_eround01	%f48, %f0, %f2, %f4
-	aes_eround23	%f50, %f0, %f2, %f2
-	aes_eround01_l	%f52, %f4, %f2, %f0
-	retl
-	aes_eround23_l	%f54, %f4, %f2, %f2
-.type	_aes128_encrypt_1x,#function
-.size	_aes128_encrypt_1x,.-_aes128_encrypt_1x
-
-.align	32
-_aes128_encrypt_2x:
-___
-for ($i=0; $i<4; $i++) {
-    $code.=<<___;
-	aes_eround01	%f`16+8*$i+0`, %f0, %f2, %f8
-	aes_eround23	%f`16+8*$i+2`, %f0, %f2, %f2
-	aes_eround01	%f`16+8*$i+0`, %f4, %f6, %f10
-	aes_eround23	%f`16+8*$i+2`, %f4, %f6, %f6
-	aes_eround01	%f`16+8*$i+4`, %f8, %f2, %f0
-	aes_eround23	%f`16+8*$i+6`, %f8, %f2, %f2
-	aes_eround01	%f`16+8*$i+4`, %f10, %f6, %f4
-	aes_eround23	%f`16+8*$i+6`, %f10, %f6, %f6
-___
-}
-$code.=<<___;
-	aes_eround01	%f48, %f0, %f2, %f8
-	aes_eround23	%f50, %f0, %f2, %f2
-	aes_eround01	%f48, %f4, %f6, %f10
-	aes_eround23	%f50, %f4, %f6, %f6
-	aes_eround01_l	%f52, %f8, %f2, %f0
-	aes_eround23_l	%f54, %f8, %f2, %f2
-	aes_eround01_l	%f52, %f10, %f6, %f4
-	retl
-	aes_eround23_l	%f54, %f10, %f6, %f6
-.type	_aes128_encrypt_2x,#function
-.size	_aes128_encrypt_2x,.-_aes128_encrypt_2x
-
-.align	32
-_aes128_decrypt_1x:
-___
-for ($i=0; $i<4; $i++) {
-    $code.=<<___;
-	aes_dround01	%f`16+8*$i+0`, %f0, %f2, %f4
-	aes_dround23	%f`16+8*$i+2`, %f0, %f2, %f2
-	aes_dround01	%f`16+8*$i+4`, %f4, %f2, %f0
-	aes_dround23	%f`16+8*$i+6`, %f4, %f2, %f2
-___
-}
-$code.=<<___;
-	aes_dround01	%f48, %f0, %f2, %f4
-	aes_dround23	%f50, %f0, %f2, %f2
-	aes_dround01_l	%f52, %f4, %f2, %f0
-	retl
-	aes_dround23_l	%f54, %f4, %f2, %f2
-.type	_aes128_decrypt_1x,#function
-.size	_aes128_decrypt_1x,.-_aes128_decrypt_1x
-
-.align	32
-_aes128_decrypt_2x:
-___
-for ($i=0; $i<4; $i++) {
-    $code.=<<___;
-	aes_dround01	%f`16+8*$i+0`, %f0, %f2, %f8
-	aes_dround23	%f`16+8*$i+2`, %f0, %f2, %f2
-	aes_dround01	%f`16+8*$i+0`, %f4, %f6, %f10
-	aes_dround23	%f`16+8*$i+2`, %f4, %f6, %f6
-	aes_dround01	%f`16+8*$i+4`, %f8, %f2, %f0
-	aes_dround23	%f`16+8*$i+6`, %f8, %f2, %f2
-	aes_dround01	%f`16+8*$i+4`, %f10, %f6, %f4
-	aes_dround23	%f`16+8*$i+6`, %f10, %f6, %f6
-___
-}
-$code.=<<___;
-	aes_dround01	%f48, %f0, %f2, %f8
-	aes_dround23	%f50, %f0, %f2, %f2
-	aes_dround01	%f48, %f4, %f6, %f10
-	aes_dround23	%f50, %f4, %f6, %f6
-	aes_dround01_l	%f52, %f8, %f2, %f0
-	aes_dround23_l	%f54, %f8, %f2, %f2
-	aes_dround01_l	%f52, %f10, %f6, %f4
-	retl
-	aes_dround23_l	%f54, %f10, %f6, %f6
-.type	_aes128_decrypt_2x,#function
-.size	_aes128_decrypt_2x,.-_aes128_decrypt_2x
-
-.align	32
-_aes192_loadkey:
-_aes256_loadkey:
-	ldx		[$key + 0], %g4
-	ldx		[$key + 8], %g5
-___
-for ($i=2; $i<26;$i++) {			# load key schedule
-    $code.=<<___;
-	ldd		[$key + `8*$i`], %f`12+2*$i`
-___
-}
-$code.=<<___;
-	retl
-	nop
-.type	_aes192_loadkey,#function
-.size	_aes192_loadkey,.-_aes192_loadkey
-_aes192_load_enckey=_aes192_loadkey
-_aes192_load_deckey=_aes192_loadkey
-_aes256_load_enckey=_aes192_loadkey
-_aes256_load_deckey=_aes192_loadkey
-
-.align	32
-_aes192_encrypt_1x:
-___
-for ($i=0; $i<5; $i++) {
-    $code.=<<___;
-	aes_eround01	%f`16+8*$i+0`, %f0, %f2, %f4
-	aes_eround23	%f`16+8*$i+2`, %f0, %f2, %f2
-	aes_eround01	%f`16+8*$i+4`, %f4, %f2, %f0
-	aes_eround23	%f`16+8*$i+6`, %f4, %f2, %f2
-___
-}
-$code.=<<___;
-	aes_eround01	%f56, %f0, %f2, %f4
-	aes_eround23	%f58, %f0, %f2, %f2
-	aes_eround01_l	%f60, %f4, %f2, %f0
-	retl
-	aes_eround23_l	%f62, %f4, %f2, %f2
-.type	_aes192_encrypt_1x,#function
-.size	_aes192_encrypt_1x,.-_aes192_encrypt_1x
-
-.align	32
-_aes192_encrypt_2x:
-___
-for ($i=0; $i<5; $i++) {
-    $code.=<<___;
-	aes_eround01	%f`16+8*$i+0`, %f0, %f2, %f8
-	aes_eround23	%f`16+8*$i+2`, %f0, %f2, %f2
-	aes_eround01	%f`16+8*$i+0`, %f4, %f6, %f10
-	aes_eround23	%f`16+8*$i+2`, %f4, %f6, %f6
-	aes_eround01	%f`16+8*$i+4`, %f8, %f2, %f0
-	aes_eround23	%f`16+8*$i+6`, %f8, %f2, %f2
-	aes_eround01	%f`16+8*$i+4`, %f10, %f6, %f4
-	aes_eround23	%f`16+8*$i+6`, %f10, %f6, %f6
-___
-}
-$code.=<<___;
-	aes_eround01	%f56, %f0, %f2, %f8
-	aes_eround23	%f58, %f0, %f2, %f2
-	aes_eround01	%f56, %f4, %f6, %f10
-	aes_eround23	%f58, %f4, %f6, %f6
-	aes_eround01_l	%f60, %f8, %f2, %f0
-	aes_eround23_l	%f62, %f8, %f2, %f2
-	aes_eround01_l	%f60, %f10, %f6, %f4
-	retl
-	aes_eround23_l	%f62, %f10, %f6, %f6
-.type	_aes192_encrypt_2x,#function
-.size	_aes192_encrypt_2x,.-_aes192_encrypt_2x
-
-.align	32
-_aes192_decrypt_1x:
-___
-for ($i=0; $i<5; $i++) {
-    $code.=<<___;
-	aes_dround01	%f`16+8*$i+0`, %f0, %f2, %f4
-	aes_dround23	%f`16+8*$i+2`, %f0, %f2, %f2
-	aes_dround01	%f`16+8*$i+4`, %f4, %f2, %f0
-	aes_dround23	%f`16+8*$i+6`, %f4, %f2, %f2
-___
-}
-$code.=<<___;
-	aes_dround01	%f56, %f0, %f2, %f4
-	aes_dround23	%f58, %f0, %f2, %f2
-	aes_dround01_l	%f60, %f4, %f2, %f0
-	retl
-	aes_dround23_l	%f62, %f4, %f2, %f2
-.type	_aes192_decrypt_1x,#function
-.size	_aes192_decrypt_1x,.-_aes192_decrypt_1x
-
-.align	32
-_aes192_decrypt_2x:
-___
-for ($i=0; $i<5; $i++) {
-    $code.=<<___;
-	aes_dround01	%f`16+8*$i+0`, %f0, %f2, %f8
-	aes_dround23	%f`16+8*$i+2`, %f0, %f2, %f2
-	aes_dround01	%f`16+8*$i+0`, %f4, %f6, %f10
-	aes_dround23	%f`16+8*$i+2`, %f4, %f6, %f6
-	aes_dround01	%f`16+8*$i+4`, %f8, %f2, %f0
-	aes_dround23	%f`16+8*$i+6`, %f8, %f2, %f2
-	aes_dround01	%f`16+8*$i+4`, %f10, %f6, %f4
-	aes_dround23	%f`16+8*$i+6`, %f10, %f6, %f6
-___
-}
-$code.=<<___;
-	aes_dround01	%f56, %f0, %f2, %f8
-	aes_dround23	%f58, %f0, %f2, %f2
-	aes_dround01	%f56, %f4, %f6, %f10
-	aes_dround23	%f58, %f4, %f6, %f6
-	aes_dround01_l	%f60, %f8, %f2, %f0
-	aes_dround23_l	%f62, %f8, %f2, %f2
-	aes_dround01_l	%f60, %f10, %f6, %f4
-	retl
-	aes_dround23_l	%f62, %f10, %f6, %f6
-.type	_aes192_decrypt_2x,#function
-.size	_aes192_decrypt_2x,.-_aes192_decrypt_2x
-
-.align	32
-_aes256_encrypt_1x:
-	aes_eround01	%f16, %f0, %f2, %f4
-	aes_eround23	%f18, %f0, %f2, %f2
-	ldd		[$key + 208], %f16
-	ldd		[$key + 216], %f18
-	aes_eround01	%f20, %f4, %f2, %f0
-	aes_eround23	%f22, %f4, %f2, %f2
-	ldd		[$key + 224], %f20
-	ldd		[$key + 232], %f22
-___
-for ($i=1; $i<6; $i++) {
-    $code.=<<___;
-	aes_eround01	%f`16+8*$i+0`, %f0, %f2, %f4
-	aes_eround23	%f`16+8*$i+2`, %f0, %f2, %f2
-	aes_eround01	%f`16+8*$i+4`, %f4, %f2, %f0
-	aes_eround23	%f`16+8*$i+6`, %f4, %f2, %f2
-___
-}
-$code.=<<___;
-	aes_eround01	%f16, %f0, %f2, %f4
-	aes_eround23	%f18, %f0, %f2, %f2
-	ldd		[$key + 16], %f16
-	ldd		[$key + 24], %f18
-	aes_eround01_l	%f20, %f4, %f2, %f0
-	aes_eround23_l	%f22, %f4, %f2, %f2
-	ldd		[$key + 32], %f20
-	retl
-	ldd		[$key + 40], %f22
-.type	_aes256_encrypt_1x,#function
-.size	_aes256_encrypt_1x,.-_aes256_encrypt_1x
-
-.align	32
-_aes256_encrypt_2x:
-	aes_eround01	%f16, %f0, %f2, %f8
-	aes_eround23	%f18, %f0, %f2, %f2
-	aes_eround01	%f16, %f4, %f6, %f10
-	aes_eround23	%f18, %f4, %f6, %f6
-	ldd		[$key + 208], %f16
-	ldd		[$key + 216], %f18
-	aes_eround01	%f20, %f8, %f2, %f0
-	aes_eround23	%f22, %f8, %f2, %f2
-	aes_eround01	%f20, %f10, %f6, %f4
-	aes_eround23	%f22, %f10, %f6, %f6
-	ldd		[$key + 224], %f20
-	ldd		[$key + 232], %f22
-___
-for ($i=1; $i<6; $i++) {
-    $code.=<<___;
-	aes_eround01	%f`16+8*$i+0`, %f0, %f2, %f8
-	aes_eround23	%f`16+8*$i+2`, %f0, %f2, %f2
-	aes_eround01	%f`16+8*$i+0`, %f4, %f6, %f10
-	aes_eround23	%f`16+8*$i+2`, %f4, %f6, %f6
-	aes_eround01	%f`16+8*$i+4`, %f8, %f2, %f0
-	aes_eround23	%f`16+8*$i+6`, %f8, %f2, %f2
-	aes_eround01	%f`16+8*$i+4`, %f10, %f6, %f4
-	aes_eround23	%f`16+8*$i+6`, %f10, %f6, %f6
-___
-}
-$code.=<<___;
-	aes_eround01	%f16, %f0, %f2, %f8
-	aes_eround23	%f18, %f0, %f2, %f2
-	aes_eround01	%f16, %f4, %f6, %f10
-	aes_eround23	%f18, %f4, %f6, %f6
-	ldd		[$key + 16], %f16
-	ldd		[$key + 24], %f18
-	aes_eround01_l	%f20, %f8, %f2, %f0
-	aes_eround23_l	%f22, %f8, %f2, %f2
-	aes_eround01_l	%f20, %f10, %f6, %f4
-	aes_eround23_l	%f22, %f10, %f6, %f6
-	ldd		[$key + 32], %f20
-	retl
-	ldd		[$key + 40], %f22
-.type	_aes256_encrypt_2x,#function
-.size	_aes256_encrypt_2x,.-_aes256_encrypt_2x
-
-.align	32
-_aes256_decrypt_1x:
-	aes_dround01	%f16, %f0, %f2, %f4
-	aes_dround23	%f18, %f0, %f2, %f2
-	ldd		[$key + 208], %f16
-	ldd		[$key + 216], %f18
-	aes_dround01	%f20, %f4, %f2, %f0
-	aes_dround23	%f22, %f4, %f2, %f2
-	ldd		[$key + 224], %f20
-	ldd		[$key + 232], %f22
-___
-for ($i=1; $i<6; $i++) {
-    $code.=<<___;
-	aes_dround01	%f`16+8*$i+0`, %f0, %f2, %f4
-	aes_dround23	%f`16+8*$i+2`, %f0, %f2, %f2
-	aes_dround01	%f`16+8*$i+4`, %f4, %f2, %f0
-	aes_dround23	%f`16+8*$i+6`, %f4, %f2, %f2
-___
-}
-$code.=<<___;
-	aes_dround01	%f16, %f0, %f2, %f4
-	aes_dround23	%f18, %f0, %f2, %f2
-	ldd		[$key + 16], %f16
-	ldd		[$key + 24], %f18
-	aes_dround01_l	%f20, %f4, %f2, %f0
-	aes_dround23_l	%f22, %f4, %f2, %f2
-	ldd		[$key + 32], %f20
-	retl
-	ldd		[$key + 40], %f22
-.type	_aes256_decrypt_1x,#function
-.size	_aes256_decrypt_1x,.-_aes256_decrypt_1x
-
-.align	32
-_aes256_decrypt_2x:
-	aes_dround01	%f16, %f0, %f2, %f8
-	aes_dround23	%f18, %f0, %f2, %f2
-	aes_dround01	%f16, %f4, %f6, %f10
-	aes_dround23	%f18, %f4, %f6, %f6
-	ldd		[$key + 208], %f16
-	ldd		[$key + 216], %f18
-	aes_dround01	%f20, %f8, %f2, %f0
-	aes_dround23	%f22, %f8, %f2, %f2
-	aes_dround01	%f20, %f10, %f6, %f4
-	aes_dround23	%f22, %f10, %f6, %f6
-	ldd		[$key + 224], %f20
-	ldd		[$key + 232], %f22
-___
-for ($i=1; $i<6; $i++) {
-    $code.=<<___;
-	aes_dround01	%f`16+8*$i+0`, %f0, %f2, %f8
-	aes_dround23	%f`16+8*$i+2`, %f0, %f2, %f2
-	aes_dround01	%f`16+8*$i+0`, %f4, %f6, %f10
-	aes_dround23	%f`16+8*$i+2`, %f4, %f6, %f6
-	aes_dround01	%f`16+8*$i+4`, %f8, %f2, %f0
-	aes_dround23	%f`16+8*$i+6`, %f8, %f2, %f2
-	aes_dround01	%f`16+8*$i+4`, %f10, %f6, %f4
-	aes_dround23	%f`16+8*$i+6`, %f10, %f6, %f6
-___
-}
-$code.=<<___;
-	aes_dround01	%f16, %f0, %f2, %f8
-	aes_dround23	%f18, %f0, %f2, %f2
-	aes_dround01	%f16, %f4, %f6, %f10
-	aes_dround23	%f18, %f4, %f6, %f6
-	ldd		[$key + 16], %f16
-	ldd		[$key + 24], %f18
-	aes_dround01_l	%f20, %f8, %f2, %f0
-	aes_dround23_l	%f22, %f8, %f2, %f2
-	aes_dround01_l	%f20, %f10, %f6, %f4
-	aes_dround23_l	%f22, %f10, %f6, %f6
-	ldd		[$key + 32], %f20
-	retl
-	ldd		[$key + 40], %f22
-.type	_aes256_decrypt_2x,#function
-.size	_aes256_decrypt_2x,.-_aes256_decrypt_2x
-___
-
-&alg_cbc_encrypt_implement("aes",128);
-&alg_cbc_encrypt_implement("aes",192);
-&alg_cbc_encrypt_implement("aes",256);
-
-&alg_cbc_decrypt_implement("aes",128);
-&alg_cbc_decrypt_implement("aes",192);
-&alg_cbc_decrypt_implement("aes",256);
-
-if ($::evp) {
-    &alg_ctr32_implement("aes",128);
-    &alg_ctr32_implement("aes",192);
-    &alg_ctr32_implement("aes",256);
-}
-}}}
-
-if (!$::evp) {
-$code.=<<___;
-.global	AES_encrypt
-AES_encrypt=aes_t4_encrypt
-.global	AES_decrypt
-AES_decrypt=aes_t4_decrypt
-.global	AES_set_encrypt_key
-.align	32
-AES_set_encrypt_key:
-	andcc		%o2, 7, %g0		! check alignment
-	bnz,a,pn	%icc, 1f
-	mov		-1, %o0
-	brz,a,pn	%o0, 1f
-	mov		-1, %o0
-	brz,a,pn	%o2, 1f
-	mov		-1, %o0
-	andncc		%o1, 0x1c0, %g0
-	bnz,a,pn	%icc, 1f
-	mov		-2, %o0
-	cmp		%o1, 128
-	bl,a,pn		%icc, 1f
-	mov		-2, %o0
-	b		aes_t4_set_encrypt_key
-	nop
-1:	retl
-	nop
-.type	AES_set_encrypt_key,#function
-.size	AES_set_encrypt_key,.-AES_set_encrypt_key
-
-.global	AES_set_decrypt_key
-.align	32
-AES_set_decrypt_key:
-	andcc		%o2, 7, %g0		! check alignment
-	bnz,a,pn	%icc, 1f
-	mov		-1, %o0
-	brz,a,pn	%o0, 1f
-	mov		-1, %o0
-	brz,a,pn	%o2, 1f
-	mov		-1, %o0
-	andncc		%o1, 0x1c0, %g0
-	bnz,a,pn	%icc, 1f
-	mov		-2, %o0
-	cmp		%o1, 128
-	bl,a,pn		%icc, 1f
-	mov		-2, %o0
-	b		aes_t4_set_decrypt_key
-	nop
-1:	retl
-	nop
-.type	AES_set_decrypt_key,#function
-.size	AES_set_decrypt_key,.-AES_set_decrypt_key
-___
-
-my ($inp,$out,$len,$key,$ivec,$enc)=map("%o$_",(0..5));
-
-$code.=<<___;
-.globl	AES_cbc_encrypt
-.align	32
-AES_cbc_encrypt:
-	ld		[$key + 240], %g1
-	nop
-	brz		$enc, .Lcbc_decrypt
-	cmp		%g1, 12
-
-	bl,pt		%icc, aes128_t4_cbc_encrypt
-	nop
-	be,pn		%icc, aes192_t4_cbc_encrypt
-	nop
-	ba		aes256_t4_cbc_encrypt
-	nop
-
-.Lcbc_decrypt:
-	bl,pt		%icc, aes128_t4_cbc_decrypt
-	nop
-	be,pn		%icc, aes192_t4_cbc_decrypt
-	nop
-	ba		aes256_t4_cbc_decrypt
-	nop
-.type	AES_cbc_encrypt,#function
-.size	AES_cbc_encrypt,.-AES_cbc_encrypt
-___
-}
-$code.=<<___;
-.asciz	"AES for SPARC T4, David S. Miller, Andy Polyakov"
-.align	4
-___
-
-&emit_assembler();
-
-close STDOUT;
--- a/components/openssl/openssl-1.0.1/inline-t4/dest4-sparcv9.pl	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,617 +0,0 @@
-#!/usr/bin/env perl
-
-# ====================================================================
-# Written by David S. Miller <[email protected]> and Andy Polyakov
-# <[email protected]>. The module is licensed under 2-clause BSD
-# license. March 2013. All rights reserved.
-# ====================================================================
-
-######################################################################
-# DES for SPARC T4.
-#
-# As with other hardware-assisted ciphers CBC encrypt results [for
-# aligned data] are virtually identical to critical path lengths:
-#
-#		DES		Triple-DES
-# CBC encrypt	4.14/4.15(*)	11.7/11.7
-# CBC decrypt	1.77/4.11(**)	6.42/7.47
-#
-#			 (*)	numbers after slash are for
-#				misaligned data;
-#			 (**)	this is result for largest
-#				block size, unlike all other
-#				cases smaller blocks results
-#				are better[?];
-
-$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-push(@INC,"${dir}","${dir}../../perlasm");
-require "sparcv9_modes.pl";
-
-&asm_init(@ARGV);
-
-$code.=<<___ if ($::abibits==64);
-.register       %g2,#scratch
-.register       %g3,#scratch
-___
-
-$code.=<<___;
-.text
-___
-
-{ my ($inp,$out)=("%o0","%o1");
-
-$code.=<<___;
-.align	32
-.globl	des_t4_key_expand
-.type	des_t4_key_expand,#function
-des_t4_key_expand:
-	andcc		$inp, 0x7, %g0
-	alignaddr	$inp, %g0, $inp
-	bz,pt		%icc, 1f
-	ldd		[$inp + 0x00], %f0
-	ldd		[$inp + 0x08], %f2
-	faligndata	%f0, %f2, %f0
-1:	des_kexpand	%f0, 0, %f0
-	des_kexpand	%f0, 1, %f2
-	std		%f0, [$out + 0x00]
-	des_kexpand	%f2, 3, %f6
-	std		%f2, [$out + 0x08]
-	des_kexpand	%f2, 2, %f4
-	des_kexpand	%f6, 3, %f10
-	std		%f6, [$out + 0x18]
-	des_kexpand	%f6, 2, %f8
-	std		%f4, [$out + 0x10]
-	des_kexpand	%f10, 3, %f14
-	std		%f10, [$out + 0x28]
-	des_kexpand	%f10, 2, %f12
-	std		%f8, [$out + 0x20]
-	des_kexpand	%f14, 1, %f16
-	std		%f14, [$out + 0x38]
-	des_kexpand	%f16, 3, %f20
-	std		%f12, [$out + 0x30]
-	des_kexpand	%f16, 2, %f18
-	std		%f16, [$out + 0x40]
-	des_kexpand	%f20, 3, %f24
-	std		%f20, [$out + 0x50]
-	des_kexpand	%f20, 2, %f22
-	std		%f18, [$out + 0x48]
-	des_kexpand	%f24, 3, %f28
-	std		%f24, [$out + 0x60]
-	des_kexpand	%f24, 2, %f26
-	std		%f22, [$out + 0x58]
-	des_kexpand	%f28, 1, %f30
-	std		%f28, [$out + 0x70]
-	std		%f26, [$out + 0x68]
-	retl
-	std		%f30, [$out + 0x78]
-.size	des_t4_key_expand,.-des_t4_key_expand
-___
-}
-{ my ($inp,$out,$len,$key,$ivec) = map("%o$_",(0..4));
-  my ($ileft,$iright,$omask) = map("%g$_",(1..3));
-
-$code.=<<___;
-.globl	des_t4_cbc_encrypt
-.align	32
-des_t4_cbc_encrypt:
-	cmp		$len, 0
-	be,pn		$::size_t_cc, .Lcbc_abort
-	nop
-	ld		[$ivec + 0], %f0	! load ivec
-	ld		[$ivec + 4], %f1
-
-	and		$inp, 7, $ileft
-	andn		$inp, 7, $inp
-	sll		$ileft, 3, $ileft
-	mov		0xff, $omask
-	prefetch	[$inp], 20
-	prefetch	[$inp + 63], 20
-	sub		%g0, $ileft, $iright
-	and		$out, 7, %g4
-	alignaddrl	$out, %g0, $out
-	srl		$omask, %g4, $omask
-	srlx		$len, 3, $len
-	movrz		%g4, 0, $omask
-	prefetch	[$out], 22
-
-	ldd		[$key + 0x00], %f4	! load key schedule
-	ldd		[$key + 0x08], %f6
-	ldd		[$key + 0x10], %f8
-	ldd		[$key + 0x18], %f10
-	ldd		[$key + 0x20], %f12
-	ldd		[$key + 0x28], %f14
-	ldd		[$key + 0x30], %f16
-	ldd		[$key + 0x38], %f18
-	ldd		[$key + 0x40], %f20
-	ldd		[$key + 0x48], %f22
-	ldd		[$key + 0x50], %f24
-	ldd		[$key + 0x58], %f26
-	ldd		[$key + 0x60], %f28
-	ldd		[$key + 0x68], %f30
-	ldd		[$key + 0x70], %f32
-	ldd		[$key + 0x78], %f34
-
-.Ldes_cbc_enc_loop:
-	ldx		[$inp + 0], %g4
-	brz,pt		$ileft, 4f
-	nop
-
-	ldx		[$inp + 8], %g5
-	sllx		%g4, $ileft, %g4
-	srlx		%g5, $iright, %g5
-	or		%g5, %g4, %g4
-4:
-	movxtod		%g4, %f2
-	prefetch	[$inp + 8+63], 20
-	add		$inp, 8, $inp
-	fxor		%f2, %f0, %f0		! ^= ivec
-	prefetch	[$out + 63], 22
-
-	des_ip		%f0, %f0
-	des_round	%f4, %f6, %f0, %f0
-	des_round	%f8, %f10, %f0, %f0
-	des_round	%f12, %f14, %f0, %f0
-	des_round	%f16, %f18, %f0, %f0
-	des_round	%f20, %f22, %f0, %f0
-	des_round	%f24, %f26, %f0, %f0
-	des_round	%f28, %f30, %f0, %f0
-	des_round	%f32, %f34, %f0, %f0
-	des_iip		%f0, %f0
-
-	brnz,pn		$omask, 2f
-	sub		$len, 1, $len
-
-	std		%f0, [$out + 0]
-	brnz,pt		$len, .Ldes_cbc_enc_loop
-	add		$out, 8, $out
-
-	st		%f0, [$ivec + 0]	! write out ivec
-	retl
-	st		%f1, [$ivec + 4]
-.Lcbc_abort:
-	retl
-	nop
-
-.align	16
-2:	ldxa		[$inp]0x82, %g4		! avoid read-after-write hazard
-						! and ~4x deterioration
-						! in inp==out case
-	faligndata	%f0, %f0, %f2		! handle unaligned output
-
-	stda		%f2, [$out + $omask]0xc0	! partial store
-	add		$out, 8, $out
-	orn		%g0, $omask, $omask
-	stda		%f2, [$out + $omask]0xc0	! partial store
-
-	brnz,pt		$len, .Ldes_cbc_enc_loop+4
-	orn		%g0, $omask, $omask
-
-	st		%f0, [$ivec + 0]	! write out ivec
-	retl
-	st		%f1, [$ivec + 4]
-.type	des_t4_cbc_encrypt,#function
-.size	des_t4_cbc_encrypt,.-des_t4_cbc_encrypt
-
-.globl	des_t4_cbc_decrypt
-.align	32
-des_t4_cbc_decrypt:
-	cmp		$len, 0
-	be,pn		$::size_t_cc, .Lcbc_abort
-	nop
-	ld		[$ivec + 0], %f2	! load ivec
-	ld		[$ivec + 4], %f3
-
-	and		$inp, 7, $ileft
-	andn		$inp, 7, $inp
-	sll		$ileft, 3, $ileft
-	mov		0xff, $omask
-	prefetch	[$inp], 20
-	prefetch	[$inp + 63], 20
-	sub		%g0, $ileft, $iright
-	and		$out, 7, %g4
-	alignaddrl	$out, %g0, $out
-	srl		$omask, %g4, $omask
-	srlx		$len, 3, $len
-	movrz		%g4, 0, $omask
-	prefetch	[$out], 22
-
-	ldd		[$key + 0x78], %f4	! load key schedule
-	ldd		[$key + 0x70], %f6
-	ldd		[$key + 0x68], %f8
-	ldd		[$key + 0x60], %f10
-	ldd		[$key + 0x58], %f12
-	ldd		[$key + 0x50], %f14
-	ldd		[$key + 0x48], %f16
-	ldd		[$key + 0x40], %f18
-	ldd		[$key + 0x38], %f20
-	ldd		[$key + 0x30], %f22
-	ldd		[$key + 0x28], %f24
-	ldd		[$key + 0x20], %f26
-	ldd		[$key + 0x18], %f28
-	ldd		[$key + 0x10], %f30
-	ldd		[$key + 0x08], %f32
-	ldd		[$key + 0x00], %f34
-
-.Ldes_cbc_dec_loop:
-	ldx		[$inp + 0], %g4
-	brz,pt		$ileft, 4f
-	nop
-
-	ldx		[$inp + 8], %g5
-	sllx		%g4, $ileft, %g4
-	srlx		%g5, $iright, %g5
-	or		%g5, %g4, %g4
-4:
-	movxtod		%g4, %f0
-	prefetch	[$inp + 8+63], 20
-	add		$inp, 8, $inp
-	prefetch	[$out + 63], 22
-
-	des_ip		%f0, %f0
-	des_round	%f4, %f6, %f0, %f0
-	des_round	%f8, %f10, %f0, %f0
-	des_round	%f12, %f14, %f0, %f0
-	des_round	%f16, %f18, %f0, %f0
-	des_round	%f20, %f22, %f0, %f0
-	des_round	%f24, %f26, %f0, %f0
-	des_round	%f28, %f30, %f0, %f0
-	des_round	%f32, %f34, %f0, %f0
-	des_iip		%f0, %f0
-
-	fxor		%f2, %f0, %f0		! ^= ivec
-	movxtod		%g4, %f2
-
-	brnz,pn		$omask, 2f
-	sub		$len, 1, $len
-
-	std		%f0, [$out + 0]
-	brnz,pt		$len, .Ldes_cbc_dec_loop
-	add		$out, 8, $out
-
-	st		%f2, [$ivec + 0]	! write out ivec
-	retl
-	st		%f3, [$ivec + 4]
-
-.align	16
-2:	ldxa		[$inp]0x82, %g4		! avoid read-after-write hazard
-						! and ~4x deterioration
-						! in inp==out case
-	faligndata	%f0, %f0, %f0		! handle unaligned output
-
-	stda		%f0, [$out + $omask]0xc0	! partial store
-	add		$out, 8, $out
-	orn		%g0, $omask, $omask
-	stda		%f0, [$out + $omask]0xc0	! partial store
-
-	brnz,pt		$len, .Ldes_cbc_dec_loop+4
-	orn		%g0, $omask, $omask
-
-	st		%f2, [$ivec + 0]	! write out ivec
-	retl
-	st		%f3, [$ivec + 4]
-.type	des_t4_cbc_decrypt,#function
-.size	des_t4_cbc_decrypt,.-des_t4_cbc_decrypt
-___
-
-# One might wonder why does one have back-to-back des_iip/des_ip
-# pairs between EDE passes. Indeed, aren't they inverse of each other?
-# They almost are. Outcome of the pair is 32-bit words being swapped
-# in target register. Consider pair of des_iip/des_ip as a way to
-# perform the due swap, it's actually fastest way in this case.
-
-$code.=<<___;
-.globl	des_t4_ede3_cbc_encrypt
-.align	32
-des_t4_ede3_cbc_encrypt:
-	cmp		$len, 0
-	be,pn		$::size_t_cc, .Lcbc_abort
-	nop
-	ld		[$ivec + 0], %f0	! load ivec
-	ld		[$ivec + 4], %f1
-
-	and		$inp, 7, $ileft
-	andn		$inp, 7, $inp
-	sll		$ileft, 3, $ileft
-	mov		0xff, $omask
-	prefetch	[$inp], 20
-	prefetch	[$inp + 63], 20
-	sub		%g0, $ileft, $iright
-	and		$out, 7, %g4
-	alignaddrl	$out, %g0, $out
-	srl		$omask, %g4, $omask
-	srlx		$len, 3, $len
-	movrz		%g4, 0, $omask
-	prefetch	[$out], 22
-
-	ldd		[$key + 0x00], %f4	! load key schedule
-	ldd		[$key + 0x08], %f6
-	ldd		[$key + 0x10], %f8
-	ldd		[$key + 0x18], %f10
-	ldd		[$key + 0x20], %f12
-	ldd		[$key + 0x28], %f14
-	ldd		[$key + 0x30], %f16
-	ldd		[$key + 0x38], %f18
-	ldd		[$key + 0x40], %f20
-	ldd		[$key + 0x48], %f22
-	ldd		[$key + 0x50], %f24
-	ldd		[$key + 0x58], %f26
-	ldd		[$key + 0x60], %f28
-	ldd		[$key + 0x68], %f30
-	ldd		[$key + 0x70], %f32
-	ldd		[$key + 0x78], %f34
-
-.Ldes_ede3_cbc_enc_loop:
-	ldx		[$inp + 0], %g4
-	brz,pt		$ileft, 4f
-	nop
-
-	ldx		[$inp + 8], %g5
-	sllx		%g4, $ileft, %g4
-	srlx		%g5, $iright, %g5
-	or		%g5, %g4, %g4
-4:
-	movxtod		%g4, %f2
-	prefetch	[$inp + 8+63], 20
-	add		$inp, 8, $inp
-	fxor		%f2, %f0, %f0		! ^= ivec
-	prefetch	[$out + 63], 22
-
-	des_ip		%f0, %f0
-	des_round	%f4, %f6, %f0, %f0
-	des_round	%f8, %f10, %f0, %f0
-	des_round	%f12, %f14, %f0, %f0
-	des_round	%f16, %f18, %f0, %f0
-	ldd		[$key + 0x100-0x08], %f36
-	ldd		[$key + 0x100-0x10], %f38
-	des_round	%f20, %f22, %f0, %f0
-	ldd		[$key + 0x100-0x18], %f40
-	ldd		[$key + 0x100-0x20], %f42
-	des_round	%f24, %f26, %f0, %f0
-	ldd		[$key + 0x100-0x28], %f44
-	ldd		[$key + 0x100-0x30], %f46
-	des_round	%f28, %f30, %f0, %f0
-	ldd		[$key + 0x100-0x38], %f48
-	ldd		[$key + 0x100-0x40], %f50
-	des_round	%f32, %f34, %f0, %f0
-	ldd		[$key + 0x100-0x48], %f52
-	ldd		[$key + 0x100-0x50], %f54
-	des_iip		%f0, %f0
-
-	ldd		[$key + 0x100-0x58], %f56
-	ldd		[$key + 0x100-0x60], %f58
-	des_ip		%f0, %f0
-	ldd		[$key + 0x100-0x68], %f60
-	ldd		[$key + 0x100-0x70], %f62
-	des_round	%f36, %f38, %f0, %f0
-	ldd		[$key + 0x100-0x78], %f36
-	ldd		[$key + 0x100-0x80], %f38
-	des_round	%f40, %f42, %f0, %f0
-	des_round	%f44, %f46, %f0, %f0
-	des_round	%f48, %f50, %f0, %f0
-	ldd		[$key + 0x100+0x00], %f40
-	ldd		[$key + 0x100+0x08], %f42
-	des_round	%f52, %f54, %f0, %f0
-	ldd		[$key + 0x100+0x10], %f44
-	ldd		[$key + 0x100+0x18], %f46
-	des_round	%f56, %f58, %f0, %f0
-	ldd		[$key + 0x100+0x20], %f48
-	ldd		[$key + 0x100+0x28], %f50
-	des_round	%f60, %f62, %f0, %f0
-	ldd		[$key + 0x100+0x30], %f52
-	ldd		[$key + 0x100+0x38], %f54
-	des_round	%f36, %f38, %f0, %f0
-	ldd		[$key + 0x100+0x40], %f56
-	ldd		[$key + 0x100+0x48], %f58
-	des_iip		%f0, %f0
-
-	ldd		[$key + 0x100+0x50], %f60
-	ldd		[$key + 0x100+0x58], %f62
-	des_ip		%f0, %f0
-	ldd		[$key + 0x100+0x60], %f36
-	ldd		[$key + 0x100+0x68], %f38
-	des_round	%f40, %f42, %f0, %f0
-	ldd		[$key + 0x100+0x70], %f40
-	ldd		[$key + 0x100+0x78], %f42
-	des_round	%f44, %f46, %f0, %f0
-	des_round	%f48, %f50, %f0, %f0
-	des_round	%f52, %f54, %f0, %f0
-	des_round	%f56, %f58, %f0, %f0
-	des_round	%f60, %f62, %f0, %f0
-	des_round	%f36, %f38, %f0, %f0
-	des_round	%f40, %f42, %f0, %f0
-	des_iip		%f0, %f0
-
-	brnz,pn		$omask, 2f
-	sub		$len, 1, $len
-
-	std		%f0, [$out + 0]
-	brnz,pt		$len, .Ldes_ede3_cbc_enc_loop
-	add		$out, 8, $out
-
-	st		%f0, [$ivec + 0]	! write out ivec
-	retl
-	st		%f1, [$ivec + 4]
-
-.align	16
-2:	ldxa		[$inp]0x82, %g4		! avoid read-after-write hazard
-						! and ~2x deterioration
-						! in inp==out case
-	faligndata	%f0, %f0, %f2		! handle unaligned output
-
-	stda		%f2, [$out + $omask]0xc0	! partial store
-	add		$out, 8, $out
-	orn		%g0, $omask, $omask
-	stda		%f2, [$out + $omask]0xc0	! partial store
-
-	brnz,pt		$len, .Ldes_ede3_cbc_enc_loop+4
-	orn		%g0, $omask, $omask
-
-	st		%f0, [$ivec + 0]	! write out ivec
-	retl
-	st		%f1, [$ivec + 4]
-.type	des_t4_ede3_cbc_encrypt,#function
-.size	des_t4_ede3_cbc_encrypt,.-des_t4_ede3_cbc_encrypt
-
-.globl	des_t4_ede3_cbc_decrypt
-.align	32
-des_t4_ede3_cbc_decrypt:
-	cmp		$len, 0
-	be,pn		$::size_t_cc, .Lcbc_abort
-	nop
-	ld		[$ivec + 0], %f2	! load ivec
-	ld		[$ivec + 4], %f3
-
-	and		$inp, 7, $ileft
-	andn		$inp, 7, $inp
-	sll		$ileft, 3, $ileft
-	mov		0xff, $omask
-	prefetch	[$inp], 20
-	prefetch	[$inp + 63], 20
-	sub		%g0, $ileft, $iright
-	and		$out, 7, %g4
-	alignaddrl	$out, %g0, $out
-	srl		$omask, %g4, $omask
-	srlx		$len, 3, $len
-	movrz		%g4, 0, $omask
-	prefetch	[$out], 22
-
-	ldd		[$key + 0x100+0x78], %f4	! load key schedule
-	ldd		[$key + 0x100+0x70], %f6
-	ldd		[$key + 0x100+0x68], %f8
-	ldd		[$key + 0x100+0x60], %f10
-	ldd		[$key + 0x100+0x58], %f12
-	ldd		[$key + 0x100+0x50], %f14
-	ldd		[$key + 0x100+0x48], %f16
-	ldd		[$key + 0x100+0x40], %f18
-	ldd		[$key + 0x100+0x38], %f20
-	ldd		[$key + 0x100+0x30], %f22
-	ldd		[$key + 0x100+0x28], %f24
-	ldd		[$key + 0x100+0x20], %f26
-	ldd		[$key + 0x100+0x18], %f28
-	ldd		[$key + 0x100+0x10], %f30
-	ldd		[$key + 0x100+0x08], %f32
-	ldd		[$key + 0x100+0x00], %f34
-
-.Ldes_ede3_cbc_dec_loop:
-	ldx		[$inp + 0], %g4
-	brz,pt		$ileft, 4f
-	nop
-
-	ldx		[$inp + 8], %g5
-	sllx		%g4, $ileft, %g4
-	srlx		%g5, $iright, %g5
-	or		%g5, %g4, %g4
-4:
-	movxtod		%g4, %f0
-	prefetch	[$inp + 8+63], 20
-	add		$inp, 8, $inp
-	prefetch	[$out + 63], 22
-
-	des_ip		%f0, %f0
-	des_round	%f4, %f6, %f0, %f0
-	des_round	%f8, %f10, %f0, %f0
-	des_round	%f12, %f14, %f0, %f0
-	des_round	%f16, %f18, %f0, %f0
-	ldd		[$key + 0x80+0x00], %f36
-	ldd		[$key + 0x80+0x08], %f38
-	des_round	%f20, %f22, %f0, %f0
-	ldd		[$key + 0x80+0x10], %f40
-	ldd		[$key + 0x80+0x18], %f42
-	des_round	%f24, %f26, %f0, %f0
-	ldd		[$key + 0x80+0x20], %f44
-	ldd		[$key + 0x80+0x28], %f46
-	des_round	%f28, %f30, %f0, %f0
-	ldd		[$key + 0x80+0x30], %f48
-	ldd		[$key + 0x80+0x38], %f50
-	des_round	%f32, %f34, %f0, %f0
-	ldd		[$key + 0x80+0x40], %f52
-	ldd		[$key + 0x80+0x48], %f54
-	des_iip		%f0, %f0
-
-	ldd		[$key + 0x80+0x50], %f56
-	ldd		[$key + 0x80+0x58], %f58
-	des_ip		%f0, %f0
-	ldd		[$key + 0x80+0x60], %f60
-	ldd		[$key + 0x80+0x68], %f62
-	des_round	%f36, %f38, %f0, %f0
-	ldd		[$key + 0x80+0x70], %f36
-	ldd		[$key + 0x80+0x78], %f38
-	des_round	%f40, %f42, %f0, %f0
-	des_round	%f44, %f46, %f0, %f0
-	des_round	%f48, %f50, %f0, %f0
-	ldd		[$key + 0x80-0x08], %f40
-	ldd		[$key + 0x80-0x10], %f42
-	des_round	%f52, %f54, %f0, %f0
-	ldd		[$key + 0x80-0x18], %f44
-	ldd		[$key + 0x80-0x20], %f46
-	des_round	%f56, %f58, %f0, %f0
-	ldd		[$key + 0x80-0x28], %f48
-	ldd		[$key + 0x80-0x30], %f50
-	des_round	%f60, %f62, %f0, %f0
-	ldd		[$key + 0x80-0x38], %f52
-	ldd		[$key + 0x80-0x40], %f54
-	des_round	%f36, %f38, %f0, %f0
-	ldd		[$key + 0x80-0x48], %f56
-	ldd		[$key + 0x80-0x50], %f58
-	des_iip		%f0, %f0
-
-	ldd		[$key + 0x80-0x58], %f60
-	ldd		[$key + 0x80-0x60], %f62
-	des_ip		%f0, %f0
-	ldd		[$key + 0x80-0x68], %f36
-	ldd		[$key + 0x80-0x70], %f38
-	des_round	%f40, %f42, %f0, %f0
-	ldd		[$key + 0x80-0x78], %f40
-	ldd		[$key + 0x80-0x80], %f42
-	des_round	%f44, %f46, %f0, %f0
-	des_round	%f48, %f50, %f0, %f0
-	des_round	%f52, %f54, %f0, %f0
-	des_round	%f56, %f58, %f0, %f0
-	des_round	%f60, %f62, %f0, %f0
-	des_round	%f36, %f38, %f0, %f0
-	des_round	%f40, %f42, %f0, %f0
-	des_iip		%f0, %f0
-
-	fxor		%f2, %f0, %f0		! ^= ivec
-	movxtod		%g4, %f2
-
-	brnz,pn		$omask, 2f
-	sub		$len, 1, $len
-
-	std		%f0, [$out + 0]
-	brnz,pt		$len, .Ldes_ede3_cbc_dec_loop
-	add		$out, 8, $out
-
-	st		%f2, [$ivec + 0]	! write out ivec
-	retl
-	st		%f3, [$ivec + 4]
-
-.align	16
-2:	ldxa		[$inp]0x82, %g4		! avoid read-after-write hazard
-						! and ~3x deterioration
-						! in inp==out case
-	faligndata	%f0, %f0, %f0		! handle unaligned output
-
-	stda		%f0, [$out + $omask]0xc0	! partial store
-	add		$out, 8, $out
-	orn		%g0, $omask, $omask
-	stda		%f0, [$out + $omask]0xc0	! partial store
-
-	brnz,pt		$len, .Ldes_ede3_cbc_dec_loop+4
-	orn		%g0, $omask, $omask
-
-	st		%f2, [$ivec + 0]	! write out ivec
-	retl
-	st		%f3, [$ivec + 4]
-.type	des_t4_ede3_cbc_decrypt,#function
-.size	des_t4_ede3_cbc_decrypt,.-des_t4_ede3_cbc_decrypt
-___
-}
-$code.=<<___;
-.asciz  "DES for SPARC T4, David S. Miller, Andy Polyakov"
-.align  4
-___
-
-&emit_assembler();
-
-close STDOUT;
--- a/components/openssl/openssl-1.0.1/inline-t4/md5-sparcv9.pl	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,434 +0,0 @@
-#!/usr/bin/env perl
-
-# ====================================================================
-# Written by Andy Polyakov <[email protected]> for the OpenSSL
-# project. The module is, however, dual licensed under OpenSSL and
-# CRYPTOGAMS licenses depending on where you obtain it. For further
-# details see http://www.openssl.org/~appro/cryptogams/.
-#
-# Hardware SPARC T4 support by David S. Miller <[email protected]>.
-# ====================================================================
-
-# MD5 for SPARCv9, 6.9 cycles per byte on UltraSPARC, >40% faster than
-# code generated by Sun C 5.2.
-
-# SPARC T4 MD5 hardware achieves 3.20 cycles per byte, which is 2.1x
-# faster than software. Multi-process benchmark saturates at 12x
-# single-process result on 8-core processor, or ~11GBps per 2.85GHz
-# socket.
-
-$bits=32;
-for (@ARGV)	{ $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
-if ($bits==64)	{ $bias=2047; $frame=192; }
-else		{ $bias=0;    $frame=112; }
-
-$output=shift;
-open STDOUT,">$output";
-
-use integer;
-
-($ctx,$inp,$len)=("%i0","%i1","%i2");	# input arguments
-
-# 64-bit values
-@X=("%o0","%o1","%o2","%o3","%o4","%o5","%o7","%g1","%g2");
-$tx="%g3";
-($AB,$CD)=("%g4","%g5");
-
-# 32-bit values
-@V=($A,$B,$C,$D)=map("%l$_",(0..3));
-($t1,$t2,$t3,$saved_asi)=map("%l$_",(4..7));
-($shr,$shl1,$shl2)=("%i3","%i4","%i5");
-
-my @K=(	0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee,
-	0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501,
-	0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be,
-	0x6b901122,0xfd987193,0xa679438e,0x49b40821,
-
-	0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa,
-	0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8,
-	0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed,
-	0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a,
-
-	0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c,
-	0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70,
-	0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05,
-	0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665,
-
-	0xf4292244,0x432aff97,0xab9423a7,0xfc93a039,
-	0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1,
-	0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1,
-	0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391, 0	);
-
-sub R0 {
-  my ($i,$a,$b,$c,$d) = @_;
-  my $rot = (7,12,17,22)[$i%4];
-  my $j   = ($i+1)/2;
-
-  if ($i&1) {
-    $code.=<<___;
-	 srlx	@X[$j],$shr,@X[$j]	! align X[`$i+1`]
-	and	$b,$t1,$t1		! round $i
-	 sllx	@X[$j+1],$shl1,$tx
-	add	$t2,$a,$a
-	 sllx	$tx,$shl2,$tx
-	xor	$d,$t1,$t1
-	 or	$tx,@X[$j],@X[$j]
-	 sethi	%hi(@K[$i+1]),$t2
-	add	$t1,$a,$a
-	 or	$t2,%lo(@K[$i+1]),$t2
-	sll	$a,$rot,$t3
-	 add	@X[$j],$t2,$t2		! X[`$i+1`]+K[`$i+1`]
-	srl	$a,32-$rot,$a
-	add	$b,$t3,$t3
-	 xor	 $b,$c,$t1
-	add	$t3,$a,$a
-___
-  } else {
-    $code.=<<___;
-	 srlx	@X[$j],32,$tx		! extract X[`2*$j+1`]
-	and	$b,$t1,$t1		! round $i
-	add	$t2,$a,$a
-	xor	$d,$t1,$t1
-	 sethi	%hi(@K[$i+1]),$t2
-	add	$t1,$a,$a
-	 or	$t2,%lo(@K[$i+1]),$t2
-	sll	$a,$rot,$t3
-	 add	$tx,$t2,$t2		! X[`2*$j+1`]+K[`$i+1`]
-	srl	$a,32-$rot,$a
-	add	$b,$t3,$t3
-	 xor	 $b,$c,$t1
-	add	$t3,$a,$a
-___
-  }
-}
-
-sub R0_1 {
-  my ($i,$a,$b,$c,$d) = @_;
-  my $rot = (7,12,17,22)[$i%4];
-
-$code.=<<___;
-	 srlx	@X[0],32,$tx		! extract X[1]
-	and	$b,$t1,$t1		! round $i
-	add	$t2,$a,$a
-	xor	$d,$t1,$t1
-	 sethi	%hi(@K[$i+1]),$t2
-	add	$t1,$a,$a
-	 or	$t2,%lo(@K[$i+1]),$t2
-	sll	$a,$rot,$t3
-	 add	$tx,$t2,$t2		! X[1]+K[`$i+1`]
-	srl	$a,32-$rot,$a
-	add	$b,$t3,$t3
-	 andn	 $b,$c,$t1
-	add	$t3,$a,$a
-___
-}
-
-sub R1 {
-  my ($i,$a,$b,$c,$d) = @_;
-  my $rot = (5,9,14,20)[$i%4];
-  my $j   = $i<31 ? (1+5*($i+1))%16 : (5+3*($i+1))%16;
-  my $xi  = @X[$j/2];
-
-$code.=<<___ if ($j&1 && ($xi=$tx));
-	 srlx	@X[$j/2],32,$xi		! extract X[$j]
-___
-$code.=<<___;
-	and	$b,$d,$t3		! round $i
-	add	$t2,$a,$a
-	or	$t3,$t1,$t1
-	 sethi	%hi(@K[$i+1]),$t2
-	add	$t1,$a,$a
-	 or	$t2,%lo(@K[$i+1]),$t2
-	sll	$a,$rot,$t3
-	 add	$xi,$t2,$t2		! X[$j]+K[`$i+1`]
-	srl	$a,32-$rot,$a
-	add	$b,$t3,$t3
-	 `$i<31?"andn":"xor"`	 $b,$c,$t1
-	add	$t3,$a,$a
-___
-}
-
-sub R2 {
-  my ($i,$a,$b,$c,$d) = @_;
-  my $rot = (4,11,16,23)[$i%4];
-  my $j   = $i<47 ? (5+3*($i+1))%16 : (0+7*($i+1))%16;
-  my $xi  = @X[$j/2];
-
-$code.=<<___ if ($j&1 && ($xi=$tx));
-	 srlx	@X[$j/2],32,$xi		! extract X[$j]
-___
-$code.=<<___;
-	add	$t2,$a,$a		! round $i
-	xor	$b,$t1,$t1
-	 sethi	%hi(@K[$i+1]),$t2
-	add	$t1,$a,$a
-	 or	$t2,%lo(@K[$i+1]),$t2
-	sll	$a,$rot,$t3
-	 add	$xi,$t2,$t2		! X[$j]+K[`$i+1`]
-	srl	$a,32-$rot,$a
-	add	$b,$t3,$t3
-	 xor	 $b,$c,$t1
-	add	$t3,$a,$a
-___
-}
-
-sub R3 {
-  my ($i,$a,$b,$c,$d) = @_;
-  my $rot = (6,10,15,21)[$i%4];
-  my $j   = (0+7*($i+1))%16;
-  my $xi  = @X[$j/2];
-
-$code.=<<___;
-	add	$t2,$a,$a		! round $i
-___
-$code.=<<___ if ($j&1 && ($xi=$tx));
-	 srlx	@X[$j/2],32,$xi		! extract X[$j]
-___
-$code.=<<___;
-	orn	$b,$d,$t1
-	 sethi	%hi(@K[$i+1]),$t2
-	xor	$c,$t1,$t1
-	 or	$t2,%lo(@K[$i+1]),$t2
-	add	$t1,$a,$a
-	sll	$a,$rot,$t3
-	 add	$xi,$t2,$t2		! X[$j]+K[`$i+1`]
-	srl	$a,32-$rot,$a
-	add	$b,$t3,$t3
-	add	$t3,$a,$a
-___
-}
-
-$code.=<<___ if ($bits==64);
-.register	%g2,#scratch
-.register	%g3,#scratch
-___
-$code.=<<___;
-#include "sparc_arch.h"
-
-.section	".text",#alloc,#execinstr
-
-#ifdef __PIC__
-SPARC_PIC_THUNK(%g1)
-#endif
-
-.globl	md5_block_asm_data_order
-.align	32
-md5_block_asm_data_order:
-	SPARC_LOAD_ADDRESS_LEAF(OPENSSL_sparcv9cap_P,%g1,%g5)
-	ld	[%g1+4],%g1		! OPENSSL_sparcv9cap_P[1]
-
-	andcc	%g1, CFR_MD5, %g0
-	be	.Lsoftware
-	nop
-
-	mov	4, %g1
-	andcc	%o1, 0x7, %g0
-	lda	[%o0 + %g0]0x88, %f0		! load context
-	lda	[%o0 + %g1]0x88, %f1
-	add	%o0, 8, %o0
-	lda	[%o0 + %g0]0x88, %f2
-	lda	[%o0 + %g1]0x88, %f3
-	bne,pn	%icc, .Lhwunaligned
-	sub	%o0, 8, %o0
-
-.Lhw_loop:
-	ldd	[%o1 + 0x00], %f8
-	ldd	[%o1 + 0x08], %f10
-	ldd	[%o1 + 0x10], %f12
-	ldd	[%o1 + 0x18], %f14
-	ldd	[%o1 + 0x20], %f16
-	ldd	[%o1 + 0x28], %f18
-	ldd	[%o1 + 0x30], %f20
-	subcc	%o2, 1, %o2		! done yet? 
-	ldd	[%o1 + 0x38], %f22
-	add	%o1, 0x40, %o1
-	prefetch [%o1 + 63], 20
-
-	.word	0x81b02800		! MD5
-
-	bne,pt	`$bits==64?"%xcc":"%icc"`, .Lhw_loop
-	nop
-
-.Lhwfinish:
-	sta	%f0, [%o0 + %g0]0x88	! store context
-	sta	%f1, [%o0 + %g1]0x88
-	add	%o0, 8, %o0
-	sta	%f2, [%o0 + %g0]0x88
-	sta	%f3, [%o0 + %g1]0x88
-	retl
-	nop
-
-.align	8
-.Lhwunaligned:
-	alignaddr %o1, %g0, %o1
-
-	ldd	[%o1 + 0x00], %f10
-.Lhwunaligned_loop:
-	ldd	[%o1 + 0x08], %f12
-	ldd	[%o1 + 0x10], %f14
-	ldd	[%o1 + 0x18], %f16
-	ldd	[%o1 + 0x20], %f18
-	ldd	[%o1 + 0x28], %f20
-	ldd	[%o1 + 0x30], %f22
-	ldd	[%o1 + 0x38], %f24
-	subcc	%o2, 1, %o2		! done yet?
-	ldd	[%o1 + 0x40], %f26
-	add	%o1, 0x40, %o1
-	prefetch [%o1 + 63], 20
-
-	faligndata %f10, %f12, %f8
-	faligndata %f12, %f14, %f10
-	faligndata %f14, %f16, %f12
-	faligndata %f16, %f18, %f14
-	faligndata %f18, %f20, %f16
-	faligndata %f20, %f22, %f18
-	faligndata %f22, %f24, %f20
-	faligndata %f24, %f26, %f22
-
-	.word	0x81b02800		! MD5
-
-	bne,pt	`$bits==64?"%xcc":"%icc"`, .Lhwunaligned_loop
-	for	%f26, %f26, %f10	! %f10=%f26
-
-	ba	.Lhwfinish
-	nop
-
-.align	16
-.Lsoftware:
-	save	%sp,-$frame,%sp
-
-	rd	%asi,$saved_asi
-	wr	%g0,0x88,%asi		! ASI_PRIMARY_LITTLE
-	and	$inp,7,$shr
-	andn	$inp,7,$inp
-
-	sll	$shr,3,$shr		! *=8
-	mov	56,$shl2
-	ld	[$ctx+0],$A
-	sub	$shl2,$shr,$shl2
-	ld	[$ctx+4],$B
-	and	$shl2,32,$shl1
-	add	$shl2,8,$shl2
-	ld	[$ctx+8],$C
-	sub	$shl2,$shl1,$shl2	! shr+shl1+shl2==64
-	ld	[$ctx+12],$D
-	nop
-
-.Loop:
-	 cmp	$shr,0			! was inp aligned?
-	ldxa	[$inp+0]%asi,@X[0]	! load little-endian input
-	ldxa	[$inp+8]%asi,@X[1]
-	ldxa	[$inp+16]%asi,@X[2]
-	ldxa	[$inp+24]%asi,@X[3]
-	ldxa	[$inp+32]%asi,@X[4]
-	 sllx	$A,32,$AB		! pack A,B
-	ldxa	[$inp+40]%asi,@X[5]
-	 sllx	$C,32,$CD		! pack C,D
-	ldxa	[$inp+48]%asi,@X[6]
-	 or	$B,$AB,$AB
-	ldxa	[$inp+56]%asi,@X[7]
-	 or	$D,$CD,$CD
-	bnz,a,pn	%icc,.+8
-	ldxa	[$inp+64]%asi,@X[8]
-
-	srlx	@X[0],$shr,@X[0]	! align X[0]
-	sllx	@X[1],$shl1,$tx
-	 sethi	%hi(@K[0]),$t2
-	sllx	$tx,$shl2,$tx
-	 or	$t2,%lo(@K[0]),$t2
-	or	$tx,@X[0],@X[0]
-	 xor	$C,$D,$t1
-	 add	@X[0],$t2,$t2		! X[0]+K[0]
-___
-	for ($i=0;$i<15;$i++)	{ &R0($i,@V);	unshift(@V,pop(@V)); }
-	for (;$i<16;$i++)	{ &R0_1($i,@V);	unshift(@V,pop(@V)); }
-	for (;$i<32;$i++)	{ &R1($i,@V);	unshift(@V,pop(@V)); }
-	for (;$i<48;$i++)	{ &R2($i,@V);	unshift(@V,pop(@V)); }
-	for (;$i<64;$i++)	{ &R3($i,@V);	unshift(@V,pop(@V)); }
-$code.=<<___;
-	srlx	$AB,32,$t1		! unpack A,B,C,D and accumulate
-	add	$inp,64,$inp		! advance inp
-	srlx	$CD,32,$t2
-	add	$t1,$A,$A
-	subcc	$len,1,$len		! done yet?
-	add	$AB,$B,$B
-	add	$t2,$C,$C
-	add	$CD,$D,$D
-	srl	$B,0,$B			! clruw	$B
-	bne	`$bits==64?"%xcc":"%icc"`,.Loop
-	srl	$D,0,$D			! clruw	$D
-
-	st	$A,[$ctx+0]		! write out ctx
-	st	$B,[$ctx+4]
-	st	$C,[$ctx+8]
-	st	$D,[$ctx+12]
-
-	wr	%g0,$saved_asi,%asi
-	ret
-	restore
-.type	md5_block_asm_data_order,#function
-.size	md5_block_asm_data_order,(.-md5_block_asm_data_order)
-
-.asciz	"MD5 block transform for SPARCv9, CRYPTOGAMS by <appro\@openssl.org>"
-.align	4
-___
-
-# Purpose of these subroutines is to explicitly encode VIS instructions,
-# so that one can compile the module without having to specify VIS
-# extentions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a.
-# Idea is to reserve for option to produce "universal" binary and let
-# programmer detect if current CPU is VIS capable at run-time.
-sub unvis {
-my ($mnemonic,$rs1,$rs2,$rd)=@_;
-my $ref,$opf;
-my %visopf = (	"faligndata"	=> 0x048,
-		"for"		=> 0x07c	);
-
-    $ref = "$mnemonic\t$rs1,$rs2,$rd";
-
-    if ($opf=$visopf{$mnemonic}) {
-	foreach ($rs1,$rs2,$rd) {
-	    return $ref if (!/%f([0-9]{1,2})/);
-	    $_=$1;
-	    if ($1>=32) {
-		return $ref if ($1&1);
-		# re-encode for upper double register addressing
-		$_=($1|$1>>5)&31;
-	    }
-	}
-
-	return	sprintf ".word\t0x%08x !%s",
-			0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
-			$ref;
-    } else {
-	return $ref;
-    }
-}
-sub unalignaddr {
-my ($mnemonic,$rs1,$rs2,$rd)=@_;
-my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 );
-my $ref="$mnemonic\t$rs1,$rs2,$rd";
-
-    foreach ($rs1,$rs2,$rd) {
-	if (/%([goli])([0-7])/)	{ $_=$bias{$1}+$2; }
-	else			{ return $ref; }
-    }
-    return  sprintf ".word\t0x%08x !%s",
-		    0x81b00300|$rd<<25|$rs1<<14|$rs2,
-		    $ref;
-}
-
-foreach (split("\n",$code)) {
-	s/\`([^\`]*)\`/eval $1/ge;
-
-	s/\b(f[^\s]*)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})/
-		&unvis($1,$2,$3,$4)
-	 /ge;
-	s/\b(alignaddr)\s+(%[goli][0-7]),\s*(%[goli][0-7]),\s*(%[goli][0-7])/
-		&unalignaddr($1,$2,$3,$4)
-	 /ge;
-
-	print $_,"\n";
-}
-
-close STDOUT;
--- a/components/openssl/openssl-1.0.1/inline-t4/sparc_arch.h	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-#ifndef __SPARC_ARCH_H__
-#define	__SPARC_ARCH_H__
-
-#define	SPARCV9_TICK_PRIVILEGED	(1<<0)
-#define	SPARCV9_PREFER_FPU	(1<<1)
-#define	SPARCV9_VIS1		(1<<2)
-#define	SPARCV9_VIS2		(1<<3)	/* reserved */
-#define	SPARCV9_FMADD		(1<<4)	/* reserved for SPARC64 V */
-#define	SPARCV9_BLK		(1<<5)	/* VIS1 block copy */
-#define	SPARCV9_VIS3		(1<<6)
-#define	SPARCV9_RANDOM		(1<<7)
-#define	SPARCV9_64BIT_STACK	(1<<8)
-
-/*
- * OPENSSL_sparcv9cap_P[1] is copy of Compatibility Feature Register,
- * %asr26, SPARC-T4 and later. There is no SPARCV9_CFR bit in
- * OPENSSL_sparcv9cap_P[0], as %cfr copy is sufficient...
- */
-#define	CFR_AES		0x00000001 /* Supports AES opcodes	*/
-#define	CFR_DES		0x00000002 /* Supports DES opcodes	*/
-#define	CFR_KASUMI	0x00000004 /* Supports KASUMI opcodes	*/
-#define	CFR_CAMELLIA	0x00000008 /* Supports CAMELLIA opcodes	*/
-#define	CFR_MD5		0x00000010 /* Supports MD5 opcodes	*/
-#define	CFR_SHA1	0x00000020 /* Supports SHA1 opcodes	*/
-#define	CFR_SHA256	0x00000040 /* Supports SHA256 opcodes	*/
-#define	CFR_SHA512	0x00000080 /* Supports SHA512 opcodes	*/
-#define	CFR_MPMUL	0x00000100 /* Supports MPMUL opcodes	*/
-#define	CFR_MONTMUL	0x00000200 /* Supports MONTMUL opcodes	*/
-#define	CFR_MONTSQR	0x00000400 /* Supports MONTSQR opcodes	*/
-#define	CFR_CRC32C	0x00000800 /* Supports CRC32C opcodes	*/
-
-#if defined(OPENSSL_PIC) && !defined(__PIC__)
-#define	__PIC__
-#endif
-
-#if defined(__SUNPRO_C) && defined(__sparcv9) && !defined(__arch64__)
-#define	__arch64__
-#endif
-
-#define	SPARC_PIC_THUNK(reg)	\
-	.align	32;		\
-.Lpic_thunk:			\
-	jmp	%o7 + 8;	\
-	add	%o7, reg, reg;
-
-#define	SPARC_PIC_THUNK_CALL(reg)			\
-	sethi	%hi(_GLOBAL_OFFSET_TABLE_-4), reg;	\
-	call	.Lpic_thunk;				\
-	or	reg, %lo(_GLOBAL_OFFSET_TABLE_+4), reg;
-
-#if 1
-#define	SPARC_SETUP_GOT_REG(reg)	SPARC_PIC_THUNK_CALL(reg)
-#else
-#define	SPARC_SETUP_GOT_REG(reg)	\
-	sethi	%hi(_GLOBAL_OFFSET_TABLE_-4), reg;	\
-	call	.+8;					\
-	or	reg, %lo(_GLOBAL_OFFSET_TABLE_+4), reg;	\
-	add	%o7, reg, reg
-#endif
-
-#if defined(__arch64__)
-
-#define	SPARC_LOAD_ADDRESS(SYM, reg)	\
-	setx	SYM, %o7, reg;
-#define	LDPTR		ldx
-#define	SIZE_T_CC	%xcc
-#define	STACK_FRAME	192
-#define	STACK_BIAS	2047
-#define	STACK_7thARG	(STACK_BIAS+176)
-
-#else
-
-#define	SPARC_LOAD_ADDRESS(SYM, reg)	\
-	set	SYM, reg;
-#define	LDPTR		ld
-#define	SIZE_T_CC	%icc
-#define	STACK_FRAME	112
-#define	STACK_BIAS	0
-#define	STACK_7thARG	92
-#define	SPARC_LOAD_ADDRESS_LEAF(SYM, reg, tmp) SPARC_LOAD_ADDRESS(SYM, reg)
-
-#endif
-
-#ifdef __PIC__
-#undef	SPARC_LOAD_ADDRESS
-#undef SPARC_LOAD_ADDRESS_LEAF
-#define	SPARC_LOAD_ADDRESS(SYM, reg)	\
-	SPARC_SETUP_GOT_REG(reg);	\
-	sethi	%hi(SYM), %o7;		\
-	or	%o7, %lo(SYM), %o7;	\
-	LDPTR	[reg + %o7], reg;
-#endif
-
-#ifndef SPARC_LOAD_ADDRESS_LEAF
-#define	SPARC_LOAD_ADDRESS_LEAF(SYM, reg, tmp)	\
-	mov	%o7, tmp;			\
-	SPARC_LOAD_ADDRESS(SYM, reg)		\
-	mov	tmp, %o7;
-#endif
-
-#endif	/* __SPARC_ARCH_H__ */
--- a/components/openssl/openssl-1.0.1/inline-t4/sparct4-mont.pl	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1222 +0,0 @@
-#!/usr/bin/env perl
-
-# ====================================================================
-# Written by David S. Miller <[email protected]> and Andy Polyakov
-# <[email protected]>. The module is licensed under 2-clause BSD
-# license. November 2012. All rights reserved.
-# ====================================================================
-
-######################################################################
-# Montgomery squaring-n-multiplication module for SPARC T4.
-#
-# The module consists of three parts:
-#
-# 1) collection of "single-op" subroutines that perform single
-#    operation, Montgomery squaring or multiplication, on 512-,
-#    1024-, 1536- and 2048-bit operands;
-# 2) collection of "multi-op" subroutines that perform 5 squaring and
-#    1 multiplication operations on operands of above lengths;
-# 3) fall-back and helper VIS3 subroutines.
-#
-# RSA sign is dominated by multi-op subroutine, while RSA verify and
-# DSA - by single-op. Special note about 4096-bit RSA verify result.
-# Operands are too long for dedicated hardware and it's handled by
-# VIS3 code, which is why you don't see any improvement. It's surely
-# possible to improve it [by deploying 'mpmul' instruction], maybe in
-# the future...
-#
-# Performance improvement.
-#
-# 64-bit process, VIS3:
-#                   sign    verify    sign/s verify/s
-# rsa 1024 bits 0.000628s 0.000028s   1592.4  35434.4
-# rsa 2048 bits 0.003282s 0.000106s    304.7   9438.3
-# rsa 4096 bits 0.025866s 0.000340s     38.7   2940.9
-# dsa 1024 bits 0.000301s 0.000332s   3323.7   3013.9
-# dsa 2048 bits 0.001056s 0.001233s    946.9    810.8
-#
-# 64-bit process, this module:
-#                   sign    verify    sign/s verify/s
-# rsa 1024 bits 0.000256s 0.000016s   3904.4  61411.9
-# rsa 2048 bits 0.000946s 0.000029s   1056.8  34292.7
-# rsa 4096 bits 0.005061s 0.000340s    197.6   2940.5
-# dsa 1024 bits 0.000176s 0.000195s   5674.7   5130.5
-# dsa 2048 bits 0.000296s 0.000354s   3383.2   2827.6
-#
-######################################################################
-# 32-bit process, VIS3:
-#                   sign    verify    sign/s verify/s
-# rsa 1024 bits 0.000665s 0.000028s   1504.8  35233.3
-# rsa 2048 bits 0.003349s 0.000106s    298.6   9433.4
-# rsa 4096 bits 0.025959s 0.000341s     38.5   2934.8
-# dsa 1024 bits 0.000320s 0.000341s   3123.3   2929.6
-# dsa 2048 bits 0.001101s 0.001260s    908.2    793.4
-#
-# 32-bit process, this module:
-#                   sign    verify    sign/s verify/s
-# rsa 1024 bits 0.000301s 0.000017s   3317.1  60240.0
-# rsa 2048 bits 0.001034s 0.000030s    966.9  33812.7
-# rsa 4096 bits 0.005244s 0.000341s    190.7   2935.4
-# dsa 1024 bits 0.000201s 0.000205s   4976.1   4879.2
-# dsa 2048 bits 0.000328s 0.000360s   3051.1   2774.2
-#
-# 32-bit code is prone to performance degradation as interrupt rate
-# dispatched to CPU executing the code grows. This is because in
-# standard process of handling interrupt in 32-bit process context
-# upper halves of most integer registers used as input or output are
-# zeroed. This renders result invalid, and operation has to be re-run.
-# If CPU is "bothered" with timer interrupts only, the penalty is
-# hardly measurable. But in order to mitigate this problem for higher
-# interrupt rates contemporary Linux kernel recognizes biased stack
-# even in 32-bit process context and preserves full register contents.
-# See http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=517ffce4e1a03aea979fe3a18a3dd1761a24fafb
-# for details.
-
-$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-push(@INC,"${dir}","${dir}../../perlasm");
-require "sparcv9_modes.pl";
-
-$code.=<<___;
-#include "sparc_arch.h"
-
-#ifdef	__arch64__
-.register	%g2,#scratch
-.register	%g3,#scratch
-#endif
-
-.section	".text",#alloc,#execinstr
-
-#ifdef	__PIC__
-SPARC_PIC_THUNK(%g1)
-#endif
-___
-
-########################################################################
-# Register layout for mont[mul|sqr] instructions.
-# For details see "Oracle SPARC Architecture 2011" manual at
-# http://www.oracle.com/technetwork/server-storage/sun-sparc-enterprise/documentation/.
-#
-my @R=map("%f".2*$_,(0..11,30,31,12..29));
-my @N=(map("%l$_",(0..7)),map("%o$_",(0..5))); @N=(@N,@N,@N[0..3]);
-my @A=(@N[0..13],@R[14..31]);
-my @B=(map("%i$_",(0..5)),map("%l$_",(0..7))); @B=(@B,@B,map("%o$_",(0..3)));
-
-########################################################################
-# int bn_mul_mont_t4_$NUM(u64 *rp,const u64 *ap,const u64 *bp,
-#			  const u64 *np,const BN_ULONG *n0);
-#
-sub generate_bn_mul_mont_t4() {
-my $NUM=shift;
-my ($rp,$ap,$bp,$np,$sentinel)=map("%g$_",(1..5));
-
-$code.=<<___;
-.globl	bn_mul_mont_t4_$NUM
-.align	32
-bn_mul_mont_t4_$NUM:
-#ifdef	__arch64__
-	mov	0,$sentinel
-	mov	-128,%g4
-#elif defined(SPARCV9_64BIT_STACK)
-	SPARC_LOAD_ADDRESS_LEAF(OPENSSL_sparcv9cap_P,%g1,%g5)
-	ld	[%g1+0],%g1	! OPENSSL_sparcv9_P[0]
-	mov	-2047,%g4
-	and	%g1,SPARCV9_64BIT_STACK,%g1
-	movrz	%g1,0,%g4
-	mov	-1,$sentinel
-	add	%g4,-128,%g4
-#else
-	mov	-1,$sentinel
-	mov	-128,%g4
-#endif
-	sllx	$sentinel,32,$sentinel
-	save	%sp,%g4,%sp
-#ifndef	__arch64__
-	save	%sp,-128,%sp	! warm it up
-	save	%sp,-128,%sp
-	save	%sp,-128,%sp
-	save	%sp,-128,%sp
-	save	%sp,-128,%sp
-	save	%sp,-128,%sp
-	restore
-	restore
-	restore
-	restore
-	restore
-	restore
-#endif
-	and	%sp,1,%g4
-	or	$sentinel,%fp,%fp
-	or	%g4,$sentinel,$sentinel
-
-	! copy arguments to global registers
-	mov	%i0,$rp
-	mov	%i1,$ap
-	mov	%i2,$bp
-	mov	%i3,$np
-	ld	[%i4+0],%f1	! load *n0
-	ld	[%i4+4],%f0
-	fsrc2	%f0,%f60
-___
-
-# load ap[$NUM] ########################################################
-$code.=<<___;
-	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-___
-for($i=0; $i<14 && $i<$NUM; $i++) {
-my $lo=$i<13?@A[$i+1]:"%o7";
-$code.=<<___;
-	ld	[$ap+$i*8+0],$lo
-	ld	[$ap+$i*8+4],@A[$i]
-	sllx	@A[$i],32,@A[$i]
-	or	$lo,@A[$i],@A[$i]
-___
-}
-for(; $i<$NUM; $i++) {
-my ($hi,$lo)=("%f".2*($i%4),"%f".(2*($i%4)+1));
-$code.=<<___;
-	ld	[$ap+$i*8+0],$lo
-	ld	[$ap+$i*8+4],$hi
-	fsrc2	$hi,@A[$i]
-___
-}
-# load np[$NUM] ########################################################
-$code.=<<___;
-	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-___
-for($i=0; $i<14 && $i<$NUM; $i++) {
-my $lo=$i<13?@N[$i+1]:"%o7";
-$code.=<<___;
-	ld	[$np+$i*8+0],$lo
-	ld	[$np+$i*8+4],@N[$i]
-	sllx	@N[$i],32,@N[$i]
-	or	$lo,@N[$i],@N[$i]
-___
-}
-$code.=<<___;
-	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-___
-for(; $i<28 && $i<$NUM; $i++) {
-my $lo=$i<27?@N[$i+1]:"%o7";
-$code.=<<___;
-	ld	[$np+$i*8+0],$lo
-	ld	[$np+$i*8+4],@N[$i]
-	sllx	@N[$i],32,@N[$i]
-	or	$lo,@N[$i],@N[$i]
-___
-}
-$code.=<<___;
-	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-___
-for(; $i<$NUM; $i++) {
-my $lo=($i<$NUM-1)?@N[$i+1]:"%o7";
-$code.=<<___;
-	ld	[$np+$i*8+0],$lo
-	ld	[$np+$i*8+4],@N[$i]
-	sllx	@N[$i],32,@N[$i]
-	or	$lo,@N[$i],@N[$i]
-___
-}
-$code.=<<___;
-	cmp	$ap,$bp
-	be	SIZE_T_CC,.Lmsquare_$NUM
-	nop
-___
-
-# load bp[$NUM] ########################################################
-$code.=<<___;
-	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-___
-for($i=0; $i<14 && $i<$NUM; $i++) {
-my $lo=$i<13?@B[$i+1]:"%o7";
-$code.=<<___;
-	ld	[$bp+$i*8+0],$lo
-	ld	[$bp+$i*8+4],@B[$i]
-	sllx	@B[$i],32,@B[$i]
-	or	$lo,@B[$i],@B[$i]
-___
-}
-$code.=<<___;
-	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-___
-for(; $i<$NUM; $i++) {
-my $lo=($i<$NUM-1)?@B[$i+1]:"%o7";
-$code.=<<___;
-	ld	[$bp+$i*8+0],$lo
-	ld	[$bp+$i*8+4],@B[$i]
-	sllx	@B[$i],32,@B[$i]
-	or	$lo,@B[$i],@B[$i]
-___
-}
-# magic ################################################################
-$code.=<<___;
-	.word	0x81b02920+$NUM-1	! montmul	$NUM-1
-.Lmresume_$NUM:
-	fbu,pn	%fcc3,.Lmabort_$NUM
-#ifndef	__arch64__
-	and	%fp,$sentinel,$sentinel
-	brz,pn	$sentinel,.Lmabort_$NUM
-#endif
-	nop
-#ifdef	__arch64__
-	restore
-	restore
-	restore
-	restore
-	restore
-#else
-	restore;		and	%fp,$sentinel,$sentinel
-	restore;		and	%fp,$sentinel,$sentinel
-	restore;		and	%fp,$sentinel,$sentinel
-	restore;		and	%fp,$sentinel,$sentinel
-	 brz,pn	$sentinel,.Lmabort1_$NUM
-	restore
-#endif
-___
-
-# save tp[$NUM] ########################################################
-for($i=0; $i<14 && $i<$NUM; $i++) {
-$code.=<<___;
-	movxtod	@A[$i],@R[$i]
-___
-}
-$code.=<<___;
-#ifdef	__arch64__
-	restore
-#else
-	 and	%fp,$sentinel,$sentinel
-	restore
-	 and	$sentinel,1,%o7
-	 and	%fp,$sentinel,$sentinel
-	 srl	%fp,0,%fp		! just in case?
-	 or	%o7,$sentinel,$sentinel
-	brz,a,pn $sentinel,.Lmdone_$NUM
-	mov	0,%i0		! return failure
-#endif
-___
-for($i=0; $i<12 && $i<$NUM; $i++) {
-@R[$i] =~ /%f([0-9]+)/;
-my $lo = "%f".($1+1);
-$code.=<<___;
-	st	$lo,[$rp+$i*8+0]
-	st	@R[$i],[$rp+$i*8+4]
-___
-}
-for(; $i<$NUM; $i++) {
-my ($hi,$lo)=("%f".2*($i%4),"%f".(2*($i%4)+1));
-$code.=<<___;
-	fsrc2	@R[$i],$hi
-	st	$lo,[$rp+$i*8+0]
-	st	$hi,[$rp+$i*8+4]
-___
-}
-$code.=<<___;
-	mov	1,%i0		! return success
-.Lmdone_$NUM:
-	ret
-	restore
-
-.Lmabort_$NUM:
-	restore
-	restore
-	restore
-	restore
-	restore
-.Lmabort1_$NUM:
-	restore
-
-	mov	0,%i0		! return failure
-	ret
-	restore
-
-.align	32
-.Lmsquare_$NUM:
-	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-	.word   0x81b02940+$NUM-1	! montsqr	$NUM-1
-	ba	.Lmresume_$NUM
-	nop
-.type	bn_mul_mont_t4_$NUM, #function
-.size	bn_mul_mont_t4_$NUM, .-bn_mul_mont_t4_$NUM
-___
-}
-
-for ($i=8;$i<=32;$i+=8) {
-	&generate_bn_mul_mont_t4($i);
-}
-
-########################################################################
-#
-sub load_ccr {
-my ($ptbl,$pwr,$ccr,$skip_wr)=@_;
-$code.=<<___;
-	srl	$pwr,	2,	%o4
-	and	$pwr,	3,	%o5
-	and	%o4,	7,	%o4
-	sll	%o5,	3,	%o5	! offset within first cache line
-	add	%o5,	$ptbl,	$ptbl	! of the pwrtbl
-	or	%g0,	1,	%o5
-	sll	%o5,	%o4,	$ccr
-___
-$code.=<<___	if (!$skip_wr);
-	wr	$ccr,	%g0,	%ccr
-___
-}
-sub load_b_pair {
-my ($pwrtbl,$B0,$B1)=@_;
-
-$code.=<<___;
-	ldx	[$pwrtbl+0*32],	$B0
-	ldx	[$pwrtbl+8*32],	$B1
-	ldx	[$pwrtbl+1*32],	%o4
-	ldx	[$pwrtbl+9*32],	%o5
-	movvs	%icc,	%o4,	$B0
-	ldx	[$pwrtbl+2*32],	%o4
-	movvs	%icc,	%o5,	$B1
-	ldx	[$pwrtbl+10*32],%o5
-	move	%icc,	%o4,	$B0
-	ldx	[$pwrtbl+3*32],	%o4
-	move	%icc,	%o5,	$B1
-	ldx	[$pwrtbl+11*32],%o5
-	movneg	%icc,	%o4,	$B0
-	ldx	[$pwrtbl+4*32],	%o4
-	movneg	%icc,	%o5,	$B1
-	ldx	[$pwrtbl+12*32],%o5
-	movcs	%xcc,	%o4,	$B0
-	ldx	[$pwrtbl+5*32],%o4
-	movcs	%xcc,	%o5,	$B1
-	ldx	[$pwrtbl+13*32],%o5
-	movvs	%xcc,	%o4,	$B0
-	ldx	[$pwrtbl+6*32],	%o4
-	movvs	%xcc,	%o5,	$B1
-	ldx	[$pwrtbl+14*32],%o5
-	move	%xcc,	%o4,	$B0
-	ldx	[$pwrtbl+7*32],	%o4
-	move	%xcc,	%o5,	$B1
-	ldx	[$pwrtbl+15*32],%o5
-	movneg	%xcc,	%o4,	$B0
-	add	$pwrtbl,16*32,	$pwrtbl
-	movneg	%xcc,	%o5,	$B1
-___
-}
-sub load_b {
-my ($pwrtbl,$Bi)=@_;
-
-$code.=<<___;
-	ldx	[$pwrtbl+0*32],	$Bi
-	ldx	[$pwrtbl+1*32],	%o4
-	ldx	[$pwrtbl+2*32],	%o5
-	movvs	%icc,	%o4,	$Bi
-	ldx	[$pwrtbl+3*32],	%o4
-	move	%icc,	%o5,	$Bi
-	ldx	[$pwrtbl+4*32],	%o5
-	movneg	%icc,	%o4,	$Bi
-	ldx	[$pwrtbl+5*32],	%o4
-	movcs	%xcc,	%o5,	$Bi
-	ldx	[$pwrtbl+6*32],	%o5
-	movvs	%xcc,	%o4,	$Bi
-	ldx	[$pwrtbl+7*32],	%o4
-	move	%xcc,	%o5,	$Bi
-	add	$pwrtbl,8*32,	$pwrtbl
-	movneg	%xcc,	%o4,	$Bi
-___
-}
-
-########################################################################
-# int bn_pwr5_mont_t4_$NUM(u64 *tp,const u64 *np,const BN_ULONG *n0,
-#			   const u64 *pwrtbl,int pwr,int stride);
-#
-sub generate_bn_pwr5_mont_t4() {
-my $NUM=shift;
-my ($tp,$np,$pwrtbl,$pwr,$sentinel)=map("%g$_",(1..5));
-
-$code.=<<___;
-.globl	bn_pwr5_mont_t4_$NUM
-.align	32
-bn_pwr5_mont_t4_$NUM:
-#ifdef	__arch64__
-	mov	0,$sentinel
-	mov	-128,%g4
-#elif defined(SPARCV9_64BIT_STACK)
-	SPARC_LOAD_ADDRESS_LEAF(OPENSSL_sparcv9cap_P,%g1,%g5)
-	ld	[%g1+0],%g1	! OPENSSL_sparcv9_P[0]
-	mov	-2047,%g4
-	and	%g1,SPARCV9_64BIT_STACK,%g1
-	movrz	%g1,0,%g4
-	mov	-1,$sentinel
-	add	%g4,-128,%g4
-#else
-	mov	-1,$sentinel
-	mov	-128,%g4
-#endif
-	sllx	$sentinel,32,$sentinel
-	save	%sp,%g4,%sp
-#ifndef	__arch64__
-	save	%sp,-128,%sp	! warm it up
-	save	%sp,-128,%sp
-	save	%sp,-128,%sp
-	save	%sp,-128,%sp
-	save	%sp,-128,%sp
-	save	%sp,-128,%sp
-	restore
-	restore
-	restore
-	restore
-	restore
-	restore
-#endif
-	and	%sp,1,%g4
-	or	$sentinel,%fp,%fp
-	or	%g4,$sentinel,$sentinel
-
-	! copy arguments to global registers
-	mov	%i0,$tp
-	mov	%i1,$np
-	ld	[%i2+0],%f1	! load *n0
-	ld	[%i2+4],%f0
-	mov	%i3,$pwrtbl
-	srl	%i4,%g0,%i4	! pack last arguments
-	sllx	%i5,32,$pwr
-	or	%i4,$pwr,$pwr
-	fsrc2	%f0,%f60
-___
-
-# load tp[$NUM] ########################################################
-$code.=<<___;
-	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-___
-for($i=0; $i<14 && $i<$NUM; $i++) {
-$code.=<<___;
-	ldx	[$tp+$i*8],@A[$i]
-___
-}
-for(; $i<$NUM; $i++) {
-$code.=<<___;
-	ldd	[$tp+$i*8],@A[$i]
-___
-}
-# load np[$NUM] ########################################################
-$code.=<<___;
-	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-___
-for($i=0; $i<14 && $i<$NUM; $i++) {
-$code.=<<___;
-	ldx	[$np+$i*8],@N[$i]
-___
-}
-$code.=<<___;
-	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-___
-for(; $i<28 && $i<$NUM; $i++) {
-$code.=<<___;
-	ldx	[$np+$i*8],@N[$i]
-___
-}
-$code.=<<___;
-	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-___
-for(; $i<$NUM; $i++) {
-$code.=<<___;
-	ldx	[$np+$i*8],@N[$i]
-___
-}
-# load pwrtbl[pwr] ########################################################
-$code.=<<___;
-	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-
-	srlx	$pwr,	32,	%o4		! unpack $pwr
-	srl	$pwr,	%g0,	%o5
-	sub	%o4,	5,	%o4
-	mov	$pwrtbl,	%o7
-	sllx	%o4,	32,	$pwr		! re-pack $pwr
-	or	%o5,	$pwr,	$pwr
-	srl	%o5,	%o4,	%o5
-___
-	&load_ccr("%o7","%o5","%o4");
-$code.=<<___;
-	b	.Lstride_$NUM
-	nop
-.align	16
-.Lstride_$NUM:
-___
-for($i=0; $i<14 && $i<$NUM; $i+=2) {
-	&load_b_pair("%o7",@B[$i],@B[$i+1]);
-}
-$code.=<<___;
-	save	%sp,-128,%sp;		or	$sentinel,%fp,%fp
-___
-for(; $i<$NUM; $i+=2) {
-	&load_b_pair("%i7",@B[$i],@B[$i+1]);
-}
-$code.=<<___;
-	srax	$pwr,	32,	%o4		! unpack $pwr
-	srl	$pwr,	%g0,	%o5
-	sub	%o4,	5,	%o4
-	mov	$pwrtbl,	%i7
-	sllx	%o4,	32,	$pwr		! re-pack $pwr
-	or	%o5,	$pwr,	$pwr
-	srl	%o5,	%o4,	%o5
-___
-	&load_ccr("%i7","%o5","%o4",1);
-
-# magic ################################################################
-for($i=0; $i<5; $i++) {
-$code.=<<___;
-	.word	0x81b02940+$NUM-1	! montsqr	$NUM-1
-	fbu,pn	%fcc3,.Labort_$NUM
-#ifndef	__arch64__
-	and	%fp,$sentinel,$sentinel
-	brz,pn	$sentinel,.Labort_$NUM
-#endif
-	nop
-___
-}
-$code.=<<___;
-	wr	%o4,	%g0,	%ccr
-	.word	0x81b02920+$NUM-1	! montmul	$NUM-1
-	fbu,pn	%fcc3,.Labort_$NUM
-#ifndef	__arch64__
-	and	%fp,$sentinel,$sentinel
-	brz,pn	$sentinel,.Labort_$NUM
-#endif
-
-	srax	$pwr,	32,	%o4
-#ifdef	__arch64__
-	brgez	%o4,.Lstride_$NUM
-	restore
-	restore
-	restore
-	restore
-	restore
-#else
-	brgez	%o4,.Lstride_$NUM
-	restore;		and	%fp,$sentinel,$sentinel
-	restore;		and	%fp,$sentinel,$sentinel
-	restore;		and	%fp,$sentinel,$sentinel
-	restore;		and	%fp,$sentinel,$sentinel
-	 brz,pn	$sentinel,.Labort1_$NUM
-	restore
-#endif
-___
-
-# save tp[$NUM] ########################################################
-for($i=0; $i<14 && $i<$NUM; $i++) {
-$code.=<<___;
-	movxtod	@A[$i],@R[$i]
-___
-}
-$code.=<<___;
-#ifdef	__arch64__
-	restore
-#else
-	 and	%fp,$sentinel,$sentinel
-	restore
-	 and	$sentinel,1,%o7
-	 and	%fp,$sentinel,$sentinel
-	 srl	%fp,0,%fp		! just in case?
-	 or	%o7,$sentinel,$sentinel
-	brz,a,pn $sentinel,.Ldone_$NUM
-	mov	0,%i0		! return failure
-#endif
-___
-for($i=0; $i<$NUM; $i++) {
-$code.=<<___;
-	std	@R[$i],[$tp+$i*8]
-___
-}
-$code.=<<___;
-	mov	1,%i0		! return success
-.Ldone_$NUM:
-	ret
-	restore
-
-.Labort_$NUM:
-	restore
-	restore
-	restore
-	restore
-	restore
-.Labort1_$NUM:
-	restore
-
-	mov	0,%i0		! return failure
-	ret
-	restore
-.type	bn_pwr5_mont_t4_$NUM, #function
-.size	bn_pwr5_mont_t4_$NUM, .-bn_pwr5_mont_t4_$NUM
-___
-}
-
-for ($i=8;$i<=32;$i+=8) {
-	&generate_bn_pwr5_mont_t4($i);
-}
-
-{
-########################################################################
-# Fall-back subroutines
-#
-# copy of bn_mul_mont_vis3 adjusted for vectors of 64-bit values
-#
-($n0,$m0,$m1,$lo0,$hi0, $lo1,$hi1,$aj,$alo,$nj,$nlo,$tj)=
-	(map("%g$_",(1..5)),map("%o$_",(0..5,7)));
-
-# int bn_mul_mont(
-$rp="%o0";	# u64 *rp,
-$ap="%o1";	# const u64 *ap,
-$bp="%o2";	# const u64 *bp,
-$np="%o3";	# const u64 *np,
-$n0p="%o4";	# const BN_ULONG *n0,
-$num="%o5";	# int num);	# caller ensures that num is >=3
-$code.=<<___;
-.globl	bn_mul_mont_t4
-.align	32
-bn_mul_mont_t4:
-	add	%sp,	STACK_BIAS,	%g4	! real top of stack
-	sll	$num,	3,	$num		! size in bytes
-	add	$num,	63,	%g1
-	andn	%g1,	63,	%g1		! buffer size rounded up to 64 bytes
-	sub	%g4,	%g1,	%g1
-	andn	%g1,	63,	%g1		! align at 64 byte
-	sub	%g1,	STACK_FRAME,	%g1	! new top of stack
-	sub	%g1,	%g4,	%g1
-
-	save	%sp,	%g1,	%sp
-___
-#	+-------------------------------+<-----	%sp
-#	.				.
-#	+-------------------------------+<-----	aligned at 64 bytes
-#	| __int64 tmp[0]		|
-#	+-------------------------------+
-#	.				.
-#	.				.
-#	+-------------------------------+<-----	aligned at 64 bytes
-#	.				.
-($rp,$ap,$bp,$np,$n0p,$num)=map("%i$_",(0..5));
-($t0,$t1,$t2,$t3,$cnt,$tp,$bufsz)=map("%l$_",(0..7));
-($ovf,$i)=($t0,$t1);
-$code.=<<___;
-	ld	[$n0p+0],	$t0	! pull n0[0..1] value
-	ld	[$n0p+4],	$t1
-	add	%sp, STACK_BIAS+STACK_FRAME, $tp
-	ldx	[$bp+0],	$m0	! m0=bp[0]
-	sllx	$t1,	32,	$n0
-	add	$bp,	8,	$bp
-	or	$t0,	$n0,	$n0
-
-	ldx	[$ap+0],	$aj	! ap[0]
-
-	mulx	$aj,	$m0,	$lo0	! ap[0]*bp[0]
-	umulxhi	$aj,	$m0,	$hi0
-
-	ldx	[$ap+8],	$aj	! ap[1]
-	add	$ap,	16,	$ap
-	ldx	[$np+0],	$nj	! np[0]
-
-	mulx	$lo0,	$n0,	$m1	! "tp[0]"*n0
-
-	mulx	$aj,	$m0,	$alo	! ap[1]*bp[0]
-	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-
-	mulx	$nj,	$m1,	$lo1	! np[0]*m1
-	umulxhi	$nj,	$m1,	$hi1
-
-	ldx	[$np+8],	$nj	! np[1]
-
-	addcc	$lo0,	$lo1,	$lo1
-	add	$np,	16,	$np
-	addxc	%g0,	$hi1,	$hi1
-
-	mulx	$nj,	$m1,	$nlo	! np[1]*m1
-	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-
-	ba	.L1st
-	sub	$num,	24,	$cnt	! cnt=num-3
-
-.align	16
-.L1st:
-	addcc	$alo,	$hi0,	$lo0
-	addxc	$aj,	%g0,	$hi0
-
-	ldx	[$ap+0],	$aj	! ap[j]
-	addcc	$nlo,	$hi1,	$lo1
-	add	$ap,	8,	$ap
-	addxc	$nj,	%g0,	$hi1	! nhi=nj
-
-	ldx	[$np+0],	$nj	! np[j]
-	mulx	$aj,	$m0,	$alo	! ap[j]*bp[0]
-	add	$np,	8,	$np
-	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-
-	mulx	$nj,	$m1,	$nlo	! np[j]*m1
-	addcc	$lo0,	$lo1,	$lo1	! np[j]*m1+ap[j]*bp[0]
-	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-	addxc	%g0,	$hi1,	$hi1
-	stxa	$lo1,	[$tp]0xe2	! tp[j-1]
-	add	$tp,	8,	$tp	! tp++
-
-	brnz,pt	$cnt,	.L1st
-	sub	$cnt,	8,	$cnt	! j--
-!.L1st
-	addcc	$alo,	$hi0,	$lo0
-	addxc	$aj,	%g0,	$hi0	! ahi=aj
-
-	addcc	$nlo,	$hi1,	$lo1
-	addxc	$nj,	%g0,	$hi1
-	addcc	$lo0,	$lo1,	$lo1	! np[j]*m1+ap[j]*bp[0]
-	addxc	%g0,	$hi1,	$hi1
-	stxa	$lo1,	[$tp]0xe2	! tp[j-1]
-	add	$tp,	8,	$tp
-
-	addcc	$hi0,	$hi1,	$hi1
-	addxc	%g0,	%g0,	$ovf	! upmost overflow bit
-	stxa	$hi1,	[$tp]0xe2
-	add	$tp,	8,	$tp
-
-	ba	.Louter
-	sub	$num,	16,	$i	! i=num-2
-
-.align	16
-.Louter:
-	ldx	[$bp+0],	$m0	! m0=bp[i]
-	add	$bp,	8,	$bp
-
-	sub	$ap,	$num,	$ap	! rewind
-	sub	$np,	$num,	$np
-	sub	$tp,	$num,	$tp
-
-	ldx	[$ap+0],	$aj	! ap[0]
-	ldx	[$np+0],	$nj	! np[0]
-
-	mulx	$aj,	$m0,	$lo0	! ap[0]*bp[i]
-	ldx	[$tp],		$tj	! tp[0]
-	umulxhi	$aj,	$m0,	$hi0
-	ldx	[$ap+8],	$aj	! ap[1]
-	addcc	$lo0,	$tj,	$lo0	! ap[0]*bp[i]+tp[0]
-	mulx	$aj,	$m0,	$alo	! ap[1]*bp[i]
-	addxc	%g0,	$hi0,	$hi0
-	mulx	$lo0,	$n0,	$m1	! tp[0]*n0
-	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-	mulx	$nj,	$m1,	$lo1	! np[0]*m1
-	add	$ap,	16,	$ap
-	umulxhi	$nj,	$m1,	$hi1
-	ldx	[$np+8],	$nj	! np[1]
-	add	$np,	16,	$np
-	addcc	$lo1,	$lo0,	$lo1
-	mulx	$nj,	$m1,	$nlo	! np[1]*m1
-	addxc	%g0,	$hi1,	$hi1
-	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-
-	ba	.Linner
-	sub	$num,	24,	$cnt	! cnt=num-3
-.align	16
-.Linner:
-	addcc	$alo,	$hi0,	$lo0
-	ldx	[$tp+8],	$tj	! tp[j]
-	addxc	$aj,	%g0,	$hi0	! ahi=aj
-	ldx	[$ap+0],	$aj	! ap[j]
-	add	$ap,	8,	$ap
-	addcc	$nlo,	$hi1,	$lo1
-	mulx	$aj,	$m0,	$alo	! ap[j]*bp[i]
-	addxc	$nj,	%g0,	$hi1	! nhi=nj
-	ldx	[$np+0],	$nj	! np[j]
-	add	$np,	8,	$np
-	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-	addcc	$lo0,	$tj,	$lo0	! ap[j]*bp[i]+tp[j]
-	mulx	$nj,	$m1,	$nlo	! np[j]*m1
-	addxc	%g0,	$hi0,	$hi0
-	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-	addcc	$lo1,	$lo0,	$lo1	! np[j]*m1+ap[j]*bp[i]+tp[j]
-	addxc	%g0,	$hi1,	$hi1
-	stx	$lo1,	[$tp]		! tp[j-1]
-	add	$tp,	8,	$tp
-	brnz,pt	$cnt,	.Linner
-	sub	$cnt,	8,	$cnt
-!.Linner
-	ldx	[$tp+8],	$tj	! tp[j]
-	addcc	$alo,	$hi0,	$lo0
-	addxc	$aj,	%g0,	$hi0	! ahi=aj
-	addcc	$lo0,	$tj,	$lo0	! ap[j]*bp[i]+tp[j]
-	addxc	%g0,	$hi0,	$hi0
-
-	addcc	$nlo,	$hi1,	$lo1
-	addxc	$nj,	%g0,	$hi1	! nhi=nj
-	addcc	$lo1,	$lo0,	$lo1	! np[j]*m1+ap[j]*bp[i]+tp[j]
-	addxc	%g0,	$hi1,	$hi1
-	stx	$lo1,	[$tp]		! tp[j-1]
-
-	subcc	%g0,	$ovf,	%g0	! move upmost overflow to CCR.xcc
-	addxccc	$hi1,	$hi0,	$hi1
-	addxc	%g0,	%g0,	$ovf
-	stx	$hi1,	[$tp+8]
-	add	$tp,	16,	$tp
-
-	brnz,pt	$i,	.Louter
-	sub	$i,	8,	$i
-
-	sub	$ap,	$num,	$ap	! rewind
-	sub	$np,	$num,	$np
-	sub	$tp,	$num,	$tp
-	ba	.Lsub
-	subcc	$num,	8,	$cnt	! cnt=num-1 and clear CCR.xcc
-
-.align	16
-.Lsub:
-	ldx	[$tp],		$tj
-	add	$tp,	8,	$tp
-	ldx	[$np+0],	$nj
-	add	$np,	8,	$np
-	subccc	$tj,	$nj,	$t2	! tp[j]-np[j]
-	srlx	$tj,	32,	$tj
-	srlx	$nj,	32,	$nj
-	subccc	$tj,	$nj,	$t3
-	add	$rp,	8,	$rp
-	st	$t2,	[$rp-4]		! reverse order
-	st	$t3,	[$rp-8]
-	brnz,pt	$cnt,	.Lsub
-	sub	$cnt,	8,	$cnt
-
-	sub	$np,	$num,	$np	! rewind
-	sub	$tp,	$num,	$tp
-	sub	$rp,	$num,	$rp
-
-	subc	$ovf,	%g0,	$ovf	! handle upmost overflow bit
-	and	$tp,	$ovf,	$ap
-	andn	$rp,	$ovf,	$np
-	or	$np,	$ap,	$ap	! ap=borrow?tp:rp
-	ba	.Lcopy
-	sub	$num,	8,	$cnt
-
-.align	16
-.Lcopy:					! copy or in-place refresh
-	ldx	[$ap+0],	$t2
-	add	$ap,	8,	$ap
-	stx	%g0,	[$tp]		! zap
-	add	$tp,	8,	$tp
-	stx	$t2,	[$rp+0]
-	add	$rp,	8,	$rp
-	brnz	$cnt,	.Lcopy
-	sub	$cnt,	8,	$cnt
-
-	mov	1,	%o0
-	ret
-	restore
-.type	bn_mul_mont_t4, #function
-.size	bn_mul_mont_t4, .-bn_mul_mont_t4
-___
-
-# int bn_mul_mont_gather5(
-$rp="%o0";	# u64 *rp,
-$ap="%o1";	# const u64 *ap,
-$bp="%o2";	# const u64 *pwrtbl,
-$np="%o3";	# const u64 *np,
-$n0p="%o4";	# const BN_ULONG *n0,
-$num="%o5";	# int num,	# caller ensures that num is >=3
-		# int power);
-$code.=<<___;
-.globl	bn_mul_mont_gather5_t4
-.align	32
-bn_mul_mont_gather5_t4:
-	add	%sp,	STACK_BIAS,	%g4	! real top of stack
-	sll	$num,	3,	$num		! size in bytes
-	add	$num,	63,	%g1
-	andn	%g1,	63,	%g1		! buffer size rounded up to 64 bytes
-	sub	%g4,	%g1,	%g1
-	andn	%g1,	63,	%g1		! align at 64 byte
-	sub	%g1,	STACK_FRAME,	%g1	! new top of stack
-	sub	%g1,	%g4,	%g1
-	LDPTR	[%sp+STACK_7thARG],	%g4	! load power, 7th argument
-
-	save	%sp,	%g1,	%sp
-___
-#	+-------------------------------+<-----	%sp
-#	.				.
-#	+-------------------------------+<-----	aligned at 64 bytes
-#	| __int64 tmp[0]		|
-#	+-------------------------------+
-#	.				.
-#	.				.
-#	+-------------------------------+<-----	aligned at 64 bytes
-#	.				.
-($rp,$ap,$bp,$np,$n0p,$num)=map("%i$_",(0..5));
-($t0,$t1,$t2,$t3,$cnt,$tp,$bufsz,$ccr)=map("%l$_",(0..7));
-($ovf,$i)=($t0,$t1);
-	&load_ccr($bp,"%g4",$ccr);
-	&load_b($bp,$m0,"%o7");		# m0=bp[0]
-
-$code.=<<___;
-	ld	[$n0p+0],	$t0	! pull n0[0..1] value
-	ld	[$n0p+4],	$t1
-	add	%sp, STACK_BIAS+STACK_FRAME, $tp
-	sllx	$t1,	32,	$n0
-	or	$t0,	$n0,	$n0
-
-	ldx	[$ap+0],	$aj	! ap[0]
-
-	mulx	$aj,	$m0,	$lo0	! ap[0]*bp[0]
-	umulxhi	$aj,	$m0,	$hi0
-
-	ldx	[$ap+8],	$aj	! ap[1]
-	add	$ap,	16,	$ap
-	ldx	[$np+0],	$nj	! np[0]
-
-	mulx	$lo0,	$n0,	$m1	! "tp[0]"*n0
-
-	mulx	$aj,	$m0,	$alo	! ap[1]*bp[0]
-	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-
-	mulx	$nj,	$m1,	$lo1	! np[0]*m1
-	umulxhi	$nj,	$m1,	$hi1
-
-	ldx	[$np+8],	$nj	! np[1]
-
-	addcc	$lo0,	$lo1,	$lo1
-	add	$np,	16,	$np
-	addxc	%g0,	$hi1,	$hi1
-
-	mulx	$nj,	$m1,	$nlo	! np[1]*m1
-	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-
-	ba	.L1st_g5
-	sub	$num,	24,	$cnt	! cnt=num-3
-
-.align	16
-.L1st_g5:
-	addcc	$alo,	$hi0,	$lo0
-	addxc	$aj,	%g0,	$hi0
-
-	ldx	[$ap+0],	$aj	! ap[j]
-	addcc	$nlo,	$hi1,	$lo1
-	add	$ap,	8,	$ap
-	addxc	$nj,	%g0,	$hi1	! nhi=nj
-
-	ldx	[$np+0],	$nj	! np[j]
-	mulx	$aj,	$m0,	$alo	! ap[j]*bp[0]
-	add	$np,	8,	$np
-	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-
-	mulx	$nj,	$m1,	$nlo	! np[j]*m1
-	addcc	$lo0,	$lo1,	$lo1	! np[j]*m1+ap[j]*bp[0]
-	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-	addxc	%g0,	$hi1,	$hi1
-	stxa	$lo1,	[$tp]0xe2	! tp[j-1]
-	add	$tp,	8,	$tp	! tp++
-
-	brnz,pt	$cnt,	.L1st_g5
-	sub	$cnt,	8,	$cnt	! j--
-!.L1st_g5
-	addcc	$alo,	$hi0,	$lo0
-	addxc	$aj,	%g0,	$hi0	! ahi=aj
-
-	addcc	$nlo,	$hi1,	$lo1
-	addxc	$nj,	%g0,	$hi1
-	addcc	$lo0,	$lo1,	$lo1	! np[j]*m1+ap[j]*bp[0]
-	addxc	%g0,	$hi1,	$hi1
-	stxa	$lo1,	[$tp]0xe2	! tp[j-1]
-	add	$tp,	8,	$tp
-
-	addcc	$hi0,	$hi1,	$hi1
-	addxc	%g0,	%g0,	$ovf	! upmost overflow bit
-	stxa	$hi1,	[$tp]0xe2
-	add	$tp,	8,	$tp
-
-	ba	.Louter_g5
-	sub	$num,	16,	$i	! i=num-2
-
-.align	16
-.Louter_g5:
-	wr	$ccr,	%g0,	%ccr
-___
-	&load_b($bp,$m0);		# m0=bp[i]
-$code.=<<___;
-	sub	$ap,	$num,	$ap	! rewind
-	sub	$np,	$num,	$np
-	sub	$tp,	$num,	$tp
-
-	ldx	[$ap+0],	$aj	! ap[0]
-	ldx	[$np+0],	$nj	! np[0]
-
-	mulx	$aj,	$m0,	$lo0	! ap[0]*bp[i]
-	ldx	[$tp],		$tj	! tp[0]
-	umulxhi	$aj,	$m0,	$hi0
-	ldx	[$ap+8],	$aj	! ap[1]
-	addcc	$lo0,	$tj,	$lo0	! ap[0]*bp[i]+tp[0]
-	mulx	$aj,	$m0,	$alo	! ap[1]*bp[i]
-	addxc	%g0,	$hi0,	$hi0
-	mulx	$lo0,	$n0,	$m1	! tp[0]*n0
-	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-	mulx	$nj,	$m1,	$lo1	! np[0]*m1
-	add	$ap,	16,	$ap
-	umulxhi	$nj,	$m1,	$hi1
-	ldx	[$np+8],	$nj	! np[1]
-	add	$np,	16,	$np
-	addcc	$lo1,	$lo0,	$lo1
-	mulx	$nj,	$m1,	$nlo	! np[1]*m1
-	addxc	%g0,	$hi1,	$hi1
-	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-
-	ba	.Linner_g5
-	sub	$num,	24,	$cnt	! cnt=num-3
-.align	16
-.Linner_g5:
-	addcc	$alo,	$hi0,	$lo0
-	ldx	[$tp+8],	$tj	! tp[j]
-	addxc	$aj,	%g0,	$hi0	! ahi=aj
-	ldx	[$ap+0],	$aj	! ap[j]
-	add	$ap,	8,	$ap
-	addcc	$nlo,	$hi1,	$lo1
-	mulx	$aj,	$m0,	$alo	! ap[j]*bp[i]
-	addxc	$nj,	%g0,	$hi1	! nhi=nj
-	ldx	[$np+0],	$nj	! np[j]
-	add	$np,	8,	$np
-	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-	addcc	$lo0,	$tj,	$lo0	! ap[j]*bp[i]+tp[j]
-	mulx	$nj,	$m1,	$nlo	! np[j]*m1
-	addxc	%g0,	$hi0,	$hi0
-	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-	addcc	$lo1,	$lo0,	$lo1	! np[j]*m1+ap[j]*bp[i]+tp[j]
-	addxc	%g0,	$hi1,	$hi1
-	stx	$lo1,	[$tp]		! tp[j-1]
-	add	$tp,	8,	$tp
-	brnz,pt	$cnt,	.Linner_g5
-	sub	$cnt,	8,	$cnt
-!.Linner_g5
-	ldx	[$tp+8],	$tj	! tp[j]
-	addcc	$alo,	$hi0,	$lo0
-	addxc	$aj,	%g0,	$hi0	! ahi=aj
-	addcc	$lo0,	$tj,	$lo0	! ap[j]*bp[i]+tp[j]
-	addxc	%g0,	$hi0,	$hi0
-
-	addcc	$nlo,	$hi1,	$lo1
-	addxc	$nj,	%g0,	$hi1	! nhi=nj
-	addcc	$lo1,	$lo0,	$lo1	! np[j]*m1+ap[j]*bp[i]+tp[j]
-	addxc	%g0,	$hi1,	$hi1
-	stx	$lo1,	[$tp]		! tp[j-1]
-
-	subcc	%g0,	$ovf,	%g0	! move upmost overflow to CCR.xcc
-	addxccc	$hi1,	$hi0,	$hi1
-	addxc	%g0,	%g0,	$ovf
-	stx	$hi1,	[$tp+8]
-	add	$tp,	16,	$tp
-
-	brnz,pt	$i,	.Louter_g5
-	sub	$i,	8,	$i
-
-	sub	$ap,	$num,	$ap	! rewind
-	sub	$np,	$num,	$np
-	sub	$tp,	$num,	$tp
-	ba	.Lsub_g5
-	subcc	$num,	8,	$cnt	! cnt=num-1 and clear CCR.xcc
-
-.align	16
-.Lsub_g5:
-	ldx	[$tp],		$tj
-	add	$tp,	8,	$tp
-	ldx	[$np+0],	$nj
-	add	$np,	8,	$np
-	subccc	$tj,	$nj,	$t2	! tp[j]-np[j]
-	srlx	$tj,	32,	$tj
-	srlx	$nj,	32,	$nj
-	subccc	$tj,	$nj,	$t3
-	add	$rp,	8,	$rp
-	st	$t2,	[$rp-4]		! reverse order
-	st	$t3,	[$rp-8]
-	brnz,pt	$cnt,	.Lsub_g5
-	sub	$cnt,	8,	$cnt
-
-	sub	$np,	$num,	$np	! rewind
-	sub	$tp,	$num,	$tp
-	sub	$rp,	$num,	$rp
-
-	subc	$ovf,	%g0,	$ovf	! handle upmost overflow bit
-	and	$tp,	$ovf,	$ap
-	andn	$rp,	$ovf,	$np
-	or	$np,	$ap,	$ap	! ap=borrow?tp:rp
-	ba	.Lcopy_g5
-	sub	$num,	8,	$cnt
-
-.align	16
-.Lcopy_g5:				! copy or in-place refresh
-	ldx	[$ap+0],	$t2
-	add	$ap,	8,	$ap
-	stx	%g0,	[$tp]		! zap
-	add	$tp,	8,	$tp
-	stx	$t2,	[$rp+0]
-	add	$rp,	8,	$rp
-	brnz	$cnt,	.Lcopy_g5
-	sub	$cnt,	8,	$cnt
-
-	mov	1,	%o0
-	ret
-	restore
-.type	bn_mul_mont_gather5_t4, #function
-.size	bn_mul_mont_gather5_t4, .-bn_mul_mont_gather5_t4
-___
-}
-
-$code.=<<___;
-.globl	bn_flip_t4
-.align	32
-bn_flip_t4:
-.Loop_flip:
-	ld	[%o1+0],	%o4
-	sub	%o2,	1,	%o2
-	ld	[%o1+4],	%o5
-	add	%o1,	8,	%o1
-	st	%o5,	[%o0+0]
-	st	%o4,	[%o0+4]
-	brnz	%o2,	.Loop_flip
-	add	%o0,	8,	%o0
-	retl
-	nop
-.type	bn_flip_t4, #function
-.size	bn_flip_t4, .-bn_flip_t4
-
-.globl	bn_flip_n_scatter5_t4
-.align	32
-bn_flip_n_scatter5_t4:
-	sll	%o3,	3,	%o3
-	srl	%o1,	1,	%o1
-	add	%o3,	%o2,	%o2	! &pwrtbl[pwr]
-	sub	%o1,	1,	%o1
-.Loop_flip_n_scatter5:
-	ld	[%o0+0],	%o4	! inp[i]
-	ld	[%o0+4],	%o5
-	add	%o0,	8,	%o0
-	sllx	%o5,	32,	%o5
-	or	%o4,	%o5,	%o5
-	stx	%o5,	[%o2]
-	add	%o2,	32*8,	%o2
-	brnz	%o1,	.Loop_flip_n_scatter5
-	sub	%o1,	1,	%o1
-	retl
-	nop
-.type	bn_flip_n_scatter5_t4, #function
-.size	bn_flip_n_scatter5_t4, .-bn_flip_n_scatter5_t4
-
-.globl	bn_gather5_t4
-.align	32
-bn_gather5_t4:
-___
-	&load_ccr("%o2","%o3","%g1");
-$code.=<<___;
-	sub	%o1,	1,	%o1
-.Loop_gather5:
-___
-	&load_b("%o2","%g1");
-$code.=<<___;
-	stx	%g1,	[%o0]
-	add	%o0,	8,	%o0
-	brnz	%o1,	.Loop_gather5
-	sub	%o1,	1,	%o1
-
-	retl
-	nop
-.type	bn_gather5_t4, #function
-.size	bn_gather5_t4, .-bn_gather5_t4
-
-.asciz	"Montgomery Multiplication for SPARC T4, David S. Miller, Andy Polyakov"
-.align	4
-___
-
-&emit_assembler();
-
-close STDOUT;
--- a/components/openssl/openssl-1.0.1/inline-t4/sparcv9-gf2m.pl	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,198 +0,0 @@
-#!/usr/bin/env perl
-#
-# ====================================================================
-# Written by Andy Polyakov <[email protected]> for the OpenSSL
-# project. The module is, however, dual licensed under OpenSSL and
-# CRYPTOGAMS licenses depending on where you obtain it. For further
-# details see http://www.openssl.org/~appro/cryptogams/.
-# ====================================================================
-#
-# October 2012
-#
-# The module implements bn_GF2m_mul_2x2 polynomial multiplication used
-# in bn_gf2m.c. It's kind of low-hanging mechanical port from C for
-# the time being... Except that it has two code paths: one suitable
-# for all SPARCv9 processors and one for VIS3-capable ones. Former
-# delivers ~25-45% more, more for longer keys, heaviest DH and DSA
-# verify operations on venerable UltraSPARC II. On T4 VIS3 code is
-# ~100-230% faster than gcc-generated code and ~35-90% faster than
-# the pure SPARCv9 code path.
-
-$bits=32;
-for (@ARGV)     { $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
-if ($bits==64)  { $bias=2047; $frame=192; }
-else            { $bias=0;    $frame=112; }
-
-$locals=16*8;
-
-$code.=<<___;
-#include <sparc_arch.h>
-
-.section        ".text",#alloc,#execinstr
-___
-$code.=<<___ if ($bits==64);
-.register       %g2,#scratch
-.register       %g3,#scratch
-___
-
-$tab="%l0";
-
-@T=("%g2","%g3");
-@i=("%g4","%g5");
-
-($a1,$a2,$a4,$a8,$a12,$a48)=map("%o$_",(0..5));
-($lo,$hi,$b)=("%g1",$a8,"%o7"); $a=$lo;
-
-$code.=<<___;
-#ifdef __PIC__
-SPARC_PIC_THUNK(%g1)
-#endif
-
-.globl	bn_GF2m_mul_2x2
-.align	16
-bn_GF2m_mul_2x2:
-        SPARC_LOAD_ADDRESS_LEAF(OPENSSL_sparcv9cap_P,%g1,%g5)
-        ld	[%g1+0],%g1             	! OPENSSL_sparcv9cap_P[0]
-
-        andcc	%g1, SPARCV9_VIS3, %g0
-        bz,pn	%icc,.Lsoftware
-        nop
-
-	sllx	%o1, 32, %o1
-	sllx	%o3, 32, %o3
-	or	%o2, %o1, %o1
-	or	%o4, %o3, %o3
-	.word	0x95b262ab			! xmulx   %o1, %o3, %o2
-	.word	0x99b262cb			! xmulxhi %o1, %o3, %o4
-	srlx	%o2, 32, %o1			! 13 cycles later
-	st	%o2, [%o0+0]
-	st	%o1, [%o0+4]
-	srlx	%o4, 32, %o3
-	st	%o4, [%o0+8]
-	retl
-	st	%o3, [%o0+12]
-
-.align	16
-.Lsoftware:
-	save	%sp,-$frame-$locals,%sp
-
-	sllx	%i1,32,$a
-	mov	-1,$a12
-	sllx	%i3,32,$b
-	or	%i2,$a,$a
-	srlx	$a12,1,$a48			! 0x7fff...
-	or	%i4,$b,$b
-	srlx	$a12,2,$a12			! 0x3fff...
-	add	%sp,$bias+$frame,$tab
-
-	sllx	$a,2,$a4
-	mov	$a,$a1
-	sllx	$a,1,$a2
-
-	srax	$a4,63,@i[1]			! broadcast 61st bit
-	and	$a48,$a4,$a4			! (a<<2)&0x7fff...
-	srlx	$a48,2,$a48
-	srax	$a2,63,@i[0]			! broadcast 62nd bit
-	and	$a12,$a2,$a2			! (a<<1)&0x3fff...
-	srax	$a1,63,$lo			! broadcast 63rd bit
-	and	$a48,$a1,$a1			! (a<<0)&0x1fff...
-
-	sllx	$a1,3,$a8
-	and	$b,$lo,$lo
-	and	$b,@i[0],@i[0]
-	and	$b,@i[1],@i[1]
-
-	stx	%g0,[$tab+0*8]			! tab[0]=0
-	xor	$a1,$a2,$a12
-	stx	$a1,[$tab+1*8]			! tab[1]=a1
-	stx	$a2,[$tab+2*8]			! tab[2]=a2
-	 xor	$a4,$a8,$a48
-	stx	$a12,[$tab+3*8]			! tab[3]=a1^a2
-	 xor	$a4,$a1,$a1
-
-	stx	$a4,[$tab+4*8]			! tab[4]=a4
-	xor	$a4,$a2,$a2
-	stx	$a1,[$tab+5*8]			! tab[5]=a1^a4
-	xor	$a4,$a12,$a12
-	stx	$a2,[$tab+6*8]			! tab[6]=a2^a4
-	 xor	$a48,$a1,$a1
-	stx	$a12,[$tab+7*8]			! tab[7]=a1^a2^a4
-	 xor	$a48,$a2,$a2
-
-	stx	$a8,[$tab+8*8]			! tab[8]=a8
-	xor	$a48,$a12,$a12
-	stx	$a1,[$tab+9*8]			! tab[9]=a1^a8
-	 xor	$a4,$a1,$a1
-	stx	$a2,[$tab+10*8]			! tab[10]=a2^a8
-	 xor	$a4,$a2,$a2
-	stx	$a12,[$tab+11*8]		! tab[11]=a1^a2^a8
-
-	xor	$a4,$a12,$a12
-	stx	$a48,[$tab+12*8]		! tab[12]=a4^a8
-	 srlx	$lo,1,$hi
-	stx	$a1,[$tab+13*8]			! tab[13]=a1^a4^a8
-	 sllx	$lo,63,$lo
-	stx	$a2,[$tab+14*8]			! tab[14]=a2^a4^a8
-	 srlx	@i[0],2,@T[0]
-	stx	$a12,[$tab+15*8]		! tab[15]=a1^a2^a4^a8
-
-	sllx	@i[0],62,$a1
-	 sllx	$b,3,@i[0]
-	srlx	@i[1],3,@T[1]
-	 and	@i[0],`0xf<<3`,@i[0]
-	sllx	@i[1],61,$a2
-	 ldx	[$tab+@i[0]],@i[0]
-	 srlx	$b,4-3,@i[1]
-	xor	@T[0],$hi,$hi
-	 and	@i[1],`0xf<<3`,@i[1]
-	xor	$a1,$lo,$lo
-	 ldx	[$tab+@i[1]],@i[1]
-	xor	@T[1],$hi,$hi
-
-	xor	@i[0],$lo,$lo
-	srlx	$b,8-3,@i[0]
-	 xor	$a2,$lo,$lo
-	and	@i[0],`0xf<<3`,@i[0]
-___
-for($n=1;$n<14;$n++) {
-$code.=<<___;
-	sllx	@i[1],`$n*4`,@T[0]
-	ldx	[$tab+@i[0]],@i[0]
-	srlx	@i[1],`64-$n*4`,@T[1]
-	xor	@T[0],$lo,$lo
-	srlx	$b,`($n+2)*4`-3,@i[1]
-	xor	@T[1],$hi,$hi
-	and	@i[1],`0xf<<3`,@i[1]
-___
-	push(@i,shift(@i)); push(@T,shift(@T));
-}
-$code.=<<___;
-	sllx	@i[1],`$n*4`,@T[0]
-	ldx	[$tab+@i[0]],@i[0]
-	srlx	@i[1],`64-$n*4`,@T[1]
-	xor	@T[0],$lo,$lo
-
-	sllx	@i[0],`($n+1)*4`,@T[0]
-	 xor	@T[1],$hi,$hi
-	srlx	@i[0],`64-($n+1)*4`,@T[1]
-	xor	@T[0],$lo,$lo
-	xor	@T[1],$hi,$hi
-
-	srlx	$lo,32,%i1
-	st	$lo,[%i0+0]
-	st	%i1,[%i0+4]
-	srlx	$hi,32,%i2
-	st	$hi,[%i0+8]
-	st	%i2,[%i0+12]
-
-	ret
-	restore
-.type	bn_GF2m_mul_2x2,#function
-.size	bn_GF2m_mul_2x2,.-bn_GF2m_mul_2x2
-.asciz	"GF(2^m) Multiplication for SPARCv9, CRYPTOGAMS by <appro\@openssl.org>"
-.align	4
-___
-
-$code =~ s/\`([^\`]*)\`/eval($1)/gem;
-print $code;
-close STDOUT;
--- a/components/openssl/openssl-1.0.1/inline-t4/sparcv9_modes.pl	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1686 +0,0 @@
-#!/usr/bin/env perl
-
-# Specific modes implementations for SPARC Architecture 2011. There
-# is T4 dependency though, an ASI value that is not specified in the
-# Architecture Manual. But as SPARC universe is rather monocultural,
-# we imply that processor capable of executing crypto instructions
-# can handle the ASI in question as well. This means that we ought to
-# keep eyes open when new processors emerge...
-#
-# As for above mentioned ASI. It's so called "block initializing
-# store" which cancels "read" in "read-update-write" on cache lines.
-# This is "cooperative" optimization, as it reduces overall pressure
-# on memory interface. Benefits can't be observed/quantified with
-# usual benchmarks, on the contrary you can notice that single-thread
-# performance for parallelizable modes is ~1.5% worse for largest
-# block sizes [though few percent better for not so long ones]. All
-# this based on suggestions from David Miller.
-
-sub asm_init {		# to be called with @ARGV as argument
-    for (@_)		{ $::abibits=64 if (/\-m64/ || /\-xarch\=v9/); }
-    if ($::abibits==64)	{ $::bias=2047; $::frame=192; $::size_t_cc="%xcc"; }
-    else		{ $::bias=0;    $::frame=112; $::size_t_cc="%icc"; }
-}
-
-# unified interface
-my ($inp,$out,$len,$key,$ivec)=map("%i$_",(0..5));
-# local variables
-my ($ileft,$iright,$ooff,$omask,$ivoff,$blk_init)=map("%l$_",(0..7));
-
-sub alg_cbc_encrypt_implement {
-my ($alg,$bits) = @_;
-
-$::code.=<<___;
-.globl	${alg}${bits}_t4_cbc_encrypt
-.align	32
-${alg}${bits}_t4_cbc_encrypt:
-	save		%sp, -$::frame, %sp
-	cmp		$len, 0
-	be,pn		$::size_t_cc, .L${bits}_cbc_enc_abort
-	sub		$inp, $out, $blk_init	! $inp!=$out
-___
-$::code.=<<___ if (!$::evp);
-	andcc		$ivec, 7, $ivoff
-	alignaddr	$ivec, %g0, $ivec
-
-	ldd		[$ivec + 0], %f0	! load ivec
-	bz,pt		%icc, 1f
-	ldd		[$ivec + 8], %f2
-	ldd		[$ivec + 16], %f4
-	faligndata	%f0, %f2, %f0
-	faligndata	%f2, %f4, %f2
-1:
-___
-$::code.=<<___ if ($::evp);
-	ld		[$ivec + 0], %f0
-	ld		[$ivec + 4], %f1
-	ld		[$ivec + 8], %f2
-	ld		[$ivec + 12], %f3
-___
-$::code.=<<___;
-	prefetch	[$inp], 20
-	prefetch	[$inp + 63], 20
-	call		_${alg}${bits}_load_enckey
-	and		$inp, 7, $ileft
-	andn		$inp, 7, $inp
-	sll		$ileft, 3, $ileft
-	mov		64, $iright
-	mov		0xff, $omask
-	sub		$iright, $ileft, $iright
-	and		$out, 7, $ooff
-	cmp		$len, 127
-	movrnz		$ooff, 0, $blk_init		! if (	$out&7 ||
-	movleu		$::size_t_cc, 0, $blk_init	!	$len<128 ||
-	brnz,pn		$blk_init, .L${bits}cbc_enc_blk	!	$inp==$out)
-	srl		$omask, $ooff, $omask
-
-	alignaddrl	$out, %g0, $out
-	srlx		$len, 4, $len
-	prefetch	[$out], 22
-
-.L${bits}_cbc_enc_loop:
-	ldx		[$inp + 0], %o0
-	brz,pt		$ileft, 4f
-	ldx		[$inp + 8], %o1
-
-	ldx		[$inp + 16], %o2
-	sllx		%o0, $ileft, %o0
-	srlx		%o1, $iright, %g1
-	sllx		%o1, $ileft, %o1
-	or		%g1, %o0, %o0
-	srlx		%o2, $iright, %o2
-	or		%o2, %o1, %o1
-4:
-	xor		%g4, %o0, %o0		! ^= rk[0]
-	xor		%g5, %o1, %o1
-	movxtod		%o0, %f12
-	movxtod		%o1, %f14
-
-	fxor		%f12, %f0, %f0		! ^= ivec
-	fxor		%f14, %f2, %f2
-	prefetch	[$out + 63], 22
-	prefetch	[$inp + 16+63], 20
-	call		_${alg}${bits}_encrypt_1x
-	add		$inp, 16, $inp
-
-	brnz,pn		$ooff, 2f
-	sub		$len, 1, $len
-		
-	std		%f0, [$out + 0]
-	std		%f2, [$out + 8]
-	brnz,pt		$len, .L${bits}_cbc_enc_loop
-	add		$out, 16, $out
-___
-$::code.=<<___ if ($::evp);
-	st		%f0, [$ivec + 0]
-	st		%f1, [$ivec + 4]
-	st		%f2, [$ivec + 8]
-	st		%f3, [$ivec + 12]
-___
-$::code.=<<___ if (!$::evp);
-	brnz,pn		$ivoff, 3f
-	nop
-
-	std		%f0, [$ivec + 0]	! write out ivec
-	std		%f2, [$ivec + 8]
-___
-$::code.=<<___;
-.L${bits}_cbc_enc_abort:
-	ret
-	restore
-
-.align	16
-2:	ldxa		[$inp]0x82, %o0		! avoid read-after-write hazard
-						! and ~3x deterioration
-						! in inp==out case
-	faligndata	%f0, %f0, %f4		! handle unaligned output
-	faligndata	%f0, %f2, %f6
-	faligndata	%f2, %f2, %f8
-
-	stda		%f4, [$out + $omask]0xc0	! partial store
-	std		%f6, [$out + 8]
-	add		$out, 16, $out
-	orn		%g0, $omask, $omask
-	stda		%f8, [$out + $omask]0xc0	! partial store
-
-	brnz,pt		$len, .L${bits}_cbc_enc_loop+4
-	orn		%g0, $omask, $omask
-___
-$::code.=<<___ if ($::evp);
-	st		%f0, [$ivec + 0]
-	st		%f1, [$ivec + 4]
-	st		%f2, [$ivec + 8]
-	st		%f3, [$ivec + 12]
-___
-$::code.=<<___ if (!$::evp);
-	brnz,pn		$ivoff, 3f
-	nop
-
-	std		%f0, [$ivec + 0]	! write out ivec
-	std		%f2, [$ivec + 8]
-	ret
-	restore
-
-.align	16
-3:	alignaddrl	$ivec, $ivoff, %g0	! handle unaligned ivec
-	mov		0xff, $omask
-	srl		$omask, $ivoff, $omask
-	faligndata	%f0, %f0, %f4
-	faligndata	%f0, %f2, %f6
-	faligndata	%f2, %f2, %f8
-	stda		%f4, [$ivec + $omask]0xc0
-	std		%f6, [$ivec + 8]
-	add		$ivec, 16, $ivec
-	orn		%g0, $omask, $omask
-	stda		%f8, [$ivec + $omask]0xc0
-___
-$::code.=<<___;
-	ret
-	restore
-
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-.align	32
-.L${bits}cbc_enc_blk:
-	add	$out, $len, $blk_init
-	and	$blk_init, 63, $blk_init	! tail
-	sub	$len, $blk_init, $len
-	add	$blk_init, 15, $blk_init	! round up to 16n
-	srlx	$len, 4, $len
-	srl	$blk_init, 4, $blk_init
-
-.L${bits}_cbc_enc_blk_loop:
-	ldx		[$inp + 0], %o0
-	brz,pt		$ileft, 5f
-	ldx		[$inp + 8], %o1
-
-	ldx		[$inp + 16], %o2
-	sllx		%o0, $ileft, %o0
-	srlx		%o1, $iright, %g1
-	sllx		%o1, $ileft, %o1
-	or		%g1, %o0, %o0
-	srlx		%o2, $iright, %o2
-	or		%o2, %o1, %o1
-5:
-	xor		%g4, %o0, %o0		! ^= rk[0]
-	xor		%g5, %o1, %o1
-	movxtod		%o0, %f12
-	movxtod		%o1, %f14
-
-	fxor		%f12, %f0, %f0		! ^= ivec
-	fxor		%f14, %f2, %f2
-	prefetch	[$inp + 16+63], 20
-	call		_${alg}${bits}_encrypt_1x
-	add		$inp, 16, $inp
-	sub		$len, 1, $len
-		
-	stda		%f0, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-	add		$out, 8, $out
-	stda		%f2, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-	brnz,pt		$len, .L${bits}_cbc_enc_blk_loop
-	add		$out, 8, $out
-
-	membar		#StoreLoad|#StoreStore
-	brnz,pt		$blk_init, .L${bits}_cbc_enc_loop
-	mov		$blk_init, $len
-___
-$::code.=<<___ if ($::evp);
-	st		%f0, [$ivec + 0]
-	st		%f1, [$ivec + 4]
-	st		%f2, [$ivec + 8]
-	st		%f3, [$ivec + 12]
-___
-$::code.=<<___ if (!$::evp);
-	brnz,pn		$ivoff, 3b
-	nop
-
-	std		%f0, [$ivec + 0]	! write out ivec
-	std		%f2, [$ivec + 8]
-___
-$::code.=<<___;
-	ret
-	restore
-.type	${alg}${bits}_t4_cbc_encrypt,#function
-.size	${alg}${bits}_t4_cbc_encrypt,.-${alg}${bits}_t4_cbc_encrypt
-___
-}
-
-sub alg_cbc_decrypt_implement {
-my ($alg,$bits) = @_;
-
-$::code.=<<___;
-.globl	${alg}${bits}_t4_cbc_decrypt
-.align	32
-${alg}${bits}_t4_cbc_decrypt:
-	save		%sp, -$::frame, %sp
-	cmp		$len, 0
-	be,pn		$::size_t_cc, .L${bits}_cbc_dec_abort
-	sub		$inp, $out, $blk_init	! $inp!=$out
-___
-$::code.=<<___ if (!$::evp);
-	andcc		$ivec, 7, $ivoff
-	alignaddr	$ivec, %g0, $ivec
-
-	ldd		[$ivec + 0], %f12	! load ivec
-	bz,pt		%icc, 1f
-	ldd		[$ivec + 8], %f14
-	ldd		[$ivec + 16], %f0
-	faligndata	%f12, %f14, %f12
-	faligndata	%f14, %f0, %f14
-1:
-___
-$::code.=<<___ if ($::evp);
-	ld		[$ivec + 0], %f12	! load ivec
-	ld		[$ivec + 4], %f13
-	ld		[$ivec + 8], %f14
-	ld		[$ivec + 12], %f15
-___
-$::code.=<<___;
-	prefetch	[$inp], 20
-	prefetch	[$inp + 63], 20
-	call		_${alg}${bits}_load_deckey
-	and		$inp, 7, $ileft
-	andn		$inp, 7, $inp
-	sll		$ileft, 3, $ileft
-	mov		64, $iright
-	mov		0xff, $omask
-	sub		$iright, $ileft, $iright
-	and		$out, 7, $ooff
-	cmp		$len, 255
-	movrnz		$ooff, 0, $blk_init		! if (	$out&7 ||
-	movleu		$::size_t_cc, 0, $blk_init	!	$len<256 ||
-	brnz,pn		$blk_init, .L${bits}cbc_dec_blk	!	$inp==$out)
-	srl		$omask, $ooff, $omask
-
-	andcc		$len, 16, %g0		! is number of blocks even?
-	srlx		$len, 4, $len
-	alignaddrl	$out, %g0, $out
-	bz		%icc, .L${bits}_cbc_dec_loop2x
-	prefetch	[$out], 22
-.L${bits}_cbc_dec_loop:
-	ldx		[$inp + 0], %o0
-	brz,pt		$ileft, 4f
-	ldx		[$inp + 8], %o1
-
-	ldx		[$inp + 16], %o2
-	sllx		%o0, $ileft, %o0
-	srlx		%o1, $iright, %g1
-	sllx		%o1, $ileft, %o1
-	or		%g1, %o0, %o0
-	srlx		%o2, $iright, %o2
-	or		%o2, %o1, %o1
-4:
-	xor		%g4, %o0, %o2		! ^= rk[0]
-	xor		%g5, %o1, %o3
-	movxtod		%o2, %f0
-	movxtod		%o3, %f2
-
-	prefetch	[$out + 63], 22
-	prefetch	[$inp + 16+63], 20
-	call		_${alg}${bits}_decrypt_1x
-	add		$inp, 16, $inp
-
-	fxor		%f12, %f0, %f0		! ^= ivec
-	fxor		%f14, %f2, %f2
-	movxtod		%o0, %f12
-	movxtod		%o1, %f14
-
-	brnz,pn		$ooff, 2f
-	sub		$len, 1, $len
-		
-	std		%f0, [$out + 0]
-	std		%f2, [$out + 8]
-	brnz,pt		$len, .L${bits}_cbc_dec_loop2x
-	add		$out, 16, $out
-___
-$::code.=<<___ if ($::evp);
-	st		%f12, [$ivec + 0]
-	st		%f13, [$ivec + 4]
-	st		%f14, [$ivec + 8]
-	st		%f15, [$ivec + 12]
-___
-$::code.=<<___ if (!$::evp);
-	brnz,pn		$ivoff, .L${bits}_cbc_dec_unaligned_ivec
-	nop
-
-	std		%f12, [$ivec + 0]	! write out ivec
-	std		%f14, [$ivec + 8]
-___
-$::code.=<<___;
-.L${bits}_cbc_dec_abort:
-	ret
-	restore
-
-.align	16
-2:	ldxa		[$inp]0x82, %o0		! avoid read-after-write hazard
-						! and ~3x deterioration
-						! in inp==out case
-	faligndata	%f0, %f0, %f4		! handle unaligned output
-	faligndata	%f0, %f2, %f6
-	faligndata	%f2, %f2, %f8
-
-	stda		%f4, [$out + $omask]0xc0	! partial store
-	std		%f6, [$out + 8]
-	add		$out, 16, $out
-	orn		%g0, $omask, $omask
-	stda		%f8, [$out + $omask]0xc0	! partial store
-
-	brnz,pt		$len, .L${bits}_cbc_dec_loop2x+4
-	orn		%g0, $omask, $omask
-___
-$::code.=<<___ if ($::evp);
-	st		%f12, [$ivec + 0]
-	st		%f13, [$ivec + 4]
-	st		%f14, [$ivec + 8]
-	st		%f15, [$ivec + 12]
-___
-$::code.=<<___ if (!$::evp);
-	brnz,pn		$ivoff, .L${bits}_cbc_dec_unaligned_ivec
-	nop
-
-	std		%f12, [$ivec + 0]	! write out ivec
-	std		%f14, [$ivec + 8]
-___
-$::code.=<<___;
-	ret
-	restore
-
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-.align	32
-.L${bits}_cbc_dec_loop2x:
-	ldx		[$inp + 0], %o0
-	ldx		[$inp + 8], %o1
-	ldx		[$inp + 16], %o2
-	brz,pt		$ileft, 4f
-	ldx		[$inp + 24], %o3
-
-	ldx		[$inp + 32], %o4
-	sllx		%o0, $ileft, %o0
-	srlx		%o1, $iright, %g1
-	or		%g1, %o0, %o0
-	sllx		%o1, $ileft, %o1
-	srlx		%o2, $iright, %g1
-	or		%g1, %o1, %o1
-	sllx		%o2, $ileft, %o2
-	srlx		%o3, $iright, %g1
-	or		%g1, %o2, %o2
-	sllx		%o3, $ileft, %o3
-	srlx		%o4, $iright, %o4
-	or		%o4, %o3, %o3
-4:
-	xor		%g4, %o0, %o4		! ^= rk[0]
-	xor		%g5, %o1, %o5
-	movxtod		%o4, %f0
-	movxtod		%o5, %f2
-	xor		%g4, %o2, %o4
-	xor		%g5, %o3, %o5
-	movxtod		%o4, %f4
-	movxtod		%o5, %f6
-
-	prefetch	[$out + 63], 22
-	prefetch	[$inp + 32+63], 20
-	call		_${alg}${bits}_decrypt_2x
-	add		$inp, 32, $inp
-
-	movxtod		%o0, %f8
-	movxtod		%o1, %f10
-	fxor		%f12, %f0, %f0		! ^= ivec
-	fxor		%f14, %f2, %f2
-	movxtod		%o2, %f12
-	movxtod		%o3, %f14
-	fxor		%f8, %f4, %f4
-	fxor		%f10, %f6, %f6
-
-	brnz,pn		$ooff, 2f
-	sub		$len, 2, $len
-		
-	std		%f0, [$out + 0]
-	std		%f2, [$out + 8]
-	std		%f4, [$out + 16]
-	std		%f6, [$out + 24]
-	brnz,pt		$len, .L${bits}_cbc_dec_loop2x
-	add		$out, 32, $out
-___
-$::code.=<<___ if ($::evp);
-	st		%f12, [$ivec + 0]
-	st		%f13, [$ivec + 4]
-	st		%f14, [$ivec + 8]
-	st		%f15, [$ivec + 12]
-___
-$::code.=<<___ if (!$::evp);
-	brnz,pn		$ivoff, .L${bits}_cbc_dec_unaligned_ivec
-	nop
-
-	std		%f12, [$ivec + 0]	! write out ivec
-	std		%f14, [$ivec + 8]
-___
-$::code.=<<___;
-	ret
-	restore
-
-.align	16
-2:	ldxa		[$inp]0x82, %o0		! avoid read-after-write hazard
-						! and ~3x deterioration
-						! in inp==out case
-	faligndata	%f0, %f0, %f8		! handle unaligned output
-	faligndata	%f0, %f2, %f0
-	faligndata	%f2, %f4, %f2
-	faligndata	%f4, %f6, %f4
-	faligndata	%f6, %f6, %f6
-	stda		%f8, [$out + $omask]0xc0	! partial store
-	std		%f0, [$out + 8]
-	std		%f2, [$out + 16]
-	std		%f4, [$out + 24]
-	add		$out, 32, $out
-	orn		%g0, $omask, $omask
-	stda		%f6, [$out + $omask]0xc0	! partial store
-
-	brnz,pt		$len, .L${bits}_cbc_dec_loop2x+4
-	orn		%g0, $omask, $omask
-___
-$::code.=<<___ if ($::evp);
-	st		%f12, [$ivec + 0]
-	st		%f13, [$ivec + 4]
-	st		%f14, [$ivec + 8]
-	st		%f15, [$ivec + 12]
-___
-$::code.=<<___ if (!$::evp);
-	brnz,pn		$ivoff, .L${bits}_cbc_dec_unaligned_ivec
-	nop
-
-	std		%f12, [$ivec + 0]	! write out ivec
-	std		%f14, [$ivec + 8]
-	ret
-	restore
-
-.align	16
-.L${bits}_cbc_dec_unaligned_ivec:
-	alignaddrl	$ivec, $ivoff, %g0	! handle unaligned ivec
-	mov		0xff, $omask
-	srl		$omask, $ivoff, $omask
-	faligndata	%f12, %f12, %f0
-	faligndata	%f12, %f14, %f2
-	faligndata	%f14, %f14, %f4
-	stda		%f0, [$ivec + $omask]0xc0
-	std		%f2, [$ivec + 8]
-	add		$ivec, 16, $ivec
-	orn		%g0, $omask, $omask
-	stda		%f4, [$ivec + $omask]0xc0
-___
-$::code.=<<___;
-	ret
-	restore
-
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-.align	32
-.L${bits}cbc_dec_blk:
-	add	$out, $len, $blk_init
-	and	$blk_init, 63, $blk_init	! tail
-	sub	$len, $blk_init, $len
-	add	$blk_init, 15, $blk_init	! round up to 16n
-	srlx	$len, 4, $len
-	srl	$blk_init, 4, $blk_init
-	sub	$len, 1, $len
-	add	$blk_init, 1, $blk_init
-
-.L${bits}_cbc_dec_blk_loop2x:
-	ldx		[$inp + 0], %o0
-	ldx		[$inp + 8], %o1
-	ldx		[$inp + 16], %o2
-	brz,pt		$ileft, 5f
-	ldx		[$inp + 24], %o3
-
-	ldx		[$inp + 32], %o4
-	sllx		%o0, $ileft, %o0
-	srlx		%o1, $iright, %g1
-	or		%g1, %o0, %o0
-	sllx		%o1, $ileft, %o1
-	srlx		%o2, $iright, %g1
-	or		%g1, %o1, %o1
-	sllx		%o2, $ileft, %o2
-	srlx		%o3, $iright, %g1
-	or		%g1, %o2, %o2
-	sllx		%o3, $ileft, %o3
-	srlx		%o4, $iright, %o4
-	or		%o4, %o3, %o3
-5:
-	xor		%g4, %o0, %o4		! ^= rk[0]
-	xor		%g5, %o1, %o5
-	movxtod		%o4, %f0
-	movxtod		%o5, %f2
-	xor		%g4, %o2, %o4
-	xor		%g5, %o3, %o5
-	movxtod		%o4, %f4
-	movxtod		%o5, %f6
-
-	prefetch	[$inp + 32+63], 20
-	call		_${alg}${bits}_decrypt_2x
-	add		$inp, 32, $inp
-	subcc		$len, 2, $len
-
-	movxtod		%o0, %f8
-	movxtod		%o1, %f10
-	fxor		%f12, %f0, %f0		! ^= ivec
-	fxor		%f14, %f2, %f2
-	movxtod		%o2, %f12
-	movxtod		%o3, %f14
-	fxor		%f8, %f4, %f4
-	fxor		%f10, %f6, %f6
-
-	stda		%f0, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-	add		$out, 8, $out
-	stda		%f2, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-	add		$out, 8, $out
-	stda		%f4, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-	add		$out, 8, $out
-	stda		%f6, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-	bgu,pt		$::size_t_cc, .L${bits}_cbc_dec_blk_loop2x
-	add		$out, 8, $out
-
-	add		$blk_init, $len, $len
-	andcc		$len, 1, %g0		! is number of blocks even?
-	membar		#StoreLoad|#StoreStore
-	bnz,pt		%icc, .L${bits}_cbc_dec_loop
-	srl		$len, 0, $len
-	brnz,pn		$len, .L${bits}_cbc_dec_loop2x
-	nop
-___
-$::code.=<<___ if ($::evp);
-	st		%f12, [$ivec + 0]	! write out ivec
-	st		%f13, [$ivec + 4]
-	st		%f14, [$ivec + 8]
-	st		%f15, [$ivec + 12]
-___
-$::code.=<<___ if (!$::evp);
-	brnz,pn		$ivoff, 3b
-	nop
-
-	std		%f12, [$ivec + 0]	! write out ivec
-	std		%f14, [$ivec + 8]
-___
-$::code.=<<___;
-	ret
-	restore
-.type	${alg}${bits}_t4_cbc_decrypt,#function
-.size	${alg}${bits}_t4_cbc_decrypt,.-${alg}${bits}_t4_cbc_decrypt
-___
-}
-
-sub alg_ctr32_implement {
-my ($alg,$bits) = @_;
-
-$::code.=<<___;
-.globl	${alg}${bits}_t4_ctr32_encrypt
-.align	32
-${alg}${bits}_t4_ctr32_encrypt:
-	save		%sp, -$::frame, %sp
-
-	prefetch	[$inp], 20
-	prefetch	[$inp + 63], 20
-	call		_${alg}${bits}_load_enckey
-	sllx		$len, 4, $len
-
-	ld		[$ivec + 0], %l4	! counter
-	ld		[$ivec + 4], %l5
-	ld		[$ivec + 8], %l6
-	ld		[$ivec + 12], %l7
-
-	sllx		%l4, 32, %o5
-	or		%l5, %o5, %o5
-	sllx		%l6, 32, %g1
-	xor		%o5, %g4, %g4		! ^= rk[0]
-	xor		%g1, %g5, %g5
-	movxtod		%g4, %f14		! most significant 64 bits
-
-	sub		$inp, $out, $blk_init	! $inp!=$out
-	and		$inp, 7, $ileft
-	andn		$inp, 7, $inp
-	sll		$ileft, 3, $ileft
-	mov		64, $iright
-	mov		0xff, $omask
-	sub		$iright, $ileft, $iright
-	and		$out, 7, $ooff
-	cmp		$len, 255
-	movrnz		$ooff, 0, $blk_init		! if (	$out&7 ||
-	movleu		$::size_t_cc, 0, $blk_init	!	$len<256 ||
-	brnz,pn		$blk_init, .L${bits}_ctr32_blk	!	$inp==$out)
-	srl		$omask, $ooff, $omask
-
-	andcc		$len, 16, %g0		! is number of blocks even?
-	alignaddrl	$out, %g0, $out
-	bz		%icc, .L${bits}_ctr32_loop2x
-	srlx		$len, 4, $len
-.L${bits}_ctr32_loop:
-	ldx		[$inp + 0], %o0
-	brz,pt		$ileft, 4f
-	ldx		[$inp + 8], %o1
-
-	ldx		[$inp + 16], %o2
-	sllx		%o0, $ileft, %o0
-	srlx		%o1, $iright, %g1
-	sllx		%o1, $ileft, %o1
-	or		%g1, %o0, %o0
-	srlx		%o2, $iright, %o2
-	or		%o2, %o1, %o1
-4:
-	xor		%g5, %l7, %g1		! ^= rk[0]
-	add		%l7, 1, %l7
-	movxtod		%g1, %f2
-	srl		%l7, 0, %l7		! clruw
-	prefetch	[$out + 63], 22
-	prefetch	[$inp + 16+63], 20
-___
-$::code.=<<___ if ($alg eq "aes");
-	aes_eround01	%f16, %f14, %f2, %f4
-	aes_eround23	%f18, %f14, %f2, %f2
-___
-$::code.=<<___ if ($alg eq "cmll");
-	camellia_f	%f16, %f2, %f14, %f2
-	camellia_f	%f18, %f14, %f2, %f0
-___
-$::code.=<<___;
-	call		_${alg}${bits}_encrypt_1x+8
-	add		$inp, 16, $inp
-
-	movxtod		%o0, %f10
-	movxtod		%o1, %f12
-	fxor		%f10, %f0, %f0		! ^= inp
-	fxor		%f12, %f2, %f2
-
-	brnz,pn		$ooff, 2f
-	sub		$len, 1, $len
-		
-	std		%f0, [$out + 0]
-	std		%f2, [$out + 8]
-	brnz,pt		$len, .L${bits}_ctr32_loop2x
-	add		$out, 16, $out
-
-	ret
-	restore
-
-.align	16
-2:	ldxa		[$inp]0x82, %o0		! avoid read-after-write hazard
-						! and ~3x deterioration
-						! in inp==out case
-	faligndata	%f0, %f0, %f4		! handle unaligned output
-	faligndata	%f0, %f2, %f6
-	faligndata	%f2, %f2, %f8
-	stda		%f4, [$out + $omask]0xc0	! partial store
-	std		%f6, [$out + 8]
-	add		$out, 16, $out
-	orn		%g0, $omask, $omask
-	stda		%f8, [$out + $omask]0xc0	! partial store
-
-	brnz,pt		$len, .L${bits}_ctr32_loop2x+4
-	orn		%g0, $omask, $omask
-
-	ret
-	restore
-
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-.align	32
-.L${bits}_ctr32_loop2x:
-	ldx		[$inp + 0], %o0
-	ldx		[$inp + 8], %o1
-	ldx		[$inp + 16], %o2
-	brz,pt		$ileft, 4f
-	ldx		[$inp + 24], %o3
-
-	ldx		[$inp + 32], %o4
-	sllx		%o0, $ileft, %o0
-	srlx		%o1, $iright, %g1
-	or		%g1, %o0, %o0
-	sllx		%o1, $ileft, %o1
-	srlx		%o2, $iright, %g1
-	or		%g1, %o1, %o1
-	sllx		%o2, $ileft, %o2
-	srlx		%o3, $iright, %g1
-	or		%g1, %o2, %o2
-	sllx		%o3, $ileft, %o3
-	srlx		%o4, $iright, %o4
-	or		%o4, %o3, %o3
-4:
-	xor		%g5, %l7, %g1		! ^= rk[0]
-	add		%l7, 1, %l7
-	movxtod		%g1, %f2
-	srl		%l7, 0, %l7		! clruw
-	xor		%g5, %l7, %g1
-	add		%l7, 1, %l7
-	movxtod		%g1, %f6
-	srl		%l7, 0, %l7		! clruw
-	prefetch	[$out + 63], 22
-	prefetch	[$inp + 32+63], 20
-___
-$::code.=<<___ if ($alg eq "aes");
-	aes_eround01	%f16, %f14, %f2, %f8
-	aes_eround23	%f18, %f14, %f2, %f2
-	aes_eround01	%f16, %f14, %f6, %f10
-	aes_eround23	%f18, %f14, %f6, %f6
-___
-$::code.=<<___ if ($alg eq "cmll");
-	camellia_f	%f16, %f2, %f14, %f2
-	camellia_f	%f16, %f6, %f14, %f6
-	camellia_f	%f18, %f14, %f2, %f0
-	camellia_f	%f18, %f14, %f6, %f4
-___
-$::code.=<<___;
-	call		_${alg}${bits}_encrypt_2x+16
-	add		$inp, 32, $inp
-
-	movxtod		%o0, %f8
-	movxtod		%o1, %f10
-	movxtod		%o2, %f12
-	fxor		%f8, %f0, %f0		! ^= inp
-	movxtod		%o3, %f8
-	fxor		%f10, %f2, %f2
-	fxor		%f12, %f4, %f4
-	fxor		%f8, %f6, %f6
-
-	brnz,pn		$ooff, 2f
-	sub		$len, 2, $len
-		
-	std		%f0, [$out + 0]
-	std		%f2, [$out + 8]
-	std		%f4, [$out + 16]
-	std		%f6, [$out + 24]
-	brnz,pt		$len, .L${bits}_ctr32_loop2x
-	add		$out, 32, $out
-
-	ret
-	restore
-
-.align	16
-2:	ldxa		[$inp]0x82, %o0		! avoid read-after-write hazard
-						! and ~3x deterioration
-						! in inp==out case
-	faligndata	%f0, %f0, %f8		! handle unaligned output
-	faligndata	%f0, %f2, %f0
-	faligndata	%f2, %f4, %f2
-	faligndata	%f4, %f6, %f4
-	faligndata	%f6, %f6, %f6
-
-	stda		%f8, [$out + $omask]0xc0	! partial store
-	std		%f0, [$out + 8]
-	std		%f2, [$out + 16]
-	std		%f4, [$out + 24]
-	add		$out, 32, $out
-	orn		%g0, $omask, $omask
-	stda		%f6, [$out + $omask]0xc0	! partial store
-
-	brnz,pt		$len, .L${bits}_ctr32_loop2x+4
-	orn		%g0, $omask, $omask
-
-	ret
-	restore
-
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-.align	32
-.L${bits}_ctr32_blk:
-	add	$out, $len, $blk_init
-	and	$blk_init, 63, $blk_init	! tail
-	sub	$len, $blk_init, $len
-	add	$blk_init, 15, $blk_init	! round up to 16n
-	srlx	$len, 4, $len
-	srl	$blk_init, 4, $blk_init
-	sub	$len, 1, $len
-	add	$blk_init, 1, $blk_init
-
-.L${bits}_ctr32_blk_loop2x:
-	ldx		[$inp + 0], %o0
-	ldx		[$inp + 8], %o1
-	ldx		[$inp + 16], %o2
-	brz,pt		$ileft, 5f
-	ldx		[$inp + 24], %o3
-
-	ldx		[$inp + 32], %o4
-	sllx		%o0, $ileft, %o0
-	srlx		%o1, $iright, %g1
-	or		%g1, %o0, %o0
-	sllx		%o1, $ileft, %o1
-	srlx		%o2, $iright, %g1
-	or		%g1, %o1, %o1
-	sllx		%o2, $ileft, %o2
-	srlx		%o3, $iright, %g1
-	or		%g1, %o2, %o2
-	sllx		%o3, $ileft, %o3
-	srlx		%o4, $iright, %o4
-	or		%o4, %o3, %o3
-5:
-	xor		%g5, %l7, %g1		! ^= rk[0]
-	add		%l7, 1, %l7
-	movxtod		%g1, %f2
-	srl		%l7, 0, %l7		! clruw
-	xor		%g5, %l7, %g1
-	add		%l7, 1, %l7
-	movxtod		%g1, %f6
-	srl		%l7, 0, %l7		! clruw
-	prefetch	[$inp + 32+63], 20
-___
-$::code.=<<___ if ($alg eq "aes");
-	aes_eround01	%f16, %f14, %f2, %f8
-	aes_eround23	%f18, %f14, %f2, %f2
-	aes_eround01	%f16, %f14, %f6, %f10
-	aes_eround23	%f18, %f14, %f6, %f6
-___
-$::code.=<<___ if ($alg eq "cmll");
-	camellia_f	%f16, %f2, %f14, %f2
-	camellia_f	%f16, %f6, %f14, %f6
-	camellia_f	%f18, %f14, %f2, %f0
-	camellia_f	%f18, %f14, %f6, %f4
-___
-$::code.=<<___;
-	call		_${alg}${bits}_encrypt_2x+16
-	add		$inp, 32, $inp
-	subcc		$len, 2, $len
-
-	movxtod		%o0, %f8
-	movxtod		%o1, %f10
-	movxtod		%o2, %f12
-	fxor		%f8, %f0, %f0		! ^= inp
-	movxtod		%o3, %f8
-	fxor		%f10, %f2, %f2
-	fxor		%f12, %f4, %f4
-	fxor		%f8, %f6, %f6
-
-	stda		%f0, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-	add		$out, 8, $out
-	stda		%f2, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-	add		$out, 8, $out
-	stda		%f4, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-	add		$out, 8, $out
-	stda		%f6, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-	bgu,pt		$::size_t_cc, .L${bits}_ctr32_blk_loop2x
-	add		$out, 8, $out
-
-	add		$blk_init, $len, $len
-	andcc		$len, 1, %g0		! is number of blocks even?
-	membar		#StoreLoad|#StoreStore
-	bnz,pt		%icc, .L${bits}_ctr32_loop
-	srl		$len, 0, $len
-	brnz,pn		$len, .L${bits}_ctr32_loop2x
-	nop
-
-	ret
-	restore
-.type	${alg}${bits}_t4_ctr32_encrypt,#function
-.size	${alg}${bits}_t4_ctr32_encrypt,.-${alg}${bits}_t4_ctr32_encrypt
-___
-}
-
-sub alg_xts_implement {
-my ($alg,$bits,$dir) = @_;
-my ($inp,$out,$len,$key1,$key2,$ivec)=map("%i$_",(0..5));
-my $rem=$ivec;
-
-$::code.=<<___;
-.globl	${alg}${bits}_t4_xts_${dir}crypt
-.align	32
-${alg}${bits}_t4_xts_${dir}crypt:
-	save		%sp, -$::frame-16, %sp
-
-	mov		$ivec, %o0
-	add		%fp, $::bias-16, %o1
-	call		${alg}_t4_encrypt
-	mov		$key2, %o2
-
-	add		%fp, $::bias-16, %l7
-	ldxa		[%l7]0x88, %g2
-	add		%fp, $::bias-8, %l7
-	ldxa		[%l7]0x88, %g3		! %g3:%g2 is tweak
-
-	sethi		%hi(0x76543210), %l7
-	or		%l7, %lo(0x76543210), %l7
-	bmask		%l7, %g0, %g0		! byte swap mask
-
-	prefetch	[$inp], 20
-	prefetch	[$inp + 63], 20
-	call		_${alg}${bits}_load_${dir}ckey
-	and		$len, 15,  $rem
-	and		$len, -16, $len
-___
-$code.=<<___ if ($dir eq "de");
-	mov		0, %l7
-	movrnz		$rem, 16,  %l7
-	sub		$len, %l7, $len
-___
-$code.=<<___;
-
-	sub		$inp, $out, $blk_init	! $inp!=$out
-	and		$inp, 7, $ileft
-	andn		$inp, 7, $inp
-	sll		$ileft, 3, $ileft
-	mov		64, $iright
-	mov		0xff, $omask
-	sub		$iright, $ileft, $iright
-	and		$out, 7, $ooff
-	cmp		$len, 255
-	movrnz		$ooff, 0, $blk_init		! if (	$out&7 ||
-	movleu		$::size_t_cc, 0, $blk_init	!	$len<256 ||
-	brnz,pn		$blk_init, .L${bits}_xts_${dir}blk !	$inp==$out)
-	srl		$omask, $ooff, $omask
-
-	andcc		$len, 16, %g0		! is number of blocks even?
-___
-$code.=<<___ if ($dir eq "de");
-	brz,pn		$len, .L${bits}_xts_${dir}steal
-___
-$code.=<<___;
-	alignaddrl	$out, %g0, $out
-	bz		%icc, .L${bits}_xts_${dir}loop2x
-	srlx		$len, 4, $len
-.L${bits}_xts_${dir}loop:
-	ldx		[$inp + 0], %o0
-	brz,pt		$ileft, 4f
-	ldx		[$inp + 8], %o1
-
-	ldx		[$inp + 16], %o2
-	sllx		%o0, $ileft, %o0
-	srlx		%o1, $iright, %g1
-	sllx		%o1, $ileft, %o1
-	or		%g1, %o0, %o0
-	srlx		%o2, $iright, %o2
-	or		%o2, %o1, %o1
-4:
-	movxtod		%g2, %f12
-	movxtod		%g3, %f14
-	bshuffle	%f12, %f12, %f12
-	bshuffle	%f14, %f14, %f14
-
-	xor		%g4, %o0, %o0		! ^= rk[0]
-	xor		%g5, %o1, %o1
-	movxtod		%o0, %f0
-	movxtod		%o1, %f2
-
-	fxor		%f12, %f0, %f0		! ^= tweak[0]
-	fxor		%f14, %f2, %f2
-
-	prefetch	[$out + 63], 22
-	prefetch	[$inp + 16+63], 20
-	call		_${alg}${bits}_${dir}crypt_1x
-	add		$inp, 16, $inp
-
-	fxor		%f12, %f0, %f0		! ^= tweak[0]
-	fxor		%f14, %f2, %f2
-
-	srax		%g3, 63, %l7		! next tweak value
-	addcc		%g2, %g2, %g2
-	and		%l7, 0x87, %l7
-	addxc		%g3, %g3, %g3
-	xor		%l7, %g2, %g2
-
-	brnz,pn		$ooff, 2f
-	sub		$len, 1, $len
-		
-	std		%f0, [$out + 0]
-	std		%f2, [$out + 8]
-	brnz,pt		$len, .L${bits}_xts_${dir}loop2x
-	add		$out, 16, $out
-
-	brnz,pn		$rem, .L${bits}_xts_${dir}steal
-	nop
-
-	ret
-	restore
-
-.align	16
-2:	ldxa		[$inp]0x82, %o0		! avoid read-after-write hazard
-						! and ~3x deterioration
-						! in inp==out case
-	faligndata	%f0, %f0, %f4		! handle unaligned output
-	faligndata	%f0, %f2, %f6
-	faligndata	%f2, %f2, %f8
-	stda		%f4, [$out + $omask]0xc0	! partial store
-	std		%f6, [$out + 8]
-	add		$out, 16, $out
-	orn		%g0, $omask, $omask
-	stda		%f8, [$out + $omask]0xc0	! partial store
-
-	brnz,pt		$len, .L${bits}_xts_${dir}loop2x+4
-	orn		%g0, $omask, $omask
-
-	brnz,pn		$rem, .L${bits}_xts_${dir}steal
-	nop
-
-	ret
-	restore
-
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-.align	32
-.L${bits}_xts_${dir}loop2x:
-	ldx		[$inp + 0], %o0
-	ldx		[$inp + 8], %o1
-	ldx		[$inp + 16], %o2
-	brz,pt		$ileft, 4f
-	ldx		[$inp + 24], %o3
-
-	ldx		[$inp + 32], %o4
-	sllx		%o0, $ileft, %o0
-	srlx		%o1, $iright, %g1
-	or		%g1, %o0, %o0
-	sllx		%o1, $ileft, %o1
-	srlx		%o2, $iright, %g1
-	or		%g1, %o1, %o1
-	sllx		%o2, $ileft, %o2
-	srlx		%o3, $iright, %g1
-	or		%g1, %o2, %o2
-	sllx		%o3, $ileft, %o3
-	srlx		%o4, $iright, %o4
-	or		%o4, %o3, %o3
-4:
-	movxtod		%g2, %f12
-	movxtod		%g3, %f14
-	bshuffle	%f12, %f12, %f12
-	bshuffle	%f14, %f14, %f14
-
-	srax		%g3, 63, %l7		! next tweak value
-	addcc		%g2, %g2, %g2
-	and		%l7, 0x87, %l7
-	addxc		%g3, %g3, %g3
-	xor		%l7, %g2, %g2
-
-	movxtod		%g2, %f8
-	movxtod		%g3, %f10
-	bshuffle	%f8,  %f8,  %f8
-	bshuffle	%f10, %f10, %f10
-
-	xor		%g4, %o0, %o0		! ^= rk[0]
-	xor		%g5, %o1, %o1
-	xor		%g4, %o2, %o2		! ^= rk[0]
-	xor		%g5, %o3, %o3
-	movxtod		%o0, %f0
-	movxtod		%o1, %f2
-	movxtod		%o2, %f4
-	movxtod		%o3, %f6
-
-	fxor		%f12, %f0, %f0		! ^= tweak[0]
-	fxor		%f14, %f2, %f2
-	fxor		%f8,  %f4, %f4		! ^= tweak[0]
-	fxor		%f10, %f6, %f6
-
-	prefetch	[$out + 63], 22
-	prefetch	[$inp + 32+63], 20
-	call		_${alg}${bits}_${dir}crypt_2x
-	add		$inp, 32, $inp
-
-	movxtod		%g2, %f8
-	movxtod		%g3, %f10
-
-	srax		%g3, 63, %l7		! next tweak value
-	addcc		%g2, %g2, %g2
-	and		%l7, 0x87, %l7
-	addxc		%g3, %g3, %g3
-	xor		%l7, %g2, %g2
-
-	bshuffle	%f8,  %f8,  %f8
-	bshuffle	%f10, %f10, %f10
-
-	fxor		%f12, %f0, %f0		! ^= tweak[0]
-	fxor		%f14, %f2, %f2
-	fxor		%f8,  %f4, %f4
-	fxor		%f10, %f6, %f6
-
-	brnz,pn		$ooff, 2f
-	sub		$len, 2, $len
-		
-	std		%f0, [$out + 0]
-	std		%f2, [$out + 8]
-	std		%f4, [$out + 16]
-	std		%f6, [$out + 24]
-	brnz,pt		$len, .L${bits}_xts_${dir}loop2x
-	add		$out, 32, $out
-
-	fsrc2		%f4, %f0
-	fsrc2		%f6, %f2
-	brnz,pn		$rem, .L${bits}_xts_${dir}steal
-	nop
-
-	ret
-	restore
-
-.align	16
-2:	ldxa		[$inp]0x82, %o0		! avoid read-after-write hazard
-						! and ~3x deterioration
-						! in inp==out case
-	faligndata	%f0, %f0, %f8		! handle unaligned output
-	faligndata	%f0, %f2, %f10
-	faligndata	%f2, %f4, %f12
-	faligndata	%f4, %f6, %f14
-	faligndata	%f6, %f6, %f0
-
-	stda		%f8, [$out + $omask]0xc0	! partial store
-	std		%f10, [$out + 8]
-	std		%f12, [$out + 16]
-	std		%f14, [$out + 24]
-	add		$out, 32, $out
-	orn		%g0, $omask, $omask
-	stda		%f0, [$out + $omask]0xc0	! partial store
-
-	brnz,pt		$len, .L${bits}_xts_${dir}loop2x+4
-	orn		%g0, $omask, $omask
-
-	fsrc2		%f4, %f0
-	fsrc2		%f6, %f2
-	brnz,pn		$rem, .L${bits}_xts_${dir}steal
-	nop
-
-	ret
-	restore
-
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-.align	32
-.L${bits}_xts_${dir}blk:
-	add	$out, $len, $blk_init
-	and	$blk_init, 63, $blk_init	! tail
-	sub	$len, $blk_init, $len
-	add	$blk_init, 15, $blk_init	! round up to 16n
-	srlx	$len, 4, $len
-	srl	$blk_init, 4, $blk_init
-	sub	$len, 1, $len
-	add	$blk_init, 1, $blk_init
-
-.L${bits}_xts_${dir}blk2x:
-	ldx		[$inp + 0], %o0
-	ldx		[$inp + 8], %o1
-	ldx		[$inp + 16], %o2
-	brz,pt		$ileft, 5f
-	ldx		[$inp + 24], %o3
-
-	ldx		[$inp + 32], %o4
-	sllx		%o0, $ileft, %o0
-	srlx		%o1, $iright, %g1
-	or		%g1, %o0, %o0
-	sllx		%o1, $ileft, %o1
-	srlx		%o2, $iright, %g1
-	or		%g1, %o1, %o1
-	sllx		%o2, $ileft, %o2
-	srlx		%o3, $iright, %g1
-	or		%g1, %o2, %o2
-	sllx		%o3, $ileft, %o3
-	srlx		%o4, $iright, %o4
-	or		%o4, %o3, %o3
-5:
-	movxtod		%g2, %f12
-	movxtod		%g3, %f14
-	bshuffle	%f12, %f12, %f12
-	bshuffle	%f14, %f14, %f14
-
-	srax		%g3, 63, %l7		! next tweak value
-	addcc		%g2, %g2, %g2
-	and		%l7, 0x87, %l7
-	addxc		%g3, %g3, %g3
-	xor		%l7, %g2, %g2
-
-	movxtod		%g2, %f8
-	movxtod		%g3, %f10
-	bshuffle	%f8,  %f8,  %f8
-	bshuffle	%f10, %f10, %f10
-
-	xor		%g4, %o0, %o0		! ^= rk[0]
-	xor		%g5, %o1, %o1
-	xor		%g4, %o2, %o2		! ^= rk[0]
-	xor		%g5, %o3, %o3
-	movxtod		%o0, %f0
-	movxtod		%o1, %f2
-	movxtod		%o2, %f4
-	movxtod		%o3, %f6
-
-	fxor		%f12, %f0, %f0		! ^= tweak[0]
-	fxor		%f14, %f2, %f2
-	fxor		%f8,  %f4, %f4		! ^= tweak[0]
-	fxor		%f10, %f6, %f6
-
-	prefetch	[$inp + 32+63], 20
-	call		_${alg}${bits}_${dir}crypt_2x
-	add		$inp, 32, $inp
-
-	movxtod		%g2, %f8
-	movxtod		%g3, %f10
-
-	srax		%g3, 63, %l7		! next tweak value
-	addcc		%g2, %g2, %g2
-	and		%l7, 0x87, %l7
-	addxc		%g3, %g3, %g3
-	xor		%l7, %g2, %g2
-
-	bshuffle	%f8,  %f8,  %f8
-	bshuffle	%f10, %f10, %f10
-
-	fxor		%f12, %f0, %f0		! ^= tweak[0]
-	fxor		%f14, %f2, %f2
-	fxor		%f8,  %f4, %f4
-	fxor		%f10, %f6, %f6
-
-	stda		%f0, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-	add		$out, 8, $out
-	stda		%f2, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-	add		$out, 8, $out
-	stda		%f4, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-	add		$out, 8, $out
-	stda		%f6, [$out]0xe2		! ASI_BLK_INIT, T4-specific
-	bgu,pt		$::size_t_cc, .L${bits}_xts_${dir}blk2x
-	add		$out, 8, $out
-
-	add		$blk_init, $len, $len
-	andcc		$len, 1, %g0		! is number of blocks even?
-	membar		#StoreLoad|#StoreStore
-	bnz,pt		%icc, .L${bits}_xts_${dir}loop
-	srl		$len, 0, $len
-	brnz,pn		$len, .L${bits}_xts_${dir}loop2x
-	nop
-
-	fsrc2		%f4, %f0
-	fsrc2		%f6, %f2
-	brnz,pn		$rem, .L${bits}_xts_${dir}steal
-	nop
-
-	ret
-	restore
-!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-___
-$code.=<<___ if ($dir eq "en");
-.align	32
-.L${bits}_xts_${dir}steal:
-	std		%f0, [%fp + $::bias-16]	! copy of output
-	std		%f2, [%fp + $::bias-8]
-
-	srl		$ileft, 3, $ileft
-	add		%fp, $::bias-16, %l7
-	add		$inp, $ileft, $inp	! original $inp+$len&-15
-	add		$out, $ooff, $out	! original $out+$len&-15
-	mov		0, $ileft
-	nop					! align
-
-.L${bits}_xts_${dir}stealing:
-	ldub		[$inp + $ileft], %o0
-	ldub		[%l7  + $ileft], %o1
-	dec		$rem
-	stb		%o0, [%l7  + $ileft]
-	stb		%o1, [$out + $ileft]
-	brnz		$rem, .L${bits}_xts_${dir}stealing
-	inc		$ileft
-
-	mov		%l7, $inp
-	sub		$out, 16, $out
-	mov		0, $ileft
-	sub		$out, $ooff, $out
-	ba		.L${bits}_xts_${dir}loop	! one more time
-	mov		1, $len				! $rem is 0
-___
-$code.=<<___ if ($dir eq "de");
-.align	32
-.L${bits}_xts_${dir}steal:
-	ldx		[$inp + 0], %o0
-	brz,pt		$ileft, 8f
-	ldx		[$inp + 8], %o1
-
-	ldx		[$inp + 16], %o2
-	sllx		%o0, $ileft, %o0
-	srlx		%o1, $iright, %g1
-	sllx		%o1, $ileft, %o1
-	or		%g1, %o0, %o0
-	srlx		%o2, $iright, %o2
-	or		%o2, %o1, %o1
-8:
-	srax		%g3, 63, %l7		! next tweak value
-	addcc		%g2, %g2, %o2
-	and		%l7, 0x87, %l7
-	addxc		%g3, %g3, %o3
-	xor		%l7, %o2, %o2
-
-	movxtod		%o2, %f12
-	movxtod		%o3, %f14
-	bshuffle	%f12, %f12, %f12
-	bshuffle	%f14, %f14, %f14
-
-	xor		%g4, %o0, %o0		! ^= rk[0]
-	xor		%g5, %o1, %o1
-	movxtod		%o0, %f0
-	movxtod		%o1, %f2
-
-	fxor		%f12, %f0, %f0		! ^= tweak[0]
-	fxor		%f14, %f2, %f2
-
-	call		_${alg}${bits}_${dir}crypt_1x
-	add		$inp, 16, $inp
-
-	fxor		%f12, %f0, %f0		! ^= tweak[0]
-	fxor		%f14, %f2, %f2
-
-	std		%f0, [%fp + $::bias-16]
-	std		%f2, [%fp + $::bias-8]
-
-	srl		$ileft, 3, $ileft
-	add		%fp, $::bias-16, %l7
-	add		$inp, $ileft, $inp	! original $inp+$len&-15
-	add		$out, $ooff, $out	! original $out+$len&-15
-	mov		0, $ileft
-	add		$out, 16, $out
-	nop					! align
-
-.L${bits}_xts_${dir}stealing:
-	ldub		[$inp + $ileft], %o0
-	ldub		[%l7  + $ileft], %o1
-	dec		$rem
-	stb		%o0, [%l7  + $ileft]
-	stb		%o1, [$out + $ileft]
-	brnz		$rem, .L${bits}_xts_${dir}stealing
-	inc		$ileft
-
-	mov		%l7, $inp
-	sub		$out, 16, $out
-	mov		0, $ileft
-	sub		$out, $ooff, $out
-	ba		.L${bits}_xts_${dir}loop	! one more time
-	mov		1, $len				! $rem is 0
-___
-$code.=<<___;
-	ret
-	restore
-.type	${alg}${bits}_t4_xts_${dir}crypt,#function
-.size	${alg}${bits}_t4_xts_${dir}crypt,.-${alg}${bits}_t4_xts_${dir}crypt
-___
-}
-
-# Purpose of these subroutines is to explicitly encode VIS instructions,
-# so that one can compile the module without having to specify VIS
-# extentions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a.
-# Idea is to reserve for option to produce "universal" binary and let
-# programmer detect if current CPU is VIS capable at run-time.
-sub unvis {
-my ($mnemonic,$rs1,$rs2,$rd)=@_;
-my ($ref,$opf);
-my %visopf = (	"faligndata"	=> 0x048,
-		"bshuffle"	=> 0x04c,
-		"fnot2"		=> 0x066,
-		"fxor"		=> 0x06c,
-		"fsrc2"		=> 0x078	);
-
-    $ref = "$mnemonic\t$rs1,$rs2,$rd";
-
-    if ($opf=$visopf{$mnemonic}) {
-	foreach ($rs1,$rs2,$rd) {
-	    return $ref if (!/%f([0-9]{1,2})/);
-	    $_=$1;
-	    if ($1>=32) {
-		return $ref if ($1&1);
-		# re-encode for upper double register addressing
-		$_=($1|$1>>5)&31;
-	    }
-	}
-
-	return	sprintf ".word\t0x%08x !%s",
-			0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
-			$ref;
-    } else {
-	return $ref;
-    }
-}
-
-sub unvis3 {
-my ($mnemonic,$rs1,$rs2,$rd)=@_;
-my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 );
-my ($ref,$opf);
-my %visopf = (	"addxc"		=> 0x011,
-		"addxccc"	=> 0x013,
-		"umulxhi"	=> 0x016,
-		"alignaddr"	=> 0x018,
-		"bmask"		=> 0x019,
-		"alignaddrl"	=> 0x01a	);
-
-    $ref = "$mnemonic\t$rs1,$rs2,$rd";
-
-    if ($opf=$visopf{$mnemonic}) {
-	foreach ($rs1,$rs2,$rd) {
-	    return $ref if (!/%([goli])([0-9])/);
-	    $_=$bias{$1}+$2;
-	}
-
-	return	sprintf ".word\t0x%08x !%s",
-			0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
-			$ref;
-    } else {
-	return $ref;
-    }
-}
-
-sub unaes_round {	# 4-argument instructions
-my ($mnemonic,$rs1,$rs2,$rs3,$rd)=@_;
-my ($ref,$opf);
-my %aesopf = (	"aes_eround01"	=> 0,
-		"aes_eround23"	=> 1,
-		"aes_dround01"	=> 2,
-		"aes_dround23"	=> 3,
-		"aes_eround01_l"=> 4,
-		"aes_eround23_l"=> 5,
-		"aes_dround01_l"=> 6,
-		"aes_dround23_l"=> 7,
-		"aes_kexpand1"	=> 8	);
-
-    $ref = "$mnemonic\t$rs1,$rs2,$rs3,$rd";
-
-    if (defined($opf=$aesopf{$mnemonic})) {
-	$rs3 = ($rs3 =~ /%f([0-6]*[02468])/) ? (($1|$1>>5)&31) : $rs3;
-	foreach ($rs1,$rs2,$rd) {
-	    return $ref if (!/%f([0-9]{1,2})/);
-	    $_=$1;
-	    if ($1>=32) {
-		return $ref if ($1&1);
-		# re-encode for upper double register addressing
-		$_=($1|$1>>5)&31;
-	    }
-	}
-
-	return	sprintf ".word\t0x%08x !%s",
-			2<<30|$rd<<25|0x19<<19|$rs1<<14|$rs3<<9|$opf<<5|$rs2,
-			$ref;
-    } else {
-	return $ref;
-    }
-}
-
-sub unaes_kexpand {	# 3-argument instructions
-my ($mnemonic,$rs1,$rs2,$rd)=@_;
-my ($ref,$opf);
-my %aesopf = (	"aes_kexpand0"	=> 0x130,
-		"aes_kexpand2"	=> 0x131	);
-
-    $ref = "$mnemonic\t$rs1,$rs2,$rd";
-
-    if (defined($opf=$aesopf{$mnemonic})) {
-	foreach ($rs1,$rs2,$rd) {
-	    return $ref if (!/%f([0-9]{1,2})/);
-	    $_=$1;
-	    if ($1>=32) {
-		return $ref if ($1&1);
-		# re-encode for upper double register addressing
-		$_=($1|$1>>5)&31;
-	    }
-	}
-
-	return	sprintf ".word\t0x%08x !%s",
-			2<<30|$rd<<25|0x36<<19|$rs1<<14|$opf<<5|$rs2,
-			$ref;
-    } else {
-	return $ref;
-    }
-}
-
-sub uncamellia_f {	# 4-argument instructions
-my ($mnemonic,$rs1,$rs2,$rs3,$rd)=@_;
-my ($ref,$opf);
-
-    $ref = "$mnemonic\t$rs1,$rs2,$rs3,$rd";
-
-    if (1) {
-	$rs3 = ($rs3 =~ /%f([0-6]*[02468])/) ? (($1|$1>>5)&31) : $rs3;
-	foreach ($rs1,$rs2,$rd) {
-	    return $ref if (!/%f([0-9]{1,2})/);
-	    $_=$1;
-	    if ($1>=32) {
-		return $ref if ($1&1);
-		# re-encode for upper double register addressing
-		$_=($1|$1>>5)&31;
-	    }
-	}
-
-	return	sprintf ".word\t0x%08x !%s",
-			2<<30|$rd<<25|0x19<<19|$rs1<<14|$rs3<<9|0xc<<5|$rs2,
-			$ref;
-    } else {
-	return $ref;
-    }
-}
-
-sub uncamellia3 {	# 3-argument instructions
-my ($mnemonic,$rs1,$rs2,$rd)=@_;
-my ($ref,$opf);
-my %cmllopf = (	"camellia_fl"	=> 0x13c,
-		"camellia_fli"	=> 0x13d	);
-
-    $ref = "$mnemonic\t$rs1,$rs2,$rd";
-
-    if (defined($opf=$cmllopf{$mnemonic})) {
-	foreach ($rs1,$rs2,$rd) {
-	    return $ref if (!/%f([0-9]{1,2})/);
-	    $_=$1;
-	    if ($1>=32) {
-		return $ref if ($1&1);
-		# re-encode for upper double register addressing
-		$_=($1|$1>>5)&31;
-	    }
-	}
-
-	return	sprintf ".word\t0x%08x !%s",
-			2<<30|$rd<<25|0x36<<19|$rs1<<14|$opf<<5|$rs2,
-			$ref;
-    } else {
-	return $ref;
-    }
-}
-
-sub unmovxtox {		# 2-argument instructions
-my ($mnemonic,$rs,$rd)=@_;
-my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24, "f" => 0 );
-my ($ref,$opf);
-my %movxopf = (	"movdtox"	=> 0x110,
-		"movstouw"	=> 0x111,
-		"movstosw"	=> 0x113,
-		"movxtod"	=> 0x118,
-		"movwtos"	=> 0x119	);
-
-    $ref = "$mnemonic\t$rs,$rd";
-
-    if (defined($opf=$movxopf{$mnemonic})) {
-	foreach ($rs,$rd) {
-	    return $ref if (!/%([fgoli])([0-9]{1,2})/);
-	    $_=$bias{$1}+$2;
-	    if ($2>=32) {
-		return $ref if ($2&1);
-		# re-encode for upper double register addressing
-		$_=($2|$2>>5)&31;
-	    }
-	}
-
-	return	sprintf ".word\t0x%08x !%s",
-			2<<30|$rd<<25|0x36<<19|$opf<<5|$rs,
-			$ref;
-    } else {
-	return $ref;
-    }
-}
-
-sub undes {
-my ($mnemonic)=shift;
-my @args=@_;
-my ($ref,$opf);
-my %desopf = (	"des_round"	=> 0b1001,
-		"des_ip"	=> 0b100110100,
-		"des_iip"	=> 0b100110101,
-		"des_kexpand"	=> 0b100110110	);
-
-    $ref = "$mnemonic\t".join(",",@_);
-
-    if (defined($opf=$desopf{$mnemonic})) {	# 4-arg
-	if ($mnemonic eq "des_round") {
-	    foreach (@args[0..3]) {
-		return $ref if (!/%f([0-9]{1,2})/);
-		$_=$1;
-		if ($1>=32) {
-		    return $ref if ($1&1);
-		    # re-encode for upper double register addressing
-		    $_=($1|$1>>5)&31;
-		}
-	    }
-	    return  sprintf ".word\t0x%08x !%s",
-			    2<<30|0b011001<<19|$opf<<5|$args[0]<<14|$args[1]|$args[2]<<9|$args[3]<<25,
-			    $ref;
-	} elsif ($mnemonic eq "des_kexpand") {	# 3-arg
-	    foreach (@args[0..2]) {
-		return $ref if (!/(%f)?([0-9]{1,2})/);
-		$_=$2;
-		if ($2>=32) {
-		    return $ref if ($2&1);
-		    # re-encode for upper double register addressing
-		    $_=($2|$2>>5)&31;
-		}
-	    }
-	    return  sprintf ".word\t0x%08x !%s",
-			    2<<30|0b110110<<19|$opf<<5|$args[0]<<14|$args[1]|$args[2]<<25,
-			    $ref;
-	} else {				# 2-arg
-	    foreach (@args[0..1]) {
-		return $ref if (!/%f([0-9]{1,2})/);
-		$_=$1;
-		if ($1>=32) {
-		    return $ref if ($2&1);
-		    # re-encode for upper double register addressing
-		    $_=($1|$1>>5)&31;
-		}
-	    }
-	    return  sprintf ".word\t0x%08x !%s",
-			    2<<30|0b110110<<19|$opf<<5|$args[0]<<14|$args[1]<<25,
-			    $ref;
-	}
-    } else {
-	return $ref;
-    }
-}
-
-sub emit_assembler {
-    foreach (split("\n",$::code)) {
-	s/\`([^\`]*)\`/eval $1/ge;
-
-	s/\b(f[a-z]+2[sd]*)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})\s*$/$1\t%f0,$2,$3/go;
-
-	s/\b(aes_[edk][^\s]*)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*([%fx0-9]+),\s*(%f[0-9]{1,2})/
-		&unaes_round($1,$2,$3,$4,$5)
-	 /geo or
-	s/\b(aes_kexpand[02])\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})/
-		&unaes_kexpand($1,$2,$3,$4)
-	 /geo or
-	s/\b(camellia_f)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*([%fx0-9]+),\s*(%f[0-9]{1,2})/
-		&uncamellia_f($1,$2,$3,$4,$5)
-	 /geo or
-	s/\b(camellia_[^s]+)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})/
-		&uncamellia3($1,$2,$3,$4)
-	 /geo or
-	s/\b(des_\w+)\s+(?<rs1>%f[0-9]{1,2}),\s*(?<rs2>[%fx0-9]+)(,\s*(?<rs3>%f[0-9]{1,2})(,\s*(?<rs4>%f[0-9]{1,2}))?)?/
-		&undes($1,$+{rs1},$+{rs2},$+{rs3},$+{rs4})
-	 /geo or
-	s/\b(mov[ds]to\w+)\s+(%f[0-9]{1,2}),\s*(%[goli][0-7])/
-		&unmovxtox($1,$2,$3)
-	 /geo or
-	s/\b(mov[xw]to[ds])\s+(%[goli][0-7]),\s*(%f[0-9]{1,2})/
-		&unmovxtox($1,$2,$3)
-	 /geo or
-	s/\b([fb][^\s]*)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})/
-		&unvis($1,$2,$3,$4)
-	 /geo or
-	s/\b(umulxhi|bmask|addxc[c]{0,2}|alignaddr[l]*)\s+(%[goli][0-7]),\s*(%[goli][0-7]),\s*(%[goli][0-7])/
-		&unvis3($1,$2,$3,$4)
-	 /geo;
-
-	print $_,"\n";
-    }
-}
-
-1;
--- a/components/openssl/openssl-1.0.1/inline-t4/vis3-mont.pl	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,373 +0,0 @@
-#!/usr/bin/env perl
-
-# ====================================================================
-# Written by Andy Polyakov <[email protected]> for the OpenSSL
-# project. The module is, however, dual licensed under OpenSSL and
-# CRYPTOGAMS licenses depending on where you obtain it. For further
-# details see http://www.openssl.org/~appro/cryptogams/.
-# ====================================================================
-
-# October 2012.
-#
-# SPARCv9 VIS3 Montgomery multiplicaion procedure suitable for T3 and
-# onward. There are three new instructions used here: umulxhi,
-# addxc[cc] and initializing store. On T3 RSA private key operations
-# are 1.54/1.87/2.11/2.26 times faster for 512/1024/2048/4096-bit key
-# lengths. This is without dedicated squaring procedure. On T4
-# corresponding coefficients are 1.47/2.10/2.80/2.90x, which is mostly
-# for reference purposes, because T4 has dedicated Montgomery
-# multiplication and squaring *instructions* that deliver even more.
-
-$bits=32;
-for (@ARGV)     { $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
-if ($bits==64)  { $bias=2047; $frame=192; }
-else            { $bias=0;    $frame=112; }
-
-$code.=<<___ if ($bits==64);
-.register	%g2,#scratch
-.register	%g3,#scratch
-___
-$code.=<<___;
-.section	".text",#alloc,#execinstr
-___
-
-($n0,$m0,$m1,$lo0,$hi0, $lo1,$hi1,$aj,$alo,$nj,$nlo,$tj)=
-	(map("%g$_",(1..5)),map("%o$_",(0..5,7)));
-
-# int bn_mul_mont(
-$rp="%o0";	# BN_ULONG *rp,
-$ap="%o1";	# const BN_ULONG *ap,
-$bp="%o2";	# const BN_ULONG *bp,
-$np="%o3";	# const BN_ULONG *np,
-$n0p="%o4";	# const BN_ULONG *n0,
-$num="%o5";	# int num);	# caller ensures that num is even
-				# and >=6
-$code.=<<___;
-.globl	bn_mul_mont_vis3
-.align	32
-bn_mul_mont_vis3:
-	add	%sp,	$bias,	%g4	! real top of stack
-	sll	$num,	2,	$num	! size in bytes
-	add	$num,	63,	%g5
-	andn	%g5,	63,	%g5	! buffer size rounded up to 64 bytes
-	add	%g5,	%g5,	%g1
-	add	%g5,	%g1,	%g1	! 3*buffer size
-	sub	%g4,	%g1,	%g1
-	andn	%g1,	63,	%g1	! align at 64 byte
-	sub	%g1,	$frame,	%g1	! new top of stack
-	sub	%g1,	%g4,	%g1
-
-	save	%sp,	%g1,	%sp
-___
-
-#	+-------------------------------+<-----	%sp
-#	.				.
-#	+-------------------------------+<-----	aligned at 64 bytes
-#	| __int64 tmp[0]		|
-#	+-------------------------------+
-#	.				.
-#	.				.
-#	+-------------------------------+<----- aligned at 64 bytes
-#	| __int64 ap[1..0]		|	converted ap[]
-#	+-------------------------------+
-#	| __int64 np[1..0]		|	converted np[]
-#	+-------------------------------+
-#	| __int64 ap[3..2]		|
-#	.				.
-#	.				.
-#	+-------------------------------+
-($rp,$ap,$bp,$np,$n0p,$num)=map("%i$_",(0..5));
-($t0,$t1,$t2,$t3,$cnt,$tp,$bufsz,$anp)=map("%l$_",(0..7));
-($ovf,$i)=($t0,$t1);
-$code.=<<___;
-	ld	[$n0p+0],	$t0	! pull n0[0..1] value
-	add	%sp, $bias+$frame, $tp
-	ld	[$n0p+4],	$t1
-	add	$tp,	%g5,	$anp
-	ld	[$bp+0],	$t2	! m0=bp[0]
-	sllx	$t1,	32,	$n0
-	ld	[$bp+4],	$t3
-	or	$t0,	$n0,	$n0
-	add	$bp,	8,	$bp
-
-	ld	[$ap+0],	$t0	! ap[0]
-	sllx	$t3,	32,	$m0
-	ld	[$ap+4],	$t1
-	or	$t2,	$m0,	$m0
-
-	ld	[$ap+8],	$t2	! ap[1]
-	sllx	$t1,	32,	$aj
-	ld	[$ap+12],	$t3
-	or	$t0,	$aj,	$aj
-	add	$ap,	16,	$ap
-	stxa	$aj,	[$anp]0xe2	! converted ap[0]
-
-	mulx	$aj,	$m0,	$lo0	! ap[0]*bp[0]
-	umulxhi	$aj,	$m0,	$hi0
-
-	ld	[$np+0],	$t0	! np[0]
-	sllx	$t3,	32,	$aj
-	ld	[$np+4],	$t1
-	or	$t2,	$aj,	$aj
-
-	ld	[$np+8],	$t2	! np[1]
-	sllx	$t1,	32,	$nj
-	ld	[$np+12],	$t3
-	or	$t0, $nj,	$nj
-	add	$np,	16,	$np
-	stx	$nj,	[$anp+8]	! converted np[0]
-
-	mulx	$lo0,	$n0,	$m1	! "tp[0]"*n0
-	stx	$aj,	[$anp+16]	! converted ap[1]
-
-	mulx	$aj,	$m0,	$alo	! ap[1]*bp[0]
-	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-
-	mulx	$nj,	$m1,	$lo1	! np[0]*m1
-	umulxhi	$nj,	$m1,	$hi1
-
-	sllx	$t3,	32,	$nj
-	or	$t2,	$nj,	$nj
-	stx	$nj,	[$anp+24]	! converted np[1]
-	add	$anp,	32,	$anp
-
-	addcc	$lo0,	$lo1,	$lo1
-	addxc	%g0,	$hi1,	$hi1
-
-	mulx	$nj,	$m1,	$nlo	! np[1]*m1
-	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-
-	ba	.L1st
-	sub	$num,	24,	$cnt	! cnt=num-3
-
-.align	16
-.L1st:
-	ld	[$ap+0],	$t0	! ap[j]
-	addcc	$alo,	$hi0,	$lo0
-	ld	[$ap+4],	$t1
-	addxc	$aj,	%g0,	$hi0
-
-	sllx	$t1,	32,	$aj
-	add	$ap,	8,	$ap
-	or	$t0,	$aj,	$aj
-	stxa	$aj,	[$anp]0xe2	! converted ap[j]
-
-	ld	[$np+0],	$t2	! np[j]
-	addcc	$nlo,	$hi1,	$lo1
-	ld	[$np+4],	$t3
-	addxc	$nj,	%g0,	$hi1	! nhi=nj
-
-	sllx	$t3,	32,	$nj
-	add	$np,	8,	$np
-	mulx	$aj,	$m0,	$alo	! ap[j]*bp[0]
-	or	$t2,	$nj,	$nj
-	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-	stx	$nj,	[$anp+8]	! converted np[j]
-	add	$anp,	16,	$anp	! anp++
-
-	mulx	$nj,	$m1,	$nlo	! np[j]*m1
-	addcc	$lo0,	$lo1,	$lo1	! np[j]*m1+ap[j]*bp[0]
-	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-	addxc	%g0,	$hi1,	$hi1
-	stxa	$lo1,	[$tp]0xe2	! tp[j-1]
-	add	$tp,	8,	$tp	! tp++
-
-	brnz,pt	$cnt,	.L1st
-	sub	$cnt,	8,	$cnt	! j--
-!.L1st
-	addcc	$alo,	$hi0,	$lo0
-	addxc	$aj,	%g0,	$hi0	! ahi=aj
-
-	addcc	$nlo,	$hi1,	$lo1
-	addxc	$nj,	%g0,	$hi1
-	addcc	$lo0,	$lo1,	$lo1	! np[j]*m1+ap[j]*bp[0]
-	addxc	%g0,	$hi1,	$hi1
-	stxa	$lo1,	[$tp]0xe2	! tp[j-1]
-	add	$tp,	8,	$tp
-
-	addcc	$hi0,	$hi1,	$hi1
-	addxc	%g0,	%g0,	$ovf	! upmost overflow bit
-	stxa	$hi1,	[$tp]0xe2
-	add	$tp,	8,	$tp
-
-	ba	.Louter
-	sub	$num,	16,	$i	! i=num-2
-
-.align	16
-.Louter:
-	ld	[$bp+0],	$t2	! m0=bp[i]
-	ld	[$bp+4],	$t3
-
-	sub	$anp,	$num,	$anp	! rewind
-	sub	$tp,	$num,	$tp
-	sub	$anp,	$num,	$anp
-
-	add	$bp,	8,	$bp
-	sllx	$t3,	32,	$m0
-	ldx	[$anp+0],	$aj	! ap[0]
-	or	$t2,	$m0,	$m0
-	ldx	[$anp+8],	$nj	! np[0]
-
-	mulx	$aj,	$m0,	$lo0	! ap[0]*bp[i]
-	ldx	[$tp],		$tj	! tp[0]
-	umulxhi	$aj,	$m0,	$hi0
-	ldx	[$anp+16],	$aj	! ap[1]
-	addcc	$lo0,	$tj,	$lo0	! ap[0]*bp[i]+tp[0]
-	mulx	$aj,	$m0,	$alo	! ap[1]*bp[i]
-	addxc	%g0,	$hi0,	$hi0
-	mulx	$lo0,	$n0,	$m1	! tp[0]*n0
-	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-	mulx	$nj,	$m1,	$lo1	! np[0]*m1
-	umulxhi	$nj,	$m1,	$hi1
-	ldx	[$anp+24],	$nj	! np[1]
-	add	$anp,	32,	$anp
-	addcc	$lo1,	$lo0,	$lo1
-	mulx	$nj,	$m1,	$nlo	! np[1]*m1
-	addxc	%g0,	$hi1,	$hi1
-	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-
-	ba	.Linner
-	sub	$num,	24,	$cnt	! cnt=num-3
-.align	16
-.Linner:
-	addcc	$alo,	$hi0,	$lo0
-	ldx	[$tp+8],	$tj	! tp[j]
-	addxc	$aj,	%g0,	$hi0	! ahi=aj
-	ldx	[$anp+0],	$aj	! ap[j]
-	addcc	$nlo,	$hi1,	$lo1
-	mulx	$aj,	$m0,	$alo	! ap[j]*bp[i]
-	addxc	$nj,	%g0,	$hi1	! nhi=nj
-	ldx	[$anp+8],	$nj	! np[j]
-	add	$anp,	16,	$anp
-	umulxhi	$aj,	$m0,	$aj	! ahi=aj
-	addcc	$lo0,	$tj,	$lo0	! ap[j]*bp[i]+tp[j]
-	mulx	$nj,	$m1,	$nlo	! np[j]*m1
-	addxc	%g0,	$hi0,	$hi0
-	umulxhi	$nj,	$m1,	$nj	! nhi=nj
-	addcc	$lo1,	$lo0,	$lo1	! np[j]*m1+ap[j]*bp[i]+tp[j]
-	addxc	%g0,	$hi1,	$hi1
-	stx	$lo1,	[$tp]		! tp[j-1]
-	add	$tp,	8,	$tp
-	brnz,pt	$cnt,	.Linner
-	sub	$cnt,	8,	$cnt
-!.Linner
-	ldx	[$tp+8],	$tj	! tp[j]
-	addcc	$alo,	$hi0,	$lo0
-	addxc	$aj,	%g0,	$hi0	! ahi=aj
-	addcc	$lo0,	$tj,	$lo0	! ap[j]*bp[i]+tp[j]
-	addxc	%g0,	$hi0,	$hi0
-
-	addcc	$nlo,	$hi1,	$lo1
-	addxc	$nj,	%g0,	$hi1	! nhi=nj
-	addcc	$lo1,	$lo0,	$lo1	! np[j]*m1+ap[j]*bp[i]+tp[j]
-	addxc	%g0,	$hi1,	$hi1
-	stx	$lo1,	[$tp]		! tp[j-1]
-
-	subcc	%g0,	$ovf,	%g0	! move upmost overflow to CCR.xcc
-	addxccc	$hi1,	$hi0,	$hi1
-	addxc	%g0,	%g0,	$ovf
-	stx	$hi1,	[$tp+8]
-	add	$tp,	16,	$tp
-
-	brnz,pt	$i,	.Louter
-	sub	$i,	8,	$i
-
-	sub	$anp,	$num,	$anp	! rewind
-	sub	$tp,	$num,	$tp
-	sub	$anp,	$num,	$anp
-	ba	.Lsub
-	subcc	$num,	8,	$cnt	! cnt=num-1 and clear CCR.xcc
-
-.align	16
-.Lsub:
-	ldx	[$tp],		$tj
-	add	$tp,	8,	$tp
-	ldx	[$anp+8],	$nj
-	add	$anp,	16,	$anp
-	subccc	$tj,	$nj,	$t2	! tp[j]-np[j]
-	srlx	$tj,	32,	$tj
-	srlx	$nj,	32,	$nj
-	subccc	$tj,	$nj,	$t3
-	add	$rp,	8,	$rp
-	st	$t2,	[$rp-4]		! reverse order
-	st	$t3,	[$rp-8]
-	brnz,pt	$cnt,	.Lsub
-	sub	$cnt,	8,	$cnt
-
-	sub	$anp,	$num,	$anp	! rewind
-	sub	$tp,	$num,	$tp
-	sub	$anp,	$num,	$anp
-	sub	$rp,	$num,	$rp
-
-	subc	$ovf,	%g0,	$ovf	! handle upmost overflow bit
-	and	$tp,	$ovf,	$ap
-	andn	$rp,	$ovf,	$np
-	or	$np,	$ap,	$ap	! ap=borrow?tp:rp
-	ba	.Lcopy
-	sub	$num,	8,	$cnt
-
-.align	16
-.Lcopy:					! copy or in-place refresh
-	ld	[$ap+0],	$t2
-	ld	[$ap+4],	$t3
-	add	$ap,	8,	$ap
-	stx	%g0,	[$tp]		! zap
-	add	$tp,	8,	$tp
-	stx	%g0,	[$anp]		! zap
-	stx	%g0,	[$anp+8]
-	add	$anp,	16,	$anp
-	st	$t3,	[$rp+0]		! flip order
-	st	$t2,	[$rp+4]
-	add	$rp,	8,	$rp
-	brnz	$cnt,	.Lcopy
-	sub	$cnt,	8,	$cnt
-
-	mov	1,	%o0
-	ret
-	restore
-.type	bn_mul_mont_vis3, #function
-.size	bn_mul_mont_vis3, .-bn_mul_mont_vis3
-.asciz  "Montgomery Multiplication for SPARCv9 VIS3, CRYPTOGAMS by <appro\@openssl.org>"
-.align	4
-___
-
-# Purpose of these subroutines is to explicitly encode VIS instructions,
-# so that one can compile the module without having to specify VIS
-# extentions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a.
-# Idea is to reserve for option to produce "universal" binary and let
-# programmer detect if current CPU is VIS capable at run-time.
-sub unvis3 {
-my ($mnemonic,$rs1,$rs2,$rd)=@_;
-my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 );
-my ($ref,$opf);
-my %visopf = (	"addxc"		=> 0x011,
-		"addxccc"	=> 0x013,
-		"umulxhi"	=> 0x016	);
-
-    $ref = "$mnemonic\t$rs1,$rs2,$rd";
-
-    if ($opf=$visopf{$mnemonic}) {
-	foreach ($rs1,$rs2,$rd) {
-	    return $ref if (!/%([goli])([0-9])/);
-	    $_=$bias{$1}+$2;
-	}
-
-	return	sprintf ".word\t0x%08x !%s",
-			0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
-			$ref;
-    } else {
-	return $ref;
-    }
-}
-
-foreach (split("\n",$code)) {
-	s/\`([^\`]*)\`/eval $1/ge;
-
-	s/\b(umulxhi|addxc[c]{0,2})\s+(%[goli][0-7]),\s*(%[goli][0-7]),\s*(%[goli][0-7])/
-		&unvis3($1,$2,$3,$4)
-	 /ge;
-
-	print $_,"\n";
-}
-
-close STDOUT;
--- a/components/openssl/openssl-1.0.1/llib-lcrypto	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* LINTLIBRARY */
-/* PROTOLIB1 */
-
-#include <openssl/aes.h>
-#include <openssl/asn1.h>
-#include <openssl/asn1_mac.h>
-#include <openssl/asn1t.h>
-#include <openssl/bio.h>
-#include <openssl/blowfish.h>
-#include <openssl/bn.h>
-#include <openssl/buffer.h>
-#include <openssl/camellia.h>
-#include <openssl/cms.h>
-#include <openssl/comp.h>
-#include <openssl/conf.h>
-#include <openssl/conf_api.h>
-#include <openssl/crypto.h>
-#include <openssl/des.h>
-#include <openssl/dh.h>
-#include <openssl/dsa.h>
-#include <openssl/dso.h>
-#include <openssl/e_os2.h>
-#include <openssl/ebcdic.h>
-#include <openssl/engine.h>
-#include <openssl/err.h>
-#include <openssl/evp.h>
-#include <openssl/hmac.h>
-#include <openssl/krb5_asn.h>
-#include <openssl/kssl.h>
-#include <openssl/lhash.h>
-#include <openssl/md2.h>
-#include <openssl/md4.h>
-#include <openssl/md5.h>
-#include <openssl/modes.h>
-#include <openssl/obj_mac.h>
-#include <openssl/objects.h>
-#include <openssl/opensslconf.h>
-#include <openssl/opensslv.h>
-#include <openssl/pem.h>
-#include <openssl/pem2.h>
-#include <openssl/pkcs12.h>
-#include <openssl/pkcs7.h>
-#include <openssl/pqueue.h>
-#include <openssl/rand.h>
-#include <openssl/ripemd.h>
-#include <openssl/rsa.h>
-#include <openssl/safestack.h>
-#include <openssl/sha.h>
-#include <openssl/stack.h>
-#include <openssl/symhacks.h>
-#include <openssl/ts.h>
-#include <openssl/txt_db.h>
-#include <openssl/ui.h>
-#include <openssl/ui_compat.h>
-#include <openssl/x509.h>
-#include <openssl/x509_vfy.h>
-#include <openssl/x509v3.h>
-
--- a/components/openssl/openssl-1.0.1/llib-lssl	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* LINTLIBRARY */
-/* PROTOLIB1 */
-
-#include <openssl/ssl.h>
-#include <openssl/ssl2.h>
-#include <openssl/ssl23.h>
-#include <openssl/ssl3.h>
-#include <openssl/tls1.h>
--- a/components/openssl/openssl-1.0.1/mapfile.wanboot	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-# Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
-#
-
-#
-# This file defines interface requirements of wanboot on OpenSSL.
-#
-
-$mapfile_version 2
-SYMBOL_SCOPE {
-		ERR_clear_error;
-		SSL_CTX_set_default_passwd_cb;
-		SSL_load_error_strings;
-		EVP_PKEY_free;
-		SSL_get_peer_certificate;
-		SSL_CIPHER_get_name;
-		sk_value;
-		RAND_load_file;
-		X509_NAME_oneline;
-		SSL_write;
-		X509_NAME_get_text_by_NID;
-		OPENSSL_uni2asc;
-		SSL_CTX_set_default_passwd_cb_userdata;
-		SSL_CTX_use_PrivateKey_file;
-		OPENSSL_asc2uni;
-		SSL_get_error;
-		ASN1_UTF8STRING_free;
-		ASN1_mbstring_copy;
-		ERR_error_string;
-		PKCS12_unpack_p7data;
-		X509_free;
-		ERR_get_error;
-		ERR_put_error;
-		PKCS12_free;
-		ASN1_UTF8STRING_new;
-		OPENSSL_add_all_algorithms_noconf;
-		OBJ_nid2obj;
-		PKCS12_SAFEBAG_free;
-		ASN1_STRING_free;
-		sk_delete;
-		OBJ_obj2nid;
-		SSL_CTX_set_verify_depth;
-		PKCS8_PRIV_KEY_INFO_free;
-		SSL_set_connect_state;
-		sk_pop_free;
-		BIO_s_file;
-		SSL_set_fd;
-		SSL_CTX_use_PrivateKey;
-		ASN1_STRING_to_UTF8;
-		PKCS12_certbag2x509;
-		PKCS7_free;
-		PKCS12_decrypt_skey;
-		BIO_new;
-		RAND_status;
-		sk_num;
-		SSL_get_verify_result;
-		SSL_free;
-		SSL_read;
-		SSL_new;
-		SSLv3_client_method;
-		TLSv1_2_client_method;
-		X509_check_private_key;
-		SSL_CTX_new;
-		ASN1_TYPE_set;
-		ASN1_TYPE_new;
-		ERR_peek_error;
-		CRYPTO_free;
-		SSL_CTX_load_verify_locations;
-		PKCS12_unpack_authsafes;
-		X509_ATTRIBUTE_new;
-		PKCS12_unpack_p7encdata;
-		sk_push;
-		SSL_connect;
-		SSL_shutdown;
-		SSL_CTX_use_certificate_file;
-		PKCS12_get_attr_gen;
-		X509_verify_cert_error_string;
-		X509_ATTRIBUTE_free;
-		X509_alias_set1;
-		PKCS12_verify_mac;
-		ASN1_TIME_print;
-		SSL_CTX_use_certificate;
-		SSL_get_ciphers;
-		SSL_CTX_ctrl;
-		SSL_CTX_free;
-		X509_keyid_set1;
-		ERR_load_strings;
-		EVP_EncodeBlock;
-		ASN1_TYPE_free;
-		sk_new_null;
-		SSL_get_current_cipher;
-		ASN1_STRING_cmp;
-		ASN1_STRING_set;
-		ERR_get_next_error_library;
-		EVP_PKCS82PKEY;
-		X509_get_issuer_name;
-		CRYPTO_malloc;
-		BIO_ctrl;
-		BIO_free;
-		X509_STORE_add_cert;
-		ASN1_STRING_type_new;
-		SSL_CTX_set_cipher_list;
-		X509_get_subject_name;
-		SSL_library_init;
-		d2i_PKCS12_fp;
-	local:
-		*;
-};
--- a/components/openssl/openssl-1.0.1/openssl-1.0.1.license	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +0,0 @@
-
-  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. Actually both licenses are BSD-style
-  Open Source licenses. In case of any license issues related to OpenSSL
-  please contact [email protected].
-
-  OpenSSL License
-  ---------------
-
-/* ====================================================================
- * Copyright (c) 1998-2016 The OpenSSL Project.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission. For written permission, please contact
- *    [email protected].
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- *    nor may "OpenSSL" appear in their names without prior written
- *    permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the OpenSSL Project
- *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * ([email protected]).  This product includes software written by Tim
- * Hudson ([email protected]).
- *
- */
-
- Original SSLeay License
- -----------------------
-
-/* Copyright (C) 1995-1998 Eric Young ([email protected])
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young ([email protected]).
- * The implementation was written so as to conform with Netscapes SSL.
- * 
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to.  The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson ([email protected]).
- * 
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *    "This product includes cryptographic software written by
- *     Eric Young ([email protected])"
- *    The word 'cryptographic' can be left out if the rouines from the library
- *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
- *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson ([email protected])"
- * 
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * 
- * The licence and distribution terms for any publically available version or
- * derivative of 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/components/openssl/openssl-1.0.1/openssl-1.0.1.p5m	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2218 +0,0 @@
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
-#
-
-<transform file path=usr.*/man/.+ -> default mangler.man.stability uncommitted>
-set name=pkg.fmri \
-    value=pkg:/library/security/openssl@$(IPS_COMPONENT_VERSION),$(BUILD_VERSION)
-set name=pkg.summary \
-    value="OpenSSL - a Toolkit for Secure Sockets Layer (SSL v2/v3) and Transport Layer (TLS v1) protocols and general purpose cryptographic library"
-set name=pkg.description \
-    value="OpenSSL is a full-featured toolkit implementing the Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1) protocols as well as a full-strength general purpose cryptography library."
-set name=pkg.human-version value=$(COMPONENT_VERSION)
-set name=com.oracle.info.description value=OpenSSL
-set name=com.oracle.info.tpno value=$(TPNO)
-set name=info.classification value=org.opensolaris.category.2008:System/Security
-set name=info.source-url value=$(COMPONENT_ARCHIVE_URL)
-set name=info.upstream-url value=$(COMPONENT_PROJECT_URL)
-set name=org.opensolaris.arc-caseid value=PSARC/2011/025
-set name=org.opensolaris.consolidation value=$(CONSOLIDATION)
-dir  path=etc/openssl/certs group=sys
-
-# Basic directories, links, and a configuration file.
-file etc/openssl/openssl.cnf path=etc/openssl/default/openssl.cnf group=sys \
-    mode=0644 preserve=true
-file path=etc/openssl/openssl.cnf group=sys mode=0644 \
-    original_name=SUNWopenssl:etc/sfw/openssl/openssl.cnf preserve=true
-dir  path=etc/openssl/private group=sys mode=0700
-link path=etc/sfw/openssl target=../openssl
-link path=lib/$(MACH64)/libcrypto.so target=libcrypto.so.1.0.0
-
-# Mediator links for 64-bit libraries
-link path=lib/$(MACH64)/libcrypto.so.1.0.0 \
-    target=../openssl/default/$(MACH64)/libcrypto.so.1.0.0 mediator=openssl \
-    mediator-implementation=default mediator-priority=vendor
-link path=lib/$(MACH64)/libssl.so target=libssl.so.1.0.0
-link path=lib/$(MACH64)/libssl.so.1.0.0 \
-    target=../openssl/default/$(MACH64)/libssl.so.1.0.0 mediator=openssl \
-    mediator-implementation=default mediator-priority=vendor
-link path=lib/$(MACH64)/llib-lcrypto \
-    target=../openssl/default/$(MACH64)/llib-lcrypto mediator=openssl \
-    mediator-implementation=default mediator-priority=vendor
-link path=lib/$(MACH64)/llib-lcrypto.ln \
-    target=../openssl/default/$(MACH64)/llib-lcrypto.ln mediator=openssl \
-    mediator-implementation=default mediator-priority=vendor
-link path=lib/$(MACH64)/llib-lssl \
-    target=../openssl/default/$(MACH64)/llib-lssl mediator=openssl \
-    mediator-implementation=default mediator-priority=vendor
-link path=lib/$(MACH64)/llib-lssl.ln \
-    target=../openssl/default/$(MACH64)/llib-lssl.ln mediator=openssl \
-    mediator-implementation=default mediator-priority=vendor
-link path=lib/libcrypto.so target=libcrypto.so.1.0.0
-
-# Mediator links for 32-bit libraries
-link path=lib/libcrypto.so.1.0.0 target=openssl/default/libcrypto.so.1.0.0 \
-    mediator=openssl mediator-implementation=default mediator-priority=vendor
-link path=lib/libssl.so target=libssl.so.1.0.0
-link path=lib/libssl.so.1.0.0 target=openssl/default/libssl.so.1.0.0 \
-    mediator=openssl mediator-implementation=default mediator-priority=vendor
-link path=lib/llib-lcrypto target=openssl/default/llib-lcrypto \
-    mediator=openssl mediator-implementation=default mediator-priority=vendor
-link path=lib/llib-lcrypto.ln target=openssl/default/llib-lcrypto.ln \
-    mediator=openssl mediator-implementation=default mediator-priority=vendor
-link path=lib/llib-lssl target=openssl/default/llib-lssl mediator=openssl \
-    mediator-implementation=default mediator-priority=vendor
-link path=lib/llib-lssl.ln target=openssl/default/llib-lssl.ln \
-    mediator=openssl mediator-implementation=default mediator-priority=vendor
-
-# Commands.
-file $(MACH32)/apps/openssl path=lib/openssl/default/$(MACH32)/openssl \
-    owner=root group=bin mode=0555
-link path=lib/openssl/default/$(MACH64)/libcrypto.so target=libcrypto.so.1.0.0
-file $(MACH64)/libcrypto.so.1.0.0 \
-    path=lib/openssl/default/$(MACH64)/libcrypto.so.1.0.0
-link path=lib/openssl/default/$(MACH64)/libssl.so target=libssl.so.1.0.0
-file $(MACH64)/libssl.so.1.0.0 \
-    path=lib/openssl/default/$(MACH64)/libssl.so.1.0.0 owner=root group=bin \
-    mode=0555
-file llib-lcrypto path=lib/openssl/default/$(MACH64)/llib-lcrypto
-file $(MACH64)/llib-lcrypto.ln \
-    path=lib/openssl/default/$(MACH64)/llib-lcrypto.ln
-file llib-lssl path=lib/openssl/default/$(MACH64)/llib-lssl
-file $(MACH64)/llib-lssl.ln path=lib/openssl/default/$(MACH64)/llib-lssl.ln
-link path=lib/openssl/default/64 target=$(MACH64)
-file etc/openssl/misc/CA.pl path=lib/openssl/default/CA.pl
-link path=lib/openssl/default/engines/$(MACH64)/libpk11.so target=libpk11.so.1
-
-# 64 bit libraries, lint libraries, and engines.
-file $(MACH64)/engines/libpk11.so \
-    path=lib/openssl/default/engines/$(MACH64)/libpk11.so.1 owner=root \
-    group=bin mode=0555
-link path=lib/openssl/default/engines/libpk11.so target=libpk11.so.1
-
-# 32 bit libraries, lint libraries, and engines.
-file $(MACH32)/engines/libpk11.so \
-    path=lib/openssl/default/engines/libpk11.so.1 owner=root group=bin
-link path=lib/openssl/default/libcrypto.so target=libcrypto.so.1.0.0
-file $(MACH32)/libcrypto.so.1.0.0 path=lib/openssl/default/libcrypto.so.1.0.0
-link path=lib/openssl/default/libssl.so target=libssl.so.1.0.0
-file $(MACH32)/libssl.so.1.0.0 path=lib/openssl/default/libssl.so.1.0.0 \
-    owner=root group=bin mode=0555
-file llib-lcrypto path=lib/openssl/default/llib-lcrypto
-file $(MACH32)/llib-lcrypto.ln path=lib/openssl/default/llib-lcrypto.ln
-file llib-lssl path=lib/openssl/default/llib-lssl
-file $(MACH32)/llib-lssl.ln path=lib/openssl/default/llib-lssl.ln
-file $(MACH64)/apps/openssl path=lib/openssl/default/openssl owner=root \
-    group=bin mode=0555
-dir  path=lib/openssl/engines group=sys mode=0755
-dir  path=lib/openssl/engines/$(MACH64) group=sys mode=0755
-link path=lib/openssl/engines/$(MACH64)/libpk11.so target=libpk11.so.1
-link path=lib/openssl/engines/$(MACH64)/libpk11.so.1 \
-    target=../../default/engines/$(MACH64)/libpk11.so.1 mediator=openssl \
-    mediator-implementation=default mediator-priority=vendor
-link path=lib/openssl/engines/64 target=$(MACH64)
-link path=lib/openssl/engines/libpk11.so target=libpk11.so.1
-link path=lib/openssl/engines/libpk11.so.1 \
-    target=../default/engines/libpk11.so.1 mediator=openssl \
-    mediator-implementation=default mediator-priority=vendor
-
-# Wanboot static standalone openssl binaries
-file path=lib/openssl/wanboot/$(MACH64)/wanboot-openssl.o \
-    pkg.depend.bypass-generate=.* pkg.linted.userland.action001=true \
-    variant.arch=sparc
-link path=usr/bin/$(MACH32)/openssl \
-    target=../../../lib/openssl/default/$(MACH32)/openssl mediator=openssl \
-    mediator-implementation=default mediator-priority=vendor
-link path=usr/bin/CA.pl target=../../lib/openssl/default/CA.pl \
-    mediator=openssl mediator-implementation=default mediator-priority=vendor
-
-# Mediator links for the commands
-link path=usr/bin/openssl target=../../lib/openssl/default/openssl \
-    mediator=openssl mediator-implementation=default mediator-priority=vendor
-
-# Header and pkg files.
-file path=usr/include/openssl/aes.h
-file path=usr/include/openssl/asn1.h
-file path=usr/include/openssl/asn1_mac.h
-file path=usr/include/openssl/asn1t.h
-file path=usr/include/openssl/bio.h
-file path=usr/include/openssl/blowfish.h
-file path=usr/include/openssl/bn.h
-file path=usr/include/openssl/buffer.h
-file path=usr/include/openssl/camellia.h
-file path=usr/include/openssl/cast.h
-file path=usr/include/openssl/cmac.h
-file path=usr/include/openssl/cms.h
-file path=usr/include/openssl/comp.h
-file path=usr/include/openssl/conf.h
-file path=usr/include/openssl/conf_api.h
-file path=usr/include/openssl/crypto.h
-file path=usr/include/openssl/des.h
-file path=usr/include/openssl/des_old.h
-file path=usr/include/openssl/dh.h
-file path=usr/include/openssl/dsa.h
-file path=usr/include/openssl/dso.h
-file path=usr/include/openssl/dtls1.h
-file path=usr/include/openssl/e_os2.h
-file path=usr/include/openssl/ebcdic.h
-file path=usr/include/openssl/engine.h
-file path=usr/include/openssl/err.h
-file path=usr/include/openssl/evp.h
-file path=usr/include/openssl/hmac.h
-file path=usr/include/openssl/krb5_asn.h
-file path=usr/include/openssl/kssl.h
-file path=usr/include/openssl/lhash.h
-file path=usr/include/openssl/md2.h
-file path=usr/include/openssl/md4.h
-file path=usr/include/openssl/md5.h
-file path=usr/include/openssl/modes.h
-file path=usr/include/openssl/obj_mac.h
-file path=usr/include/openssl/objects.h
-file path=usr/include/openssl/ocsp.h
-# A special case. This header file is patched but possibly overwritten in the
-# proto are with the 64 bit install. We must use the one from the 32 bit build
-# which is the one we have a patch for.
-file $(MACH32)/include/openssl/opensslconf.h \
-    path=usr/include/openssl/opensslconf.h
-file path=usr/include/openssl/opensslv.h
-file path=usr/include/openssl/ossl_typ.h
-file path=usr/include/openssl/pem.h
-file path=usr/include/openssl/pem2.h
-file path=usr/include/openssl/pkcs12.h
-file path=usr/include/openssl/pkcs7.h
-file path=usr/include/openssl/pqueue.h
-file path=usr/include/openssl/rand.h
-file path=usr/include/openssl/rc2.h
-file path=usr/include/openssl/rc4.h
-file path=usr/include/openssl/ripemd.h
-file path=usr/include/openssl/rsa.h
-file path=usr/include/openssl/safestack.h
-file path=usr/include/openssl/sha.h
-file path=usr/include/openssl/srp.h
-file path=usr/include/openssl/srtp.h
-file path=usr/include/openssl/ssl.h
-file path=usr/include/openssl/ssl2.h
-file path=usr/include/openssl/ssl23.h
-file path=usr/include/openssl/ssl3.h
-file path=usr/include/openssl/stack.h
-file path=usr/include/openssl/symhacks.h
-file path=usr/include/openssl/tls1.h
-file path=usr/include/openssl/ts.h
-file path=usr/include/openssl/txt_db.h
-file path=usr/include/openssl/ui.h
-file path=usr/include/openssl/ui_compat.h
-file path=usr/include/openssl/x509.h
-file path=usr/include/openssl/x509_vfy.h
-file path=usr/include/openssl/x509v3.h
-link path=usr/lib/$(MACH64)/libcrypto.so \
-    target=../../../lib/$(MACH64)/libcrypto.so
-link path=usr/lib/$(MACH64)/libcrypto.so.1.0.0 \
-    target=../../../lib/$(MACH64)/libcrypto.so.1.0.0
-link path=usr/lib/$(MACH64)/libssl.so target=../../../lib/$(MACH64)/libssl.so
-link path=usr/lib/$(MACH64)/libssl.so.1.0.0 \
-    target=../../../lib/$(MACH64)/libssl.so.1.0.0
-file $(MACH64)/openssl.pc path=usr/lib/$(MACH64)/pkgconfig/openssl.pc
-link path=usr/lib/libcrypto.so target=../../lib/libcrypto.so
-link path=usr/lib/libcrypto.so.1.0.0 target=../../lib/libcrypto.so.1.0.0
-link path=usr/lib/libssl.so target=../../lib/libssl.so
-link path=usr/lib/libssl.so.1.0.0 target=../../lib/libssl.so.1.0.0
-
-# Manual pages.
-file $(MACH32)/openssl.pc path=usr/lib/pkgconfig/openssl.pc
-link path=usr/sfw/bin/$(MACH64)/openssl target=../../../bin/openssl
-link path=usr/sfw/bin/openssl target=../../bin/openssl
-file path=usr/share/man/man1openssl/CA.pl.1openssl
-file path=usr/share/man/man1openssl/asn1parse.1openssl
-file path=usr/share/man/man1openssl/ca.1openssl
-file path=usr/share/man/man1openssl/ciphers.1openssl
-file path=usr/share/man/man1openssl/cms.1openssl
-file path=usr/share/man/man1openssl/crl.1openssl
-file path=usr/share/man/man1openssl/crl2pkcs7.1openssl
-file path=usr/share/man/man1openssl/dgst.1openssl
-file path=usr/share/man/man1openssl/dhparam.1openssl
-file path=usr/share/man/man1openssl/dsa.1openssl
-file path=usr/share/man/man1openssl/dsaparam.1openssl
-file path=usr/share/man/man1openssl/ec.1openssl
-file path=usr/share/man/man1openssl/ecparam.1openssl
-file path=usr/share/man/man1openssl/enc.1openssl
-file path=usr/share/man/man1openssl/errstr.1openssl
-file path=usr/share/man/man1openssl/gendsa.1openssl
-file path=usr/share/man/man1openssl/genpkey.1openssl
-file path=usr/share/man/man1openssl/genrsa.1openssl
-link path=usr/share/man/man1openssl/md2.1openssl target=dgst.1openssl
-link path=usr/share/man/man1openssl/md4.1openssl target=dgst.1openssl
-link path=usr/share/man/man1openssl/md5.1openssl target=dgst.1openssl
-link path=usr/share/man/man1openssl/mdc2.1openssl target=dgst.1openssl
-file path=usr/share/man/man1openssl/nseq.1openssl
-file path=usr/share/man/man1openssl/ocsp.1openssl
-file path=usr/share/man/man1openssl/openssl.1openssl
-file path=usr/share/man/man1openssl/passwd.1openssl
-file path=usr/share/man/man1openssl/pkcs12.1openssl
-file path=usr/share/man/man1openssl/pkcs7.1openssl
-file path=usr/share/man/man1openssl/pkcs8.1openssl
-file path=usr/share/man/man1openssl/pkey.1openssl
-file path=usr/share/man/man1openssl/pkeyparam.1openssl
-file path=usr/share/man/man1openssl/pkeyutl.1openssl
-file path=usr/share/man/man1openssl/rand.1openssl
-file path=usr/share/man/man1openssl/req.1openssl
-link path=usr/share/man/man1openssl/ripemd160.1openssl target=dgst.1openssl
-file path=usr/share/man/man1openssl/rsa.1openssl
-file path=usr/share/man/man1openssl/rsautl.1openssl
-file path=usr/share/man/man1openssl/s_client.1openssl
-file path=usr/share/man/man1openssl/s_server.1openssl
-file path=usr/share/man/man1openssl/s_time.1openssl
-file path=usr/share/man/man1openssl/sess_id.1openssl
-link path=usr/share/man/man1openssl/sha.1openssl target=dgst.1openssl
-link path=usr/share/man/man1openssl/sha1.1openssl target=dgst.1openssl
-file path=usr/share/man/man1openssl/smime.1openssl
-file path=usr/share/man/man1openssl/speed.1openssl
-file path=usr/share/man/man1openssl/spkac.1openssl
-file path=usr/share/man/man1openssl/ts.1openssl
-file path=usr/share/man/man1openssl/tsget.1openssl
-file path=usr/share/man/man1openssl/verify.1openssl
-file path=usr/share/man/man1openssl/version.1openssl
-file path=usr/share/man/man1openssl/x509.1openssl
-link path=usr/share/man/man3openssl/ASN1_OBJECT_free.3openssl \
-    target=ASN1_OBJECT_new.3openssl
-file path=usr/share/man/man3openssl/ASN1_OBJECT_new.3openssl
-link path=usr/share/man/man3openssl/ASN1_STRING_cmp.3openssl \
-    target=ASN1_STRING_length.3openssl
-link path=usr/share/man/man3openssl/ASN1_STRING_data.3openssl \
-    target=ASN1_STRING_length.3openssl
-link path=usr/share/man/man3openssl/ASN1_STRING_dup.3openssl \
-    target=ASN1_STRING_length.3openssl
-link path=usr/share/man/man3openssl/ASN1_STRING_free.3openssl \
-    target=ASN1_STRING_new.3openssl
-file path=usr/share/man/man3openssl/ASN1_STRING_length.3openssl
-link path=usr/share/man/man3openssl/ASN1_STRING_length_set.3openssl \
-    target=ASN1_STRING_length.3openssl
-file path=usr/share/man/man3openssl/ASN1_STRING_new.3openssl
-file path=usr/share/man/man3openssl/ASN1_STRING_print_ex.3openssl
-link path=usr/share/man/man3openssl/ASN1_STRING_print_ex_fp.3openssl \
-    target=ASN1_STRING_print_ex.3openssl
-link path=usr/share/man/man3openssl/ASN1_STRING_set.3openssl \
-    target=ASN1_STRING_length.3openssl
-link path=usr/share/man/man3openssl/ASN1_STRING_type.3openssl \
-    target=ASN1_STRING_length.3openssl
-link path=usr/share/man/man3openssl/ASN1_STRING_type_new.3openssl \
-    target=ASN1_STRING_new.3openssl
-file path=usr/share/man/man3openssl/ASN1_generate_nconf.3openssl
-link path=usr/share/man/man3openssl/ASN1_generate_v3.3openssl \
-    target=ASN1_generate_nconf.3openssl
-link path=usr/share/man/man3openssl/BF_cbc_encrypt.3openssl \
-    target=blowfish.3openssl
-link path=usr/share/man/man3openssl/BF_cfb64_encrypt.3openssl \
-    target=blowfish.3openssl
-link path=usr/share/man/man3openssl/BF_decrypt.3openssl target=blowfish.3openssl
-link path=usr/share/man/man3openssl/BF_ecb_encrypt.3openssl \
-    target=blowfish.3openssl
-link path=usr/share/man/man3openssl/BF_encrypt.3openssl target=blowfish.3openssl
-link path=usr/share/man/man3openssl/BF_ofb64_encrypt.3openssl \
-    target=blowfish.3openssl
-link path=usr/share/man/man3openssl/BF_options.3openssl target=blowfish.3openssl
-link path=usr/share/man/man3openssl/BF_set_key.3openssl target=blowfish.3openssl
-link path=usr/share/man/man3openssl/BIO_append_filename.3openssl \
-    target=BIO_s_file.3openssl
-link path=usr/share/man/man3openssl/BIO_callback_ctrl.3openssl \
-    target=BIO_ctrl.3openssl
-file path=usr/share/man/man3openssl/BIO_ctrl.3openssl
-link path=usr/share/man/man3openssl/BIO_ctrl_get_read_request.3openssl \
-    target=BIO_s_bio.3openssl
-link path=usr/share/man/man3openssl/BIO_ctrl_get_write_guarantee.3openssl \
-    target=BIO_s_bio.3openssl
-link path=usr/share/man/man3openssl/BIO_ctrl_pending.3openssl \
-    target=BIO_ctrl.3openssl
-link path=usr/share/man/man3openssl/BIO_ctrl_reset_read_request.3openssl \
-    target=BIO_s_bio.3openssl
-link path=usr/share/man/man3openssl/BIO_ctrl_wpending.3openssl \
-    target=BIO_ctrl.3openssl
-link path=usr/share/man/man3openssl/BIO_debug_callback.3openssl \
-    target=BIO_set_callback.3openssl
-link path=usr/share/man/man3openssl/BIO_destroy_bio_pair.3openssl \
-    target=BIO_s_bio.3openssl
-link path=usr/share/man/man3openssl/BIO_do_accept.3openssl \
-    target=BIO_s_accept.3openssl
-link path=usr/share/man/man3openssl/BIO_do_connect.3openssl \
-    target=BIO_s_connect.3openssl
-link path=usr/share/man/man3openssl/BIO_eof.3openssl target=BIO_ctrl.3openssl
-file path=usr/share/man/man3openssl/BIO_f_base64.3openssl
-file path=usr/share/man/man3openssl/BIO_f_buffer.3openssl
-file path=usr/share/man/man3openssl/BIO_f_cipher.3openssl
-file path=usr/share/man/man3openssl/BIO_f_md.3openssl
-file path=usr/share/man/man3openssl/BIO_f_null.3openssl
-file path=usr/share/man/man3openssl/BIO_f_ssl.3openssl
-file path=usr/share/man/man3openssl/BIO_find_type.3openssl
-link path=usr/share/man/man3openssl/BIO_flush.3openssl target=BIO_ctrl.3openssl
-link path=usr/share/man/man3openssl/BIO_free.3openssl target=BIO_new.3openssl
-link path=usr/share/man/man3openssl/BIO_free_all.3openssl \
-    target=BIO_new.3openssl
-link path=usr/share/man/man3openssl/BIO_get_accept_port.3openssl \
-    target=BIO_s_accept.3openssl
-link path=usr/share/man/man3openssl/BIO_get_bind_mode.3openssl \
-    target=BIO_s_accept.3openssl
-link path=usr/share/man/man3openssl/BIO_get_callback.3openssl \
-    target=BIO_set_callback.3openssl
-link path=usr/share/man/man3openssl/BIO_get_callback_arg.3openssl \
-    target=BIO_set_callback.3openssl
-link path=usr/share/man/man3openssl/BIO_get_cipher_ctx.3openssl \
-    target=BIO_f_cipher.3openssl
-link path=usr/share/man/man3openssl/BIO_get_cipher_status.3openssl \
-    target=BIO_f_cipher.3openssl
-link path=usr/share/man/man3openssl/BIO_get_close.3openssl \
-    target=BIO_ctrl.3openssl
-link path=usr/share/man/man3openssl/BIO_get_conn_hostname.3openssl \
-    target=BIO_s_connect.3openssl
-link path=usr/share/man/man3openssl/BIO_get_conn_int_port.3openssl \
-    target=BIO_s_connect.3openssl
-link path=usr/share/man/man3openssl/BIO_get_conn_ip.3openssl \
-    target=BIO_s_connect.3openssl
-link path=usr/share/man/man3openssl/BIO_get_conn_port.3openssl \
-    target=BIO_s_connect.3openssl
-link path=usr/share/man/man3openssl/BIO_get_fd.3openssl target=BIO_s_fd.3openssl
-link path=usr/share/man/man3openssl/BIO_get_fp.3openssl \
-    target=BIO_s_file.3openssl
-link path=usr/share/man/man3openssl/BIO_get_info_callback.3openssl \
-    target=BIO_ctrl.3openssl
-link path=usr/share/man/man3openssl/BIO_get_md.3openssl target=BIO_f_md.3openssl
-link path=usr/share/man/man3openssl/BIO_get_md_ctx.3openssl \
-    target=BIO_f_md.3openssl
-link path=usr/share/man/man3openssl/BIO_get_mem_data.3openssl \
-    target=BIO_s_mem.3openssl
-link path=usr/share/man/man3openssl/BIO_get_mem_ptr.3openssl \
-    target=BIO_s_mem.3openssl
-link path=usr/share/man/man3openssl/BIO_get_num_renegotiates.3openssl \
-    target=BIO_f_ssl.3openssl
-link path=usr/share/man/man3openssl/BIO_get_read_request.3openssl \
-    target=BIO_s_bio.3openssl
-link path=usr/share/man/man3openssl/BIO_get_retry_BIO.3openssl \
-    target=BIO_should_retry.3openssl
-link path=usr/share/man/man3openssl/BIO_get_retry_reason.3openssl \
-    target=BIO_should_retry.3openssl
-link path=usr/share/man/man3openssl/BIO_get_ssl.3openssl \
-    target=BIO_f_ssl.3openssl
-link path=usr/share/man/man3openssl/BIO_get_write_buf_size.3openssl \
-    target=BIO_s_bio.3openssl
-link path=usr/share/man/man3openssl/BIO_get_write_guarantee.3openssl \
-    target=BIO_s_bio.3openssl
-link path=usr/share/man/man3openssl/BIO_gets.3openssl target=BIO_read.3openssl
-link path=usr/share/man/man3openssl/BIO_int_ctrl.3openssl \
-    target=BIO_ctrl.3openssl
-link path=usr/share/man/man3openssl/BIO_make_bio_pair.3openssl \
-    target=BIO_s_bio.3openssl
-file path=usr/share/man/man3openssl/BIO_new.3openssl
-file path=usr/share/man/man3openssl/BIO_new_CMS.3openssl
-link path=usr/share/man/man3openssl/BIO_new_bio_pair.3openssl \
-    target=BIO_s_bio.3openssl
-link path=usr/share/man/man3openssl/BIO_new_buffer_ssl_connect.3openssl \
-    target=BIO_f_ssl.3openssl
-link path=usr/share/man/man3openssl/BIO_new_fd.3openssl target=BIO_s_fd.3openssl
-link path=usr/share/man/man3openssl/BIO_new_file.3openssl \
-    target=BIO_s_file.3openssl
-link path=usr/share/man/man3openssl/BIO_new_fp.3openssl \
-    target=BIO_s_file.3openssl
-link path=usr/share/man/man3openssl/BIO_new_mem_buf.3openssl \
-    target=BIO_s_mem.3openssl
-link path=usr/share/man/man3openssl/BIO_new_socket.3openssl \
-    target=BIO_s_socket.3openssl
-link path=usr/share/man/man3openssl/BIO_new_ssl.3openssl \
-    target=BIO_f_ssl.3openssl
-link path=usr/share/man/man3openssl/BIO_new_ssl_connect.3openssl \
-    target=BIO_f_ssl.3openssl
-link path=usr/share/man/man3openssl/BIO_next.3openssl \
-    target=BIO_find_type.3openssl
-link path=usr/share/man/man3openssl/BIO_pending.3openssl \
-    target=BIO_ctrl.3openssl
-link path=usr/share/man/man3openssl/BIO_pop.3openssl target=BIO_push.3openssl
-link path=usr/share/man/man3openssl/BIO_ptr_ctrl.3openssl \
-    target=BIO_ctrl.3openssl
-file path=usr/share/man/man3openssl/BIO_push.3openssl
-link path=usr/share/man/man3openssl/BIO_puts.3openssl target=BIO_read.3openssl
-file path=usr/share/man/man3openssl/BIO_read.3openssl
-link path=usr/share/man/man3openssl/BIO_read_filename.3openssl \
-    target=BIO_s_file.3openssl
-link path=usr/share/man/man3openssl/BIO_reset.3openssl target=BIO_ctrl.3openssl
-link path=usr/share/man/man3openssl/BIO_retry_type.3openssl \
-    target=BIO_should_retry.3openssl
-link path=usr/share/man/man3openssl/BIO_rw_filename.3openssl \
-    target=BIO_s_file.3openssl
-file path=usr/share/man/man3openssl/BIO_s_accept.3openssl
-file path=usr/share/man/man3openssl/BIO_s_bio.3openssl
-file path=usr/share/man/man3openssl/BIO_s_connect.3openssl
-file path=usr/share/man/man3openssl/BIO_s_fd.3openssl
-file path=usr/share/man/man3openssl/BIO_s_file.3openssl
-file path=usr/share/man/man3openssl/BIO_s_mem.3openssl
-file path=usr/share/man/man3openssl/BIO_s_null.3openssl
-file path=usr/share/man/man3openssl/BIO_s_socket.3openssl
-link path=usr/share/man/man3openssl/BIO_seek.3openssl target=BIO_ctrl.3openssl
-link path=usr/share/man/man3openssl/BIO_set.3openssl target=BIO_new.3openssl
-link path=usr/share/man/man3openssl/BIO_set_accept_bios.3openssl \
-    target=BIO_s_accept.3openssl
-link path=usr/share/man/man3openssl/BIO_set_accept_port.3openssl \
-    target=BIO_s_accept.3openssl
-link path=usr/share/man/man3openssl/BIO_set_bind_mode.3openssl \
-    target=BIO_s_accept.3openssl
-file path=usr/share/man/man3openssl/BIO_set_callback.3openssl
-link path=usr/share/man/man3openssl/BIO_set_callback_arg.3openssl \
-    target=BIO_set_callback.3openssl
-link path=usr/share/man/man3openssl/BIO_set_cipher.3openssl \
-    target=BIO_f_cipher.3openssl
-link path=usr/share/man/man3openssl/BIO_set_close.3openssl \
-    target=BIO_ctrl.3openssl
-link path=usr/share/man/man3openssl/BIO_set_conn_hostname.3openssl \
-    target=BIO_s_connect.3openssl
-link path=usr/share/man/man3openssl/BIO_set_conn_int_port.3openssl \
-    target=BIO_s_connect.3openssl
-link path=usr/share/man/man3openssl/BIO_set_conn_ip.3openssl \
-    target=BIO_s_connect.3openssl
-link path=usr/share/man/man3openssl/BIO_set_conn_port.3openssl \
-    target=BIO_s_connect.3openssl
-link path=usr/share/man/man3openssl/BIO_set_fd.3openssl target=BIO_s_fd.3openssl
-link path=usr/share/man/man3openssl/BIO_set_fp.3openssl \
-    target=BIO_s_file.3openssl
-link path=usr/share/man/man3openssl/BIO_set_info_callback.3openssl \
-    target=BIO_ctrl.3openssl
-link path=usr/share/man/man3openssl/BIO_set_md.3openssl target=BIO_f_md.3openssl
-link path=usr/share/man/man3openssl/BIO_set_mem_buf.3openssl \
-    target=BIO_s_mem.3openssl
-link path=usr/share/man/man3openssl/BIO_set_mem_eof_return.3openssl \
-    target=BIO_s_mem.3openssl
-link path=usr/share/man/man3openssl/BIO_set_nbio.3openssl \
-    target=BIO_s_connect.3openssl
-link path=usr/share/man/man3openssl/BIO_set_nbio_accept.3openssl \
-    target=BIO_s_accept.3openssl
-link path=usr/share/man/man3openssl/BIO_set_ssl.3openssl \
-    target=BIO_f_ssl.3openssl
-link path=usr/share/man/man3openssl/BIO_set_ssl_mode.3openssl \
-    target=BIO_f_ssl.3openssl
-link path=usr/share/man/man3openssl/BIO_set_ssl_renegotiate_bytes.3openssl \
-    target=BIO_f_ssl.3openssl
-link path=usr/share/man/man3openssl/BIO_set_ssl_renegotiate_timeout.3openssl \
-    target=BIO_f_ssl.3openssl
-link path=usr/share/man/man3openssl/BIO_set_write_buf_size.3openssl \
-    target=BIO_s_bio.3openssl
-link path=usr/share/man/man3openssl/BIO_should_io_special.3openssl \
-    target=BIO_should_retry.3openssl
-link path=usr/share/man/man3openssl/BIO_should_read.3openssl \
-    target=BIO_should_retry.3openssl
-file path=usr/share/man/man3openssl/BIO_should_retry.3openssl
-link path=usr/share/man/man3openssl/BIO_should_write.3openssl \
-    target=BIO_should_retry.3openssl
-link path=usr/share/man/man3openssl/BIO_shutdown_wr.3openssl \
-    target=BIO_s_bio.3openssl
-link path=usr/share/man/man3openssl/BIO_ssl_copy_session_id.3openssl \
-    target=BIO_f_ssl.3openssl
-link path=usr/share/man/man3openssl/BIO_ssl_shutdown.3openssl \
-    target=BIO_f_ssl.3openssl
-link path=usr/share/man/man3openssl/BIO_tell.3openssl target=BIO_ctrl.3openssl
-link path=usr/share/man/man3openssl/BIO_vfree.3openssl target=BIO_new.3openssl
-link path=usr/share/man/man3openssl/BIO_wpending.3openssl \
-    target=BIO_ctrl.3openssl
-link path=usr/share/man/man3openssl/BIO_write.3openssl target=BIO_read.3openssl
-link path=usr/share/man/man3openssl/BIO_write_filename.3openssl \
-    target=BIO_s_file.3openssl
-link path=usr/share/man/man3openssl/BN_BLINDING_convert.3openssl \
-    target=BN_BLINDING_new.3openssl
-link path=usr/share/man/man3openssl/BN_BLINDING_convert_ex.3openssl \
-    target=BN_BLINDING_new.3openssl
-link path=usr/share/man/man3openssl/BN_BLINDING_create_param.3openssl \
-    target=BN_BLINDING_new.3openssl
-link path=usr/share/man/man3openssl/BN_BLINDING_free.3openssl \
-    target=BN_BLINDING_new.3openssl
-link path=usr/share/man/man3openssl/BN_BLINDING_get_flags.3openssl \
-    target=BN_BLINDING_new.3openssl
-link path=usr/share/man/man3openssl/BN_BLINDING_get_thread_id.3openssl \
-    target=BN_BLINDING_new.3openssl
-link path=usr/share/man/man3openssl/BN_BLINDING_invert.3openssl \
-    target=BN_BLINDING_new.3openssl
-link path=usr/share/man/man3openssl/BN_BLINDING_invert_ex.3openssl \
-    target=BN_BLINDING_new.3openssl
-file path=usr/share/man/man3openssl/BN_BLINDING_new.3openssl
-link path=usr/share/man/man3openssl/BN_BLINDING_set_flags.3openssl \
-    target=BN_BLINDING_new.3openssl
-link path=usr/share/man/man3openssl/BN_BLINDING_set_thread_id.3openssl \
-    target=BN_BLINDING_new.3openssl
-link path=usr/share/man/man3openssl/BN_BLINDING_update.3openssl \
-    target=BN_BLINDING_new.3openssl
-link path=usr/share/man/man3openssl/BN_CTX_end.3openssl \
-    target=BN_CTX_start.3openssl
-link path=usr/share/man/man3openssl/BN_CTX_free.3openssl \
-    target=BN_CTX_new.3openssl
-link path=usr/share/man/man3openssl/BN_CTX_get.3openssl \
-    target=BN_CTX_start.3openssl
-link path=usr/share/man/man3openssl/BN_CTX_init.3openssl \
-    target=BN_CTX_new.3openssl
-file path=usr/share/man/man3openssl/BN_CTX_new.3openssl
-file path=usr/share/man/man3openssl/BN_CTX_start.3openssl
-link path=usr/share/man/man3openssl/BN_MONT_CTX_copy.3openssl \
-    target=BN_mod_mul_montgomery.3openssl
-link path=usr/share/man/man3openssl/BN_MONT_CTX_free.3openssl \
-    target=BN_mod_mul_montgomery.3openssl
-link path=usr/share/man/man3openssl/BN_MONT_CTX_init.3openssl \
-    target=BN_mod_mul_montgomery.3openssl
-link path=usr/share/man/man3openssl/BN_MONT_CTX_new.3openssl \
-    target=BN_mod_mul_montgomery.3openssl
-link path=usr/share/man/man3openssl/BN_MONT_CTX_set.3openssl \
-    target=BN_mod_mul_montgomery.3openssl
-link path=usr/share/man/man3openssl/BN_RECP_CTX_free.3openssl \
-    target=BN_mod_mul_reciprocal.3openssl
-link path=usr/share/man/man3openssl/BN_RECP_CTX_init.3openssl \
-    target=BN_mod_mul_reciprocal.3openssl
-link path=usr/share/man/man3openssl/BN_RECP_CTX_new.3openssl \
-    target=BN_mod_mul_reciprocal.3openssl
-link path=usr/share/man/man3openssl/BN_RECP_CTX_set.3openssl \
-    target=BN_mod_mul_reciprocal.3openssl
-file path=usr/share/man/man3openssl/BN_add.3openssl
-file path=usr/share/man/man3openssl/BN_add_word.3openssl
-link path=usr/share/man/man3openssl/BN_bin2bn.3openssl target=BN_bn2bin.3openssl
-file path=usr/share/man/man3openssl/BN_bn2bin.3openssl
-link path=usr/share/man/man3openssl/BN_bn2dec.3openssl target=BN_bn2bin.3openssl
-link path=usr/share/man/man3openssl/BN_bn2hex.3openssl target=BN_bn2bin.3openssl
-link path=usr/share/man/man3openssl/BN_bn2mpi.3openssl target=BN_bn2bin.3openssl
-link path=usr/share/man/man3openssl/BN_clear.3openssl target=BN_new.3openssl
-link path=usr/share/man/man3openssl/BN_clear_bit.3openssl \
-    target=BN_set_bit.3openssl
-link path=usr/share/man/man3openssl/BN_clear_free.3openssl \
-    target=BN_new.3openssl
-file path=usr/share/man/man3openssl/BN_cmp.3openssl
-file path=usr/share/man/man3openssl/BN_copy.3openssl
-link path=usr/share/man/man3openssl/BN_dec2bn.3openssl target=BN_bn2bin.3openssl
-link path=usr/share/man/man3openssl/BN_div.3openssl target=BN_add.3openssl
-link path=usr/share/man/man3openssl/BN_div_recp.3openssl \
-    target=BN_mod_mul_reciprocal.3openssl
-link path=usr/share/man/man3openssl/BN_div_word.3openssl \
-    target=BN_add_word.3openssl
-link path=usr/share/man/man3openssl/BN_dup.3openssl target=BN_copy.3openssl
-link path=usr/share/man/man3openssl/BN_exp.3openssl target=BN_add.3openssl
-link path=usr/share/man/man3openssl/BN_free.3openssl target=BN_new.3openssl
-link path=usr/share/man/man3openssl/BN_from_montgomery.3openssl \
-    target=BN_mod_mul_montgomery.3openssl
-link path=usr/share/man/man3openssl/BN_gcd.3openssl target=BN_add.3openssl
-file path=usr/share/man/man3openssl/BN_generate_prime.3openssl
-link path=usr/share/man/man3openssl/BN_get_word.3openssl target=BN_zero.3openssl
-link path=usr/share/man/man3openssl/BN_hex2bn.3openssl target=BN_bn2bin.3openssl
-link path=usr/share/man/man3openssl/BN_init.3openssl target=BN_new.3openssl
-link path=usr/share/man/man3openssl/BN_is_bit_set.3openssl \
-    target=BN_set_bit.3openssl
-link path=usr/share/man/man3openssl/BN_is_odd.3openssl target=BN_cmp.3openssl
-link path=usr/share/man/man3openssl/BN_is_one.3openssl target=BN_cmp.3openssl
-link path=usr/share/man/man3openssl/BN_is_prime.3openssl \
-    target=BN_generate_prime.3openssl
-link path=usr/share/man/man3openssl/BN_is_prime_fasttest.3openssl \
-    target=BN_generate_prime.3openssl
-link path=usr/share/man/man3openssl/BN_is_word.3openssl target=BN_cmp.3openssl
-link path=usr/share/man/man3openssl/BN_is_zero.3openssl target=BN_cmp.3openssl
-link path=usr/share/man/man3openssl/BN_lshift.3openssl \
-    target=BN_set_bit.3openssl
-link path=usr/share/man/man3openssl/BN_lshift1.3openssl \
-    target=BN_set_bit.3openssl
-link path=usr/share/man/man3openssl/BN_mask_bits.3openssl \
-    target=BN_set_bit.3openssl
-link path=usr/share/man/man3openssl/BN_mod.3openssl target=BN_add.3openssl
-link path=usr/share/man/man3openssl/BN_mod_add.3openssl target=BN_add.3openssl
-link path=usr/share/man/man3openssl/BN_mod_exp.3openssl target=BN_add.3openssl
-file path=usr/share/man/man3openssl/BN_mod_inverse.3openssl
-link path=usr/share/man/man3openssl/BN_mod_mul.3openssl target=BN_add.3openssl
-file path=usr/share/man/man3openssl/BN_mod_mul_montgomery.3openssl
-file path=usr/share/man/man3openssl/BN_mod_mul_reciprocal.3openssl
-link path=usr/share/man/man3openssl/BN_mod_sqr.3openssl target=BN_add.3openssl
-link path=usr/share/man/man3openssl/BN_mod_sub.3openssl target=BN_add.3openssl
-link path=usr/share/man/man3openssl/BN_mod_word.3openssl \
-    target=BN_add_word.3openssl
-link path=usr/share/man/man3openssl/BN_mpi2bn.3openssl target=BN_bn2bin.3openssl
-link path=usr/share/man/man3openssl/BN_mul.3openssl target=BN_add.3openssl
-link path=usr/share/man/man3openssl/BN_mul_word.3openssl \
-    target=BN_add_word.3openssl
-file path=usr/share/man/man3openssl/BN_new.3openssl
-link path=usr/share/man/man3openssl/BN_nnmod.3openssl target=BN_add.3openssl
-link path=usr/share/man/man3openssl/BN_num_bits.3openssl \
-    target=BN_num_bytes.3openssl
-link path=usr/share/man/man3openssl/BN_num_bits_word.3openssl \
-    target=BN_num_bytes.3openssl
-file path=usr/share/man/man3openssl/BN_num_bytes.3openssl
-link path=usr/share/man/man3openssl/BN_one.3openssl target=BN_zero.3openssl
-link path=usr/share/man/man3openssl/BN_print.3openssl target=BN_bn2bin.3openssl
-link path=usr/share/man/man3openssl/BN_print_fp.3openssl \
-    target=BN_bn2bin.3openssl
-link path=usr/share/man/man3openssl/BN_pseudo_rand.3openssl \
-    target=BN_rand.3openssl
-file path=usr/share/man/man3openssl/BN_rand.3openssl
-link path=usr/share/man/man3openssl/BN_rshift.3openssl \
-    target=BN_set_bit.3openssl
-link path=usr/share/man/man3openssl/BN_rshift1.3openssl \
-    target=BN_set_bit.3openssl
-file path=usr/share/man/man3openssl/BN_set_bit.3openssl
-link path=usr/share/man/man3openssl/BN_set_word.3openssl target=BN_zero.3openssl
-link path=usr/share/man/man3openssl/BN_sqr.3openssl target=BN_add.3openssl
-link path=usr/share/man/man3openssl/BN_sub.3openssl target=BN_add.3openssl
-link path=usr/share/man/man3openssl/BN_sub_word.3openssl \
-    target=BN_add_word.3openssl
-file path=usr/share/man/man3openssl/BN_swap.3openssl
-link path=usr/share/man/man3openssl/BN_to_montgomery.3openssl \
-    target=BN_mod_mul_montgomery.3openssl
-link path=usr/share/man/man3openssl/BN_ucmp.3openssl target=BN_cmp.3openssl
-link path=usr/share/man/man3openssl/BN_value_one.3openssl \
-    target=BN_zero.3openssl
-file path=usr/share/man/man3openssl/BN_zero.3openssl
-link path=usr/share/man/man3openssl/BUF_MEM_free.3openssl target=buffer.3openssl
-link path=usr/share/man/man3openssl/BUF_MEM_grow.3openssl target=buffer.3openssl
-link path=usr/share/man/man3openssl/BUF_MEM_new.3openssl target=buffer.3openssl
-link path=usr/share/man/man3openssl/BUF_strdup.3openssl target=buffer.3openssl
-link path=usr/share/man/man3openssl/CMS_ReceiptRequest_create0.3openssl \
-    target=CMS_get1_ReceiptRequest.3openssl
-link path=usr/share/man/man3openssl/CMS_ReceiptRequest_get0_values.3openssl \
-    target=CMS_get1_ReceiptRequest.3openssl
-link path=usr/share/man/man3openssl/CMS_RecipientInfo_decrypt.3openssl \
-    target=CMS_get0_RecipientInfos.3openssl
-link path=usr/share/man/man3openssl/CMS_RecipientInfo_kekri_get0_id.3openssl \
-    target=CMS_get0_RecipientInfos.3openssl
-link path=usr/share/man/man3openssl/CMS_RecipientInfo_kekri_id_cmp.3openssl \
-    target=CMS_get0_RecipientInfos.3openssl
-link path=usr/share/man/man3openssl/CMS_RecipientInfo_ktri_cert_cmp.3openssl \
-    target=CMS_get0_RecipientInfos.3openssl
-link \
-    path=usr/share/man/man3openssl/CMS_RecipientInfo_ktri_get0_signer_id.3openssl \
-    target=CMS_get0_RecipientInfos.3openssl
-link path=usr/share/man/man3openssl/CMS_RecipientInfo_set0_key.3openssl \
-    target=CMS_get0_RecipientInfos.3openssl
-link path=usr/share/man/man3openssl/CMS_RecipientInfo_set0_pkey.3openssl \
-    target=CMS_get0_RecipientInfos.3openssl
-link path=usr/share/man/man3openssl/CMS_RecipientInfo_type.3openssl \
-    target=CMS_get0_RecipientInfos.3openssl
-link path=usr/share/man/man3openssl/CMS_SignerInfo_cert_cmp.3openssl \
-    target=CMS_get0_SignerInfos.3openssl
-link path=usr/share/man/man3openssl/CMS_SignerInfo_get0_signer_id.3openssl \
-    target=CMS_get0_SignerInfos.3openssl
-link path=usr/share/man/man3openssl/CMS_SignerInfo_sign.3openssl \
-    target=CMS_add1_signer.3openssl
-file path=usr/share/man/man3openssl/CMS_add0_cert.3openssl
-link path=usr/share/man/man3openssl/CMS_add0_crl.3openssl \
-    target=CMS_add0_cert.3openssl
-link path=usr/share/man/man3openssl/CMS_add0_recipient_key.3openssl \
-    target=CMS_add1_recipient_cert.3openssl
-link path=usr/share/man/man3openssl/CMS_add1_ReceiptRequest.3openssl \
-    target=CMS_get1_ReceiptRequest.3openssl
-link path=usr/share/man/man3openssl/CMS_add1_cert.3openssl \
-    target=CMS_add0_cert.3openssl
-file path=usr/share/man/man3openssl/CMS_add1_recipient_cert.3openssl
-file path=usr/share/man/man3openssl/CMS_add1_signer.3openssl
-file path=usr/share/man/man3openssl/CMS_compress.3openssl
-file path=usr/share/man/man3openssl/CMS_decrypt.3openssl
-file path=usr/share/man/man3openssl/CMS_encrypt.3openssl
-file path=usr/share/man/man3openssl/CMS_final.3openssl
-file path=usr/share/man/man3openssl/CMS_get0_RecipientInfos.3openssl
-file path=usr/share/man/man3openssl/CMS_get0_SignerInfos.3openssl
-link path=usr/share/man/man3openssl/CMS_get0_eContentType.3openssl \
-    target=CMS_get0_type.3openssl
-file path=usr/share/man/man3openssl/CMS_get0_type.3openssl
-file path=usr/share/man/man3openssl/CMS_get1_ReceiptRequest.3openssl
-link path=usr/share/man/man3openssl/CMS_get1_certs.3openssl \
-    target=CMS_add0_cert.3openssl
-link path=usr/share/man/man3openssl/CMS_get1_crls.3openssl \
-    target=CMS_add0_cert.3openssl
-link path=usr/share/man/man3openssl/CMS_set1_eContentType.3openssl \
-    target=CMS_get0_type.3openssl
-link path=usr/share/man/man3openssl/CMS_set1_signer_certs.3openssl \
-    target=CMS_get0_SignerInfos.3openssl
-file path=usr/share/man/man3openssl/CMS_sign.3openssl
-file path=usr/share/man/man3openssl/CMS_sign_receipt.3openssl
-file path=usr/share/man/man3openssl/CMS_uncompress.3openssl
-file path=usr/share/man/man3openssl/CMS_verify.3openssl
-file path=usr/share/man/man3openssl/CMS_verify_receipt.3openssl
-link path=usr/share/man/man3openssl/CONF_modules_finish.3openssl \
-    target=CONF_modules_free.3openssl
-file path=usr/share/man/man3openssl/CONF_modules_free.3openssl
-link path=usr/share/man/man3openssl/CONF_modules_load.3openssl \
-    target=CONF_modules_load_file.3openssl
-file path=usr/share/man/man3openssl/CONF_modules_load_file.3openssl
-link path=usr/share/man/man3openssl/CONF_modules_unload.3openssl \
-    target=CONF_modules_free.3openssl
-link path=usr/share/man/man3openssl/CRYPTO_THREADID_cmp.3openssl \
-    target=threads.3openssl
-link path=usr/share/man/man3openssl/CRYPTO_THREADID_cpy.3openssl \
-    target=threads.3openssl
-link path=usr/share/man/man3openssl/CRYPTO_THREADID_current.3openssl \
-    target=threads.3openssl
-link path=usr/share/man/man3openssl/CRYPTO_THREADID_get_callback.3openssl \
-    target=threads.3openssl
-link path=usr/share/man/man3openssl/CRYPTO_THREADID_hash.3openssl \
-    target=threads.3openssl
-link path=usr/share/man/man3openssl/CRYPTO_THREADID_set_callback.3openssl \
-    target=threads.3openssl
-link path=usr/share/man/man3openssl/CRYPTO_destroy_dynlockid.3openssl \
-    target=threads.3openssl
-link path=usr/share/man/man3openssl/CRYPTO_get_ex_data.3openssl \
-    target=CRYPTO_set_ex_data.3openssl
-link path=usr/share/man/man3openssl/CRYPTO_get_new_dynlockid.3openssl \
-    target=threads.3openssl
-link path=usr/share/man/man3openssl/CRYPTO_lock.3openssl target=threads.3openssl
-link path=usr/share/man/man3openssl/CRYPTO_num_locks.3openssl \
-    target=threads.3openssl
-link \
-    path=usr/share/man/man3openssl/CRYPTO_set_dynlock_create_callback.3openssl \
-    target=threads.3openssl
-link \
-    path=usr/share/man/man3openssl/CRYPTO_set_dynlock_destroy_callback.3openssl \
-    target=threads.3openssl
-link path=usr/share/man/man3openssl/CRYPTO_set_dynlock_lock_callback.3openssl \
-    target=threads.3openssl
-file path=usr/share/man/man3openssl/CRYPTO_set_ex_data.3openssl
-link path=usr/share/man/man3openssl/CRYPTO_set_locking_callback.3openssl \
-    target=threads.3openssl
-link path=usr/share/man/man3openssl/DES_cbc_cksum.3openssl target=des.3openssl
-link path=usr/share/man/man3openssl/DES_cfb64_encrypt.3openssl \
-    target=des.3openssl
-link path=usr/share/man/man3openssl/DES_cfb_encrypt.3openssl target=des.3openssl
-link path=usr/share/man/man3openssl/DES_crypt.3openssl target=des.3openssl
-link path=usr/share/man/man3openssl/DES_ecb2_encrypt.3openssl \
-    target=des.3openssl
-link path=usr/share/man/man3openssl/DES_ecb3_encrypt.3openssl \
-    target=des.3openssl
-link path=usr/share/man/man3openssl/DES_ecb_encrypt.3openssl target=des.3openssl
-link path=usr/share/man/man3openssl/DES_ede2_cbc_encrypt.3openssl \
-    target=des.3openssl
-link path=usr/share/man/man3openssl/DES_ede2_cfb64_encrypt.3openssl \
-    target=des.3openssl
-link path=usr/share/man/man3openssl/DES_ede2_ofb64_encrypt.3openssl \
-    target=des.3openssl
-link path=usr/share/man/man3openssl/DES_ede3_cbc_encrypt.3openssl \
-    target=des.3openssl
-link path=usr/share/man/man3openssl/DES_ede3_cbcm_encrypt.3openssl \
-    target=des.3openssl
-link path=usr/share/man/man3openssl/DES_ede3_cfb64_encrypt.3openssl \
-    target=des.3openssl
-link path=usr/share/man/man3openssl/DES_ede3_ofb64_encrypt.3openssl \
-    target=des.3openssl
-link path=usr/share/man/man3openssl/DES_enc_read.3openssl target=des.3openssl
-link path=usr/share/man/man3openssl/DES_enc_write.3openssl target=des.3openssl
-link path=usr/share/man/man3openssl/DES_fcrypt.3openssl target=des.3openssl
-link path=usr/share/man/man3openssl/DES_is_weak_key.3openssl target=des.3openssl
-link path=usr/share/man/man3openssl/DES_key_sched.3openssl target=des.3openssl
-link path=usr/share/man/man3openssl/DES_ncbc_encrypt.3openssl \
-    target=des.3openssl
-link path=usr/share/man/man3openssl/DES_ofb64_encrypt.3openssl \
-    target=des.3openssl
-link path=usr/share/man/man3openssl/DES_ofb_encrypt.3openssl target=des.3openssl
-link path=usr/share/man/man3openssl/DES_pcbc_encrypt.3openssl \
-    target=des.3openssl
-link path=usr/share/man/man3openssl/DES_quad_cksum.3openssl target=des.3openssl
-link path=usr/share/man/man3openssl/DES_random_key.3openssl target=des.3openssl
-link path=usr/share/man/man3openssl/DES_set_key.3openssl target=des.3openssl
-link path=usr/share/man/man3openssl/DES_set_key_checked.3openssl \
-    target=des.3openssl
-link path=usr/share/man/man3openssl/DES_set_key_unchecked.3openssl \
-    target=des.3openssl
-link path=usr/share/man/man3openssl/DES_set_odd_parity.3openssl \
-    target=des.3openssl
-link path=usr/share/man/man3openssl/DES_string_to_2keys.3openssl \
-    target=des.3openssl
-link path=usr/share/man/man3openssl/DES_string_to_key.3openssl \
-    target=des.3openssl
-link path=usr/share/man/man3openssl/DES_xcbc_encrypt.3openssl \
-    target=des.3openssl
-link path=usr/share/man/man3openssl/DH_OpenSSL.3openssl \
-    target=DH_set_method.3openssl
-link path=usr/share/man/man3openssl/DH_check.3openssl \
-    target=DH_generate_parameters.3openssl
-link path=usr/share/man/man3openssl/DH_compute_key.3openssl \
-    target=DH_generate_key.3openssl
-link path=usr/share/man/man3openssl/DH_free.3openssl target=DH_new.3openssl
-file path=usr/share/man/man3openssl/DH_generate_key.3openssl
-file path=usr/share/man/man3openssl/DH_generate_parameters.3openssl
-link path=usr/share/man/man3openssl/DH_get_default_method.3openssl \
-    target=DH_set_method.3openssl
-link path=usr/share/man/man3openssl/DH_get_ex_data.3openssl \
-    target=DH_get_ex_new_index.3openssl
-file path=usr/share/man/man3openssl/DH_get_ex_new_index.3openssl
-file path=usr/share/man/man3openssl/DH_new.3openssl
-link path=usr/share/man/man3openssl/DH_new_method.3openssl \
-    target=DH_set_method.3openssl
-link path=usr/share/man/man3openssl/DH_set_default_method.3openssl \
-    target=DH_set_method.3openssl
-link path=usr/share/man/man3openssl/DH_set_ex_data.3openssl \
-    target=DH_get_ex_new_index.3openssl
-file path=usr/share/man/man3openssl/DH_set_method.3openssl
-file path=usr/share/man/man3openssl/DH_size.3openssl
-link path=usr/share/man/man3openssl/DHparams_print.3openssl \
-    target=RSA_print.3openssl
-link path=usr/share/man/man3openssl/DHparams_print_fp.3openssl \
-    target=RSA_print.3openssl
-link path=usr/share/man/man3openssl/DSA_OpenSSL.3openssl \
-    target=DSA_set_method.3openssl
-link path=usr/share/man/man3openssl/DSA_SIG_free.3openssl \
-    target=DSA_SIG_new.3openssl
-file path=usr/share/man/man3openssl/DSA_SIG_new.3openssl
-file path=usr/share/man/man3openssl/DSA_do_sign.3openssl
-link path=usr/share/man/man3openssl/DSA_do_verify.3openssl \
-    target=DSA_do_sign.3openssl
-file path=usr/share/man/man3openssl/DSA_dup_DH.3openssl
-link path=usr/share/man/man3openssl/DSA_free.3openssl target=DSA_new.3openssl
-file path=usr/share/man/man3openssl/DSA_generate_key.3openssl
-file path=usr/share/man/man3openssl/DSA_generate_parameters.3openssl
-link path=usr/share/man/man3openssl/DSA_get_default_method.3openssl \
-    target=DSA_set_method.3openssl
-link path=usr/share/man/man3openssl/DSA_get_ex_data.3openssl \
-    target=DSA_get_ex_new_index.3openssl
-file path=usr/share/man/man3openssl/DSA_get_ex_new_index.3openssl
-file path=usr/share/man/man3openssl/DSA_new.3openssl
-link path=usr/share/man/man3openssl/DSA_new_method.3openssl \
-    target=DSA_set_method.3openssl
-link path=usr/share/man/man3openssl/DSA_print.3openssl target=RSA_print.3openssl
-link path=usr/share/man/man3openssl/DSA_print_fp.3openssl \
-    target=RSA_print.3openssl
-link path=usr/share/man/man3openssl/DSA_set_default_method.3openssl \
-    target=DSA_set_method.3openssl
-link path=usr/share/man/man3openssl/DSA_set_ex_data.3openssl \
-    target=DSA_get_ex_new_index.3openssl
-file path=usr/share/man/man3openssl/DSA_set_method.3openssl
-file path=usr/share/man/man3openssl/DSA_sign.3openssl
-link path=usr/share/man/man3openssl/DSA_sign_setup.3openssl \
-    target=DSA_sign.3openssl
-file path=usr/share/man/man3openssl/DSA_size.3openssl
-link path=usr/share/man/man3openssl/DSA_verify.3openssl target=DSA_sign.3openssl
-link path=usr/share/man/man3openssl/DSAparams_print.3openssl \
-    target=RSA_print.3openssl
-link path=usr/share/man/man3openssl/DSAparams_print_fp.3openssl \
-    target=RSA_print.3openssl
-link path=usr/share/man/man3openssl/ERR_GET_FUNC.3openssl \
-    target=ERR_GET_LIB.3openssl
-file path=usr/share/man/man3openssl/ERR_GET_LIB.3openssl
-link path=usr/share/man/man3openssl/ERR_GET_REASON.3openssl \
-    target=ERR_GET_LIB.3openssl
-link path=usr/share/man/man3openssl/ERR_PACK.3openssl \
-    target=ERR_load_strings.3openssl
-link path=usr/share/man/man3openssl/ERR_add_error_data.3openssl \
-    target=ERR_put_error.3openssl
-file path=usr/share/man/man3openssl/ERR_clear_error.3openssl
-file path=usr/share/man/man3openssl/ERR_error_string.3openssl
-link path=usr/share/man/man3openssl/ERR_error_string_n.3openssl \
-    target=ERR_error_string.3openssl
-link path=usr/share/man/man3openssl/ERR_free_strings.3openssl \
-    target=ERR_load_crypto_strings.3openssl
-link path=usr/share/man/man3openssl/ERR_func_error_string.3openssl \
-    target=ERR_error_string.3openssl
-file path=usr/share/man/man3openssl/ERR_get_error.3openssl
-link path=usr/share/man/man3openssl/ERR_get_error_line.3openssl \
-    target=ERR_get_error.3openssl
-link path=usr/share/man/man3openssl/ERR_get_error_line_data.3openssl \
-    target=ERR_get_error.3openssl
-link path=usr/share/man/man3openssl/ERR_get_next_error_library.3openssl \
-    target=ERR_load_strings.3openssl
-link path=usr/share/man/man3openssl/ERR_lib_error_string.3openssl \
-    target=ERR_error_string.3openssl
-link path=usr/share/man/man3openssl/ERR_load_UI_strings.3openssl \
-    target=ui.3openssl
-file path=usr/share/man/man3openssl/ERR_load_crypto_strings.3openssl
-file path=usr/share/man/man3openssl/ERR_load_strings.3openssl
-link path=usr/share/man/man3openssl/ERR_peek_error.3openssl \
-    target=ERR_get_error.3openssl
-link path=usr/share/man/man3openssl/ERR_peek_error_line.3openssl \
-    target=ERR_get_error.3openssl
-link path=usr/share/man/man3openssl/ERR_peek_error_line_data.3openssl \
-    target=ERR_get_error.3openssl
-link path=usr/share/man/man3openssl/ERR_peek_last_error.3openssl \
-    target=ERR_get_error.3openssl
-link path=usr/share/man/man3openssl/ERR_peek_last_error_line.3openssl \
-    target=ERR_get_error.3openssl
-link path=usr/share/man/man3openssl/ERR_peek_last_error_line_data.3openssl \
-    target=ERR_get_error.3openssl
-link path=usr/share/man/man3openssl/ERR_pop_to_mark.3openssl \
-    target=ERR_set_mark.3openssl
-file path=usr/share/man/man3openssl/ERR_print_errors.3openssl
-link path=usr/share/man/man3openssl/ERR_print_errors_fp.3openssl \
-    target=ERR_print_errors.3openssl
-file path=usr/share/man/man3openssl/ERR_put_error.3openssl
-link path=usr/share/man/man3openssl/ERR_reason_error_string.3openssl \
-    target=ERR_error_string.3openssl
-file path=usr/share/man/man3openssl/ERR_remove_state.3openssl
-file path=usr/share/man/man3openssl/ERR_set_mark.3openssl
-file path=usr/share/man/man3openssl/EVP_BytesToKey.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_block_size.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_cipher.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_cleanup.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_ctrl.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_flags.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_get_app_data.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_init.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_iv_length.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_key_length.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_mode.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_nid.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_set_app_data.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_set_key_length.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_set_padding.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_type.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_asn1_to_param.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_block_size.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_flags.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_iv_length.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_key_length.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_mode.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_nid.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_param_to_asn1.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CIPHER_type.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CipherFinal.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CipherFinal_ex.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CipherInit.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CipherInit_ex.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_CipherUpdate.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_DecryptFinal.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_DecryptFinal_ex.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_DecryptInit.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_DecryptInit_ex.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_DecryptUpdate.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_DigestFinal_ex.3openssl \
-    target=EVP_DigestInit.3openssl
-file path=usr/share/man/man3openssl/EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_DigestInit_ex.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_DigestSignFinal.3openssl \
-    target=EVP_DigestSignInit.3openssl
-file path=usr/share/man/man3openssl/EVP_DigestSignInit.3openssl
-link path=usr/share/man/man3openssl/EVP_DigestSignUpdate.3openssl \
-    target=EVP_DigestSignInit.3openssl
-link path=usr/share/man/man3openssl/EVP_DigestUpdate.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_DigestVerifyFinal.3openssl \
-    target=EVP_DigestVerifyInit.3openssl
-file path=usr/share/man/man3openssl/EVP_DigestVerifyInit.3openssl
-link path=usr/share/man/man3openssl/EVP_DigestVerifyUpdate.3openssl \
-    target=EVP_DigestVerifyInit.3openssl
-link path=usr/share/man/man3openssl/EVP_EncryptFinal.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_EncryptFinal_ex.3openssl \
-    target=EVP_EncryptInit.3openssl
-file path=usr/share/man/man3openssl/EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_EncryptInit_ex.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_EncryptUpdate.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_MAX_MD_SIZE.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_MD_CTX_block_size.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_MD_CTX_cleanup.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_MD_CTX_copy.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_MD_CTX_copy_ex.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_MD_CTX_create.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_MD_CTX_destroy.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_MD_CTX_init.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_MD_CTX_md.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_MD_CTX_size.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_MD_CTX_type.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_MD_block_size.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_MD_pkey_type.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_MD_size.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_MD_type.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_OpenFinal.3openssl \
-    target=EVP_OpenInit.3openssl
-file path=usr/share/man/man3openssl/EVP_OpenInit.3openssl
-link path=usr/share/man/man3openssl/EVP_OpenUpdate.3openssl \
-    target=EVP_OpenInit.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEVP_PKEY_CTX_set_app_data.3openssl \
-    target=EVP_PKEY_keygen.3openssl
-file path=usr/share/man/man3openssl/EVP_PKEY_CTX_ctrl.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_CTX_dup.3openssl \
-    target=EVP_PKEY_CTX_new.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_CTX_free.3openssl \
-    target=EVP_PKEY_CTX_new.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_CTX_get_app_data.3openssl \
-    target=EVP_PKEY_keygen.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_CTX_get_cb.3openssl \
-    target=EVP_PKEY_keygen.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_CTX_get_keygen_info.3openssl \
-    target=EVP_PKEY_keygen.3openssl
-file path=usr/share/man/man3openssl/EVP_PKEY_CTX_new.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_CTX_new_id.3openssl \
-    target=EVP_PKEY_CTX_new.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_CTX_set_cb.3openssl \
-    target=EVP_PKEY_keygen.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_assign_DH.3openssl \
-    target=EVP_PKEY_set1_RSA.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_assign_DSA.3openssl \
-    target=EVP_PKEY_set1_RSA.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_assign_EC_KEY.3openssl \
-    target=EVP_PKEY_set1_RSA.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_assign_RSA.3openssl \
-    target=EVP_PKEY_set1_RSA.3openssl
-file path=usr/share/man/man3openssl/EVP_PKEY_cmp.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_cmp_parameters.3openssl \
-    target=EVP_PKEY_cmp.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_copy_parameters.3openssl \
-    target=EVP_PKEY_cmp.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_ctrl.3openssl \
-    target=EVP_PKEY_CTX_ctrl.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_ctrl_str.3openssl \
-    target=EVP_PKEY_CTX_ctrl.3openssl
-file path=usr/share/man/man3openssl/EVP_PKEY_decrypt.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_decrypt_init.3openssl \
-    target=EVP_PKEY_decrypt.3openssl
-file path=usr/share/man/man3openssl/EVP_PKEY_derive.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_derive_init.3openssl \
-    target=EVP_PKEY_derive.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_derive_set_peer.3openssl \
-    target=EVP_PKEY_derive.3openssl
-file path=usr/share/man/man3openssl/EVP_PKEY_encrypt.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_encrypt_init.3openssl \
-    target=EVP_PKEY_encrypt.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_free.3openssl \
-    target=EVP_PKEY_new.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_get1_DH.3openssl \
-    target=EVP_PKEY_set1_RSA.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_get1_DSA.3openssl \
-    target=EVP_PKEY_set1_RSA.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_get1_EC_KEY.3openssl \
-    target=EVP_PKEY_set1_RSA.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_get1_RSA.3openssl \
-    target=EVP_PKEY_set1_RSA.3openssl
-file path=usr/share/man/man3openssl/EVP_PKEY_get_default_digest.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_get_default_digest_nid.3openssl \
-    target=EVP_PKEY_get_default_digest.3openssl
-file path=usr/share/man/man3openssl/EVP_PKEY_keygen.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_keygen_init.3openssl \
-    target=EVP_PKEY_keygen.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_missing_parameters.3openssl \
-    target=EVP_PKEY_cmp.3openssl
-file path=usr/share/man/man3openssl/EVP_PKEY_new.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_paramgen.3openssl \
-    target=EVP_PKEY_keygen.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_paramgen_init.3openssl \
-    target=EVP_PKEY_keygen.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_print_params.3openssl \
-    target=EVP_PKEY_print_private.3openssl
-file path=usr/share/man/man3openssl/EVP_PKEY_print_private.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_print_public.3openssl \
-    target=EVP_PKEY_print_private.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_set1_DH.3openssl \
-    target=EVP_PKEY_set1_RSA.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_set1_DSA.3openssl \
-    target=EVP_PKEY_set1_RSA.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_set1_EC_KEY.3openssl \
-    target=EVP_PKEY_set1_RSA.3openssl
-file path=usr/share/man/man3openssl/EVP_PKEY_set1_RSA.3openssl
-file path=usr/share/man/man3openssl/EVP_PKEY_sign.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_sign_init.3openssl \
-    target=EVP_PKEY_sign.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_type.3openssl \
-    target=EVP_PKEY_set1_RSA.3openssl
-file path=usr/share/man/man3openssl/EVP_PKEY_verify.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_verify_init.3openssl \
-    target=EVP_PKEY_verify.3openssl
-file path=usr/share/man/man3openssl/EVP_PKEY_verify_recover.3openssl
-link path=usr/share/man/man3openssl/EVP_PKEY_verify_recover_init.3openssl \
-    target=EVP_PKEY_verify_recover.3openssl
-link path=usr/share/man/man3openssl/EVP_SealFinal.3openssl \
-    target=EVP_SealInit.3openssl
-file path=usr/share/man/man3openssl/EVP_SealInit.3openssl
-link path=usr/share/man/man3openssl/EVP_SealUpdate.3openssl \
-    target=EVP_SealInit.3openssl
-link path=usr/share/man/man3openssl/EVP_SignFinal.3openssl \
-    target=EVP_SignInit.3openssl
-file path=usr/share/man/man3openssl/EVP_SignInit.3openssl
-link path=usr/share/man/man3openssl/EVP_SignUpdate.3openssl \
-    target=EVP_SignInit.3openssl
-link path=usr/share/man/man3openssl/EVP_VerifyFinal.3openssl \
-    target=EVP_VerifyInit.3openssl
-file path=usr/share/man/man3openssl/EVP_VerifyInit.3openssl
-link path=usr/share/man/man3openssl/EVP_VerifyUpdate.3openssl \
-    target=EVP_VerifyInit.3openssl
-link path=usr/share/man/man3openssl/EVP_dss.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_dss1.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_get_cipherbyname.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_get_cipherbynid.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_get_cipherbyobj.3openssl \
-    target=EVP_EncryptInit.3openssl
-link path=usr/share/man/man3openssl/EVP_get_digestbyname.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_get_digestbynid.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_get_digestbyobj.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_md2.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_md5.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_md_null.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_mdc2.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_ripemd160.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_sha.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/EVP_sha1.3openssl \
-    target=EVP_DigestInit.3openssl
-link path=usr/share/man/man3openssl/HMAC.3openssl target=hmac.3openssl
-link path=usr/share/man/man3openssl/HMAC_CTX_cleanup.3openssl \
-    target=hmac.3openssl
-link path=usr/share/man/man3openssl/HMAC_CTX_init.3openssl target=hmac.3openssl
-link path=usr/share/man/man3openssl/HMAC_Final.3openssl target=hmac.3openssl
-link path=usr/share/man/man3openssl/HMAC_Init.3openssl target=hmac.3openssl
-link path=usr/share/man/man3openssl/HMAC_Init_ex.3openssl target=hmac.3openssl
-link path=usr/share/man/man3openssl/HMAC_Update.3openssl target=hmac.3openssl
-link path=usr/share/man/man3openssl/HMAC_cleanup.3openssl target=hmac.3openssl
-link path=usr/share/man/man3openssl/MD2.3openssl target=md5.3openssl
-link path=usr/share/man/man3openssl/MD2_Final.3openssl target=md5.3openssl
-link path=usr/share/man/man3openssl/MD2_Init.3openssl target=md5.3openssl
-link path=usr/share/man/man3openssl/MD2_Update.3openssl target=md5.3openssl
-link path=usr/share/man/man3openssl/MD4.3openssl target=md5.3openssl
-link path=usr/share/man/man3openssl/MD4_Final.3openssl target=md5.3openssl
-link path=usr/share/man/man3openssl/MD4_Init.3openssl target=md5.3openssl
-link path=usr/share/man/man3openssl/MD4_Update.3openssl target=md5.3openssl
-link path=usr/share/man/man3openssl/MD5.3openssl target=md5.3openssl
-link path=usr/share/man/man3openssl/MD5_Final.3openssl target=md5.3openssl
-link path=usr/share/man/man3openssl/MD5_Init.3openssl target=md5.3openssl
-link path=usr/share/man/man3openssl/MD5_Update.3openssl target=md5.3openssl
-link path=usr/share/man/man3openssl/MDC2.3openssl target=mdc2.3openssl
-link path=usr/share/man/man3openssl/MDC2_Final.3openssl target=mdc2.3openssl
-link path=usr/share/man/man3openssl/MDC2_Init.3openssl target=mdc2.3openssl
-link path=usr/share/man/man3openssl/MDC2_Update.3openssl target=mdc2.3openssl
-link path=usr/share/man/man3openssl/OBJ_cleanup.3openssl \
-    target=OBJ_nid2obj.3openssl
-link path=usr/share/man/man3openssl/OBJ_cmp.3openssl target=OBJ_nid2obj.3openssl
-link path=usr/share/man/man3openssl/OBJ_create.3openssl \
-    target=OBJ_nid2obj.3openssl
-link path=usr/share/man/man3openssl/OBJ_dup.3openssl target=OBJ_nid2obj.3openssl
-link path=usr/share/man/man3openssl/OBJ_ln2nid.3openssl \
-    target=OBJ_nid2obj.3openssl
-link path=usr/share/man/man3openssl/OBJ_nid2ln.3openssl \
-    target=OBJ_nid2obj.3openssl
-file path=usr/share/man/man3openssl/OBJ_nid2obj.3openssl
-link path=usr/share/man/man3openssl/OBJ_nid2sn.3openssl \
-    target=OBJ_nid2obj.3openssl
-link path=usr/share/man/man3openssl/OBJ_obj2nid.3openssl \
-    target=OBJ_nid2obj.3openssl
-link path=usr/share/man/man3openssl/OBJ_obj2txt.3openssl \
-    target=OBJ_nid2obj.3openssl
-link path=usr/share/man/man3openssl/OBJ_sn2nid.3openssl \
-    target=OBJ_nid2obj.3openssl
-link path=usr/share/man/man3openssl/OBJ_txt2nid.3openssl \
-    target=OBJ_nid2obj.3openssl
-link path=usr/share/man/man3openssl/OBJ_txt2obj.3openssl \
-    target=OBJ_nid2obj.3openssl
-file path=usr/share/man/man3openssl/OPENSSL_Applink.3openssl
-file path=usr/share/man/man3openssl/OPENSSL_VERSION_NUMBER.3openssl
-file path=usr/share/man/man3openssl/OPENSSL_config.3openssl
-file path=usr/share/man/man3openssl/OPENSSL_ia32cap.3openssl
-file path=usr/share/man/man3openssl/OPENSSL_load_builtin_modules.3openssl
-link path=usr/share/man/man3openssl/OPENSSL_no_config.3openssl \
-    target=OPENSSL_config.3openssl
-file path=usr/share/man/man3openssl/OpenSSL_add_all_algorithms.3openssl
-link path=usr/share/man/man3openssl/OpenSSL_add_all_ciphers.3openssl \
-    target=OpenSSL_add_all_algorithms.3openssl
-link path=usr/share/man/man3openssl/OpenSSL_add_all_digests.3openssl \
-    target=OpenSSL_add_all_algorithms.3openssl
-link path=usr/share/man/man3openssl/OpenSSL_add_ssl_algorithms.3openssl \
-    target=SSL_library_init.3openssl
-link path=usr/share/man/man3openssl/PEM.3openssl target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_DHparams.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_DSAPrivateKey.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_DSA_PUBKEY.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_DSAparams.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_NETSCAPE_CERT_SEQUENCE.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_PKCS7.3openssl target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_PUBKEY.3openssl target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_PrivateKey.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_RSAPrivateKey.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_RSAPublicKey.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_RSA_PUBKEY.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_X509.3openssl target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_X509_AUX.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_X509_CRL.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_X509_REQ.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_bio_DHparams.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_bio_DSAPrivateKey.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_bio_DSA_PUBKEY.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_bio_DSAparams.3openssl \
-    target=pem.3openssl
-link \
-    path=usr/share/man/man3openssl/PEM_read_bio_NETSCAPE_CERT_SEQUENCE.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_bio_PKCS7.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_bio_PUBKEY.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_bio_PrivateKey.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_bio_RSAPrivateKey.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_bio_RSAPublicKey.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_bio_RSA_PUBKEY.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_bio_X509.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_bio_X509_AUX.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_bio_X509_CRL.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_read_bio_X509_REQ.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_DHparams.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_DSAPrivateKey.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_DSA_PUBKEY.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_DSAparams.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_NETSCAPE_CERT_SEQUENCE.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_PKCS7.3openssl target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_PKCS8PrivateKey.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_PKCS8PrivateKey_nid.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_PUBKEY.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_PrivateKey.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_RSAPrivateKey.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_RSAPublicKey.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_RSA_PUBKEY.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_X509.3openssl target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_X509_AUX.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_X509_CRL.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_X509_REQ.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_X509_REQ_NEW.3openssl \
-    target=pem.3openssl
-file path=usr/share/man/man3openssl/PEM_write_bio_CMS_stream.3openssl
-link path=usr/share/man/man3openssl/PEM_write_bio_DHparams.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_bio_DSAPrivateKey.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_bio_DSA_PUBKEY.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_bio_DSAparams.3openssl \
-    target=pem.3openssl
-link \
-    path=usr/share/man/man3openssl/PEM_write_bio_NETSCAPE_CERT_SEQUENCE.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_bio_PKCS7.3openssl \
-    target=pem.3openssl
-file path=usr/share/man/man3openssl/PEM_write_bio_PKCS7_stream.3openssl
-link path=usr/share/man/man3openssl/PEM_write_bio_PKCS8PrivateKey.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_bio_PKCS8PrivateKey_nid.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_bio_PUBKEY.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_bio_PrivateKey.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_bio_RSAPrivateKey.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_bio_RSAPublicKey.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_bio_RSA_PUBKEY.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_bio_X509.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_bio_X509_AUX.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_bio_X509_CRL.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_bio_X509_REQ.3openssl \
-    target=pem.3openssl
-link path=usr/share/man/man3openssl/PEM_write_bio_X509_REQ_NEW.3openssl \
-    target=pem.3openssl
-file path=usr/share/man/man3openssl/PKCS12_create.3openssl
-file path=usr/share/man/man3openssl/PKCS12_parse.3openssl
-file path=usr/share/man/man3openssl/PKCS7_decrypt.3openssl
-file path=usr/share/man/man3openssl/PKCS7_encrypt.3openssl
-file path=usr/share/man/man3openssl/PKCS7_sign.3openssl
-file path=usr/share/man/man3openssl/PKCS7_sign_add_signer.3openssl
-file path=usr/share/man/man3openssl/PKCS7_verify.3openssl
-link path=usr/share/man/man3openssl/RAND_SSLeay.3openssl \
-    target=RAND_set_rand_method.3openssl
-file path=usr/share/man/man3openssl/RAND_add.3openssl
-file path=usr/share/man/man3openssl/RAND_bytes.3openssl
-file path=usr/share/man/man3openssl/RAND_cleanup.3openssl
-file path=usr/share/man/man3openssl/RAND_egd.3openssl
-link path=usr/share/man/man3openssl/RAND_event.3openssl target=RAND_add.3openssl
-link path=usr/share/man/man3openssl/RAND_file_name.3openssl \
-    target=RAND_load_file.3openssl
-link path=usr/share/man/man3openssl/RAND_get_rand_method.3openssl \
-    target=RAND_set_rand_method.3openssl
-file path=usr/share/man/man3openssl/RAND_load_file.3openssl
-link path=usr/share/man/man3openssl/RAND_pseudo_bytes.3openssl \
-    target=RAND_bytes.3openssl
-link path=usr/share/man/man3openssl/RAND_screen.3openssl \
-    target=RAND_add.3openssl
-link path=usr/share/man/man3openssl/RAND_seed.3openssl target=RAND_add.3openssl
-file path=usr/share/man/man3openssl/RAND_set_rand_method.3openssl
-link path=usr/share/man/man3openssl/RAND_status.3openssl \
-    target=RAND_add.3openssl
-link path=usr/share/man/man3openssl/RAND_write_file.3openssl \
-    target=RAND_load_file.3openssl
-link path=usr/share/man/man3openssl/RC4.3openssl target=rc4.3openssl
-link path=usr/share/man/man3openssl/RC4_set_key.3openssl target=rc4.3openssl
-link path=usr/share/man/man3openssl/RIPEMD160.3openssl target=ripemd.3openssl
-link path=usr/share/man/man3openssl/RIPEMD160_Final.3openssl \
-    target=ripemd.3openssl
-link path=usr/share/man/man3openssl/RIPEMD160_Init.3openssl \
-    target=ripemd.3openssl
-link path=usr/share/man/man3openssl/RIPEMD160_Update.3openssl \
-    target=ripemd.3openssl
-link path=usr/share/man/man3openssl/RSA_PKCS1_SSLeay.3openssl \
-    target=RSA_set_method.3openssl
-link path=usr/share/man/man3openssl/RSA_blinding_off.3openssl \
-    target=RSA_blinding_on.3openssl
-file path=usr/share/man/man3openssl/RSA_blinding_on.3openssl
-file path=usr/share/man/man3openssl/RSA_check_key.3openssl
-link path=usr/share/man/man3openssl/RSA_flags.3openssl \
-    target=RSA_set_method.3openssl
-link path=usr/share/man/man3openssl/RSA_free.3openssl target=RSA_new.3openssl
-file path=usr/share/man/man3openssl/RSA_generate_key.3openssl
-link path=usr/share/man/man3openssl/RSA_get_default_method.3openssl \
-    target=RSA_set_method.3openssl
-link path=usr/share/man/man3openssl/RSA_get_ex_data.3openssl \
-    target=RSA_get_ex_new_index.3openssl
-file path=usr/share/man/man3openssl/RSA_get_ex_new_index.3openssl
-link path=usr/share/man/man3openssl/RSA_get_method.3openssl \
-    target=RSA_set_method.3openssl
-file path=usr/share/man/man3openssl/RSA_new.3openssl
-link path=usr/share/man/man3openssl/RSA_new_method.3openssl \
-    target=RSA_set_method.3openssl
-link path=usr/share/man/man3openssl/RSA_null_method.3openssl \
-    target=RSA_set_method.3openssl
-link path=usr/share/man/man3openssl/RSA_padding_add_PKCS1_OAEP.3openssl \
-    target=RSA_padding_add_PKCS1_type_1.3openssl
-file path=usr/share/man/man3openssl/RSA_padding_add_PKCS1_type_1.3openssl
-link path=usr/share/man/man3openssl/RSA_padding_add_PKCS1_type_2.3openssl \
-    target=RSA_padding_add_PKCS1_type_1.3openssl
-link path=usr/share/man/man3openssl/RSA_padding_add_SSLv23.3openssl \
-    target=RSA_padding_add_PKCS1_type_1.3openssl
-link path=usr/share/man/man3openssl/RSA_padding_add_none.3openssl \
-    target=RSA_padding_add_PKCS1_type_1.3openssl
-link path=usr/share/man/man3openssl/RSA_padding_check_PKCS1_OAEP.3openssl \
-    target=RSA_padding_add_PKCS1_type_1.3openssl
-link path=usr/share/man/man3openssl/RSA_padding_check_PKCS1_type_1.3openssl \
-    target=RSA_padding_add_PKCS1_type_1.3openssl
-link path=usr/share/man/man3openssl/RSA_padding_check_PKCS1_type_2.3openssl \
-    target=RSA_padding_add_PKCS1_type_1.3openssl
-link path=usr/share/man/man3openssl/RSA_padding_check_SSLv23.3openssl \
-    target=RSA_padding_add_PKCS1_type_1.3openssl
-link path=usr/share/man/man3openssl/RSA_padding_check_none.3openssl \
-    target=RSA_padding_add_PKCS1_type_1.3openssl
-file path=usr/share/man/man3openssl/RSA_print.3openssl
-link path=usr/share/man/man3openssl/RSA_print_fp.3openssl \
-    target=RSA_print.3openssl
-link path=usr/share/man/man3openssl/RSA_private_decrypt.3openssl \
-    target=RSA_public_encrypt.3openssl
-file path=usr/share/man/man3openssl/RSA_private_encrypt.3openssl
-link path=usr/share/man/man3openssl/RSA_public_decrypt.3openssl \
-    target=RSA_private_encrypt.3openssl
-file path=usr/share/man/man3openssl/RSA_public_encrypt.3openssl
-link path=usr/share/man/man3openssl/RSA_set_default_method.3openssl \
-    target=RSA_set_method.3openssl
-link path=usr/share/man/man3openssl/RSA_set_ex_data.3openssl \
-    target=RSA_get_ex_new_index.3openssl
-file path=usr/share/man/man3openssl/RSA_set_method.3openssl
-file path=usr/share/man/man3openssl/RSA_sign.3openssl
-file path=usr/share/man/man3openssl/RSA_sign_ASN1_OCTET_STRING.3openssl
-file path=usr/share/man/man3openssl/RSA_size.3openssl
-link path=usr/share/man/man3openssl/RSA_verify.3openssl target=RSA_sign.3openssl
-link path=usr/share/man/man3openssl/RSA_verify_ASN1_OCTET_STRING.3openssl \
-    target=RSA_sign_ASN1_OCTET_STRING.3openssl
-link path=usr/share/man/man3openssl/SHA1.3openssl target=sha.3openssl
-link path=usr/share/man/man3openssl/SHA1_Final.3openssl target=sha.3openssl
-link path=usr/share/man/man3openssl/SHA1_Init.3openssl target=sha.3openssl
-link path=usr/share/man/man3openssl/SHA1_Update.3openssl target=sha.3openssl
-file path=usr/share/man/man3openssl/SMIME_read_CMS.3openssl
-file path=usr/share/man/man3openssl/SMIME_read_PKCS7.3openssl
-file path=usr/share/man/man3openssl/SMIME_write_CMS.3openssl
-file path=usr/share/man/man3openssl/SMIME_write_PKCS7.3openssl
-link path=usr/share/man/man3openssl/SSL.3openssl target=ssl.3openssl
-link path=usr/share/man/man3openssl/SSL_CIPHER_description.3openssl \
-    target=SSL_CIPHER_get_name.3openssl
-link path=usr/share/man/man3openssl/SSL_CIPHER_get_bits.3openssl \
-    target=SSL_CIPHER_get_name.3openssl
-file path=usr/share/man/man3openssl/SSL_CIPHER_get_name.3openssl
-link path=usr/share/man/man3openssl/SSL_CIPHER_get_version.3openssl \
-    target=SSL_CIPHER_get_name.3openssl
-file path=usr/share/man/man3openssl/SSL_COMP_add_compression_method.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_add_client_CA.3openssl \
-    target=SSL_CTX_set_client_CA_list.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_add_extra_chain_cert.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_add_session.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_callback_ctrl.3openssl \
-    target=SSL_CTX_ctrl.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_check_private_key.3openssl \
-    target=SSL_CTX_use_certificate.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_clear_options.3openssl \
-    target=SSL_CTX_set_options.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_ctrl.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_flush_sessions.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_free.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_get_cert_store.3openssl \
-    target=SSL_CTX_set_cert_store.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_get_client_CA_list.3openssl \
-    target=SSL_get_client_CA_list.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_get_client_cert_cb.3openssl \
-    target=SSL_CTX_set_client_cert_cb.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_get_ex_data.3openssl \
-    target=SSL_CTX_get_ex_new_index.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_get_ex_new_index.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_get_info_callback.3openssl \
-    target=SSL_CTX_set_info_callback.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_get_max_cert_list.3openssl \
-    target=SSL_CTX_set_max_cert_list.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_get_mode.3openssl \
-    target=SSL_CTX_set_mode.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_get_options.3openssl \
-    target=SSL_CTX_set_options.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_get_quiet_shutdown.3openssl \
-    target=SSL_CTX_set_quiet_shutdown.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_get_session_cache_mode.3openssl \
-    target=SSL_CTX_set_session_cache_mode.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_get_timeout.3openssl \
-    target=SSL_CTX_set_timeout.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_get_verify_callback.3openssl \
-    target=SSL_CTX_get_verify_mode.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_get_verify_depth.3openssl \
-    target=SSL_CTX_get_verify_mode.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_get_verify_mode.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_load_verify_locations.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_need_tmp_rsa.3openssl \
-    target=SSL_CTX_set_tmp_rsa_callback.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_new.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_remove_session.3openssl \
-    target=SSL_CTX_add_session.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_sess_accept.3openssl \
-    target=SSL_CTX_sess_number.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_sess_accept_good.3openssl \
-    target=SSL_CTX_sess_number.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_sess_accept_renegotiate.3openssl \
-    target=SSL_CTX_sess_number.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_sess_cache_full.3openssl \
-    target=SSL_CTX_sess_number.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_sess_cb_hits.3openssl \
-    target=SSL_CTX_sess_number.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_sess_connect.3openssl \
-    target=SSL_CTX_sess_number.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_sess_connect_good.3openssl \
-    target=SSL_CTX_sess_number.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_sess_connect_renegotiate.3openssl \
-    target=SSL_CTX_sess_number.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_sess_get_cache_size.3openssl \
-    target=SSL_CTX_sess_set_cache_size.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_sess_get_get_cb.3openssl \
-    target=SSL_CTX_sess_set_get_cb.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_sess_get_new_cb.3openssl \
-    target=SSL_CTX_sess_set_get_cb.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_sess_get_remove_cb.3openssl \
-    target=SSL_CTX_sess_set_get_cb.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_sess_hits.3openssl \
-    target=SSL_CTX_sess_number.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_sess_misses.3openssl \
-    target=SSL_CTX_sess_number.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_sess_number.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_sess_set_cache_size.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_sess_set_get_cb.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_sess_set_new_cb.3openssl \
-    target=SSL_CTX_sess_set_get_cb.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_sess_set_remove_cb.3openssl \
-    target=SSL_CTX_sess_set_get_cb.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_sess_timeouts.3openssl \
-    target=SSL_CTX_sess_number.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_sessions.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_set_cert_store.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_set_cert_verify_callback.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_set_cipher_list.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_set_client_CA_list.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_set_client_cert_cb.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_set_default_passwd_cb.3openssl
-link \
-    path=usr/share/man/man3openssl/SSL_CTX_set_default_passwd_cb_userdata.3openssl \
-    target=SSL_CTX_set_default_passwd_cb.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_set_ex_data.3openssl \
-    target=SSL_CTX_get_ex_new_index.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_set_generate_session_id.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_set_info_callback.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_set_max_cert_list.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_set_mode.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_set_msg_callback.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_set_msg_callback_arg.3openssl \
-    target=SSL_CTX_set_msg_callback.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_set_options.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_set_psk_client_callback.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_set_psk_server_callback.3openssl \
-    target=SSL_CTX_use_psk_identity_hint.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_set_quiet_shutdown.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_set_session_cache_mode.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_set_session_id_context.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_set_ssl_version.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_set_timeout.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_set_tmp_dh.3openssl \
-    target=SSL_CTX_set_tmp_dh_callback.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_set_tmp_dh_callback.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_set_tmp_rsa.3openssl \
-    target=SSL_CTX_set_tmp_rsa_callback.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_set_tmp_rsa_callback.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_set_verify.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_set_verify_depth.3openssl \
-    target=SSL_CTX_set_verify.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_use_PrivateKey.3openssl \
-    target=SSL_CTX_use_certificate.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_use_PrivateKey_ASN1.3openssl \
-    target=SSL_CTX_use_certificate.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_use_PrivateKey_file.3openssl \
-    target=SSL_CTX_use_certificate.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_use_RSAPrivateKey.3openssl \
-    target=SSL_CTX_use_certificate.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_use_RSAPrivateKey_ASN1.3openssl \
-    target=SSL_CTX_use_certificate.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_use_RSAPrivateKey_file.3openssl \
-    target=SSL_CTX_use_certificate.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_use_certificate.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_use_certificate_ASN1.3openssl \
-    target=SSL_CTX_use_certificate.3openssl
-link \
-    path=usr/share/man/man3openssl/SSL_CTX_use_certificate_chain_file.3openssl \
-    target=SSL_CTX_use_certificate.3openssl
-link path=usr/share/man/man3openssl/SSL_CTX_use_certificate_file.3openssl \
-    target=SSL_CTX_use_certificate.3openssl
-file path=usr/share/man/man3openssl/SSL_CTX_use_psk_identity_hint.3openssl
-file path=usr/share/man/man3openssl/SSL_SESSION_free.3openssl
-link path=usr/share/man/man3openssl/SSL_SESSION_get_ex_data.3openssl \
-    target=SSL_SESSION_get_ex_new_index.3openssl
-file path=usr/share/man/man3openssl/SSL_SESSION_get_ex_new_index.3openssl
-file path=usr/share/man/man3openssl/SSL_SESSION_get_time.3openssl
-link path=usr/share/man/man3openssl/SSL_SESSION_get_timeout.3openssl \
-    target=SSL_SESSION_get_time.3openssl
-link path=usr/share/man/man3openssl/SSL_SESSION_set_ex_data.3openssl \
-    target=SSL_SESSION_get_ex_new_index.3openssl
-link path=usr/share/man/man3openssl/SSL_SESSION_set_time.3openssl \
-    target=SSL_SESSION_get_time.3openssl
-link path=usr/share/man/man3openssl/SSL_SESSION_set_timeout.3openssl \
-    target=SSL_SESSION_get_time.3openssl
-file path=usr/share/man/man3openssl/SSL_accept.3openssl
-link path=usr/share/man/man3openssl/SSL_add_client_CA.3openssl \
-    target=SSL_CTX_set_client_CA_list.3openssl
-link path=usr/share/man/man3openssl/SSL_add_session.3openssl \
-    target=SSL_CTX_add_session.3openssl
-link path=usr/share/man/man3openssl/SSL_alert_desc_string.3openssl \
-    target=SSL_alert_type_string.3openssl
-link path=usr/share/man/man3openssl/SSL_alert_desc_string_long.3openssl \
-    target=SSL_alert_type_string.3openssl
-file path=usr/share/man/man3openssl/SSL_alert_type_string.3openssl
-link path=usr/share/man/man3openssl/SSL_alert_type_string_long.3openssl \
-    target=SSL_alert_type_string.3openssl
-link path=usr/share/man/man3openssl/SSL_callback_ctrl.3openssl \
-    target=SSL_CTX_ctrl.3openssl
-link path=usr/share/man/man3openssl/SSL_check_private_key.3openssl \
-    target=SSL_CTX_use_certificate.3openssl
-file path=usr/share/man/man3openssl/SSL_clear.3openssl
-link path=usr/share/man/man3openssl/SSL_clear_options.3openssl \
-    target=SSL_CTX_set_options.3openssl
-file path=usr/share/man/man3openssl/SSL_connect.3openssl
-link path=usr/share/man/man3openssl/SSL_ctrl.3openssl \
-    target=SSL_CTX_ctrl.3openssl
-file path=usr/share/man/man3openssl/SSL_do_handshake.3openssl
-link path=usr/share/man/man3openssl/SSL_flush_sessions.3openssl \
-    target=SSL_CTX_flush_sessions.3openssl
-file path=usr/share/man/man3openssl/SSL_free.3openssl
-file path=usr/share/man/man3openssl/SSL_get_SSL_CTX.3openssl
-link path=usr/share/man/man3openssl/SSL_get_accept_state.3openssl \
-    target=SSL_set_connect_state.3openssl
-link path=usr/share/man/man3openssl/SSL_get_cipher.3openssl \
-    target=SSL_get_current_cipher.3openssl
-link path=usr/share/man/man3openssl/SSL_get_cipher_bits.3openssl \
-    target=SSL_get_current_cipher.3openssl
-link path=usr/share/man/man3openssl/SSL_get_cipher_list.3openssl \
-    target=SSL_get_ciphers.3openssl
-link path=usr/share/man/man3openssl/SSL_get_cipher_name.3openssl \
-    target=SSL_get_current_cipher.3openssl
-link path=usr/share/man/man3openssl/SSL_get_cipher_version.3openssl \
-    target=SSL_get_current_cipher.3openssl
-file path=usr/share/man/man3openssl/SSL_get_ciphers.3openssl
-file path=usr/share/man/man3openssl/SSL_get_client_CA_list.3openssl
-file path=usr/share/man/man3openssl/SSL_get_current_cipher.3openssl
-file path=usr/share/man/man3openssl/SSL_get_default_timeout.3openssl
-file path=usr/share/man/man3openssl/SSL_get_error.3openssl
-link path=usr/share/man/man3openssl/SSL_get_ex_data.3openssl \
-    target=SSL_get_ex_new_index.3openssl
-file path=usr/share/man/man3openssl/SSL_get_ex_data_X509_STORE_CTX_idx.3openssl
-file path=usr/share/man/man3openssl/SSL_get_ex_new_index.3openssl
-file path=usr/share/man/man3openssl/SSL_get_fd.3openssl
-link path=usr/share/man/man3openssl/SSL_get_info_callback.3openssl \
-    target=SSL_CTX_set_info_callback.3openssl
-link path=usr/share/man/man3openssl/SSL_get_max_cert_list.3openssl \
-    target=SSL_CTX_set_max_cert_list.3openssl
-link path=usr/share/man/man3openssl/SSL_get_mode.3openssl \
-    target=SSL_CTX_set_mode.3openssl
-link path=usr/share/man/man3openssl/SSL_get_msg_callback_arg.3openssl \
-    target=SSL_CTX_set_msg_callback.3openssl
-link path=usr/share/man/man3openssl/SSL_get_options.3openssl \
-    target=SSL_CTX_set_options.3openssl
-file path=usr/share/man/man3openssl/SSL_get_peer_cert_chain.3openssl
-file path=usr/share/man/man3openssl/SSL_get_peer_certificate.3openssl
-file path=usr/share/man/man3openssl/SSL_get_psk_identity.3openssl
-link path=usr/share/man/man3openssl/SSL_get_psk_identity_hint.3openssl \
-    target=SSL_get_psk_identity.3openssl
-link path=usr/share/man/man3openssl/SSL_get_quiet_shutdown.3openssl \
-    target=SSL_CTX_set_quiet_shutdown.3openssl
-file path=usr/share/man/man3openssl/SSL_get_rbio.3openssl
-link \
-    path=usr/share/man/man3openssl/SSL_get_secure_renegotiation_support.3openssl \
-    target=SSL_CTX_set_options.3openssl
-file path=usr/share/man/man3openssl/SSL_get_session.3openssl
-link path=usr/share/man/man3openssl/SSL_get_shutdown.3openssl \
-    target=SSL_set_shutdown.3openssl
-link path=usr/share/man/man3openssl/SSL_get_ssl_method.3openssl \
-    target=SSL_CTX_set_ssl_version.3openssl
-link path=usr/share/man/man3openssl/SSL_get_verify_callback.3openssl \
-    target=SSL_CTX_get_verify_mode.3openssl
-link path=usr/share/man/man3openssl/SSL_get_verify_depth.3openssl \
-    target=SSL_CTX_get_verify_mode.3openssl
-link path=usr/share/man/man3openssl/SSL_get_verify_mode.3openssl \
-    target=SSL_CTX_get_verify_mode.3openssl
-file path=usr/share/man/man3openssl/SSL_get_verify_result.3openssl
-file path=usr/share/man/man3openssl/SSL_get_version.3openssl
-link path=usr/share/man/man3openssl/SSL_has_matching_session_id.3openssl \
-    target=SSL_CTX_set_generate_session_id.3openssl
-file path=usr/share/man/man3openssl/SSL_library_init.3openssl
-file path=usr/share/man/man3openssl/SSL_load_client_CA_file.3openssl
-link path=usr/share/man/man3openssl/SSL_load_error_strings.3openssl \
-    target=ERR_load_crypto_strings.3openssl
-link path=usr/share/man/man3openssl/SSL_need_tmp_rsa.3openssl \
-    target=SSL_CTX_set_tmp_rsa_callback.3openssl
-file path=usr/share/man/man3openssl/SSL_new.3openssl
-file path=usr/share/man/man3openssl/SSL_pending.3openssl
-file path=usr/share/man/man3openssl/SSL_read.3openssl
-link path=usr/share/man/man3openssl/SSL_remove_session.3openssl \
-    target=SSL_CTX_add_session.3openssl
-file path=usr/share/man/man3openssl/SSL_rstate_string.3openssl
-link path=usr/share/man/man3openssl/SSL_rstate_string_long.3openssl \
-    target=SSL_rstate_string.3openssl
-file path=usr/share/man/man3openssl/SSL_session_reused.3openssl
-file path=usr/share/man/man3openssl/SSL_set_bio.3openssl
-link path=usr/share/man/man3openssl/SSL_set_cipher_list.3openssl \
-    target=SSL_CTX_set_cipher_list.3openssl
-link path=usr/share/man/man3openssl/SSL_set_client_CA_list.3openssl \
-    target=SSL_CTX_set_client_CA_list.3openssl
-file path=usr/share/man/man3openssl/SSL_set_connect_state.3openssl
-link path=usr/share/man/man3openssl/SSL_set_ex_data.3openssl \
-    target=SSL_get_ex_new_index.3openssl
-file path=usr/share/man/man3openssl/SSL_set_fd.3openssl
-link path=usr/share/man/man3openssl/SSL_set_generate_session_id.3openssl \
-    target=SSL_CTX_set_generate_session_id.3openssl
-link path=usr/share/man/man3openssl/SSL_set_info_callback.3openssl \
-    target=SSL_CTX_set_info_callback.3openssl
-link path=usr/share/man/man3openssl/SSL_set_max_cert_list.3openssl \
-    target=SSL_CTX_set_max_cert_list.3openssl
-link path=usr/share/man/man3openssl/SSL_set_mode.3openssl \
-    target=SSL_CTX_set_mode.3openssl
-link path=usr/share/man/man3openssl/SSL_set_msg_callback.3openssl \
-    target=SSL_CTX_set_msg_callback.3openssl
-link path=usr/share/man/man3openssl/SSL_set_options.3openssl \
-    target=SSL_CTX_set_options.3openssl
-link path=usr/share/man/man3openssl/SSL_set_psk_client_callback.3openssl \
-    target=SSL_CTX_set_psk_client_callback.3openssl
-link path=usr/share/man/man3openssl/SSL_set_psk_server_callback.3openssl \
-    target=SSL_CTX_use_psk_identity_hint.3openssl
-link path=usr/share/man/man3openssl/SSL_set_quiet_shutdown.3openssl \
-    target=SSL_CTX_set_quiet_shutdown.3openssl
-file path=usr/share/man/man3openssl/SSL_set_session.3openssl
-link path=usr/share/man/man3openssl/SSL_set_session_id_context.3openssl \
-    target=SSL_CTX_set_session_id_context.3openssl
-file path=usr/share/man/man3openssl/SSL_set_shutdown.3openssl
-link path=usr/share/man/man3openssl/SSL_set_ssl_method.3openssl \
-    target=SSL_CTX_set_ssl_version.3openssl
-link path=usr/share/man/man3openssl/SSL_set_tmp_dh.3openssl \
-    target=SSL_CTX_set_tmp_dh_callback.3openssl
-link path=usr/share/man/man3openssl/SSL_set_tmp_dh_callback.3openssl \
-    target=SSL_CTX_set_tmp_dh_callback.3openssl
-link path=usr/share/man/man3openssl/SSL_set_tmp_rsa.3openssl \
-    target=SSL_CTX_set_tmp_rsa_callback.3openssl
-link path=usr/share/man/man3openssl/SSL_set_tmp_rsa_callback.3openssl \
-    target=SSL_CTX_set_tmp_rsa_callback.3openssl
-link path=usr/share/man/man3openssl/SSL_set_verify.3openssl \
-    target=SSL_CTX_set_verify.3openssl
-link path=usr/share/man/man3openssl/SSL_set_verify_depth.3openssl \
-    target=SSL_CTX_set_verify.3openssl
-file path=usr/share/man/man3openssl/SSL_set_verify_result.3openssl
-file path=usr/share/man/man3openssl/SSL_shutdown.3openssl
-file path=usr/share/man/man3openssl/SSL_state_string.3openssl
-link path=usr/share/man/man3openssl/SSL_state_string_long.3openssl \
-    target=SSL_state_string.3openssl
-link path=usr/share/man/man3openssl/SSL_use_PrivateKey.3openssl \
-    target=SSL_CTX_use_certificate.3openssl
-link path=usr/share/man/man3openssl/SSL_use_PrivateKey_ASN1.3openssl \
-    target=SSL_CTX_use_certificate.3openssl
-link path=usr/share/man/man3openssl/SSL_use_PrivateKey_file.3openssl \
-    target=SSL_CTX_use_certificate.3openssl
-link path=usr/share/man/man3openssl/SSL_use_RSAPrivateKey.3openssl \
-    target=SSL_CTX_use_certificate.3openssl
-link path=usr/share/man/man3openssl/SSL_use_RSAPrivateKey_ASN1.3openssl \
-    target=SSL_CTX_use_certificate.3openssl
-link path=usr/share/man/man3openssl/SSL_use_RSAPrivateKey_file.3openssl \
-    target=SSL_CTX_use_certificate.3openssl
-link path=usr/share/man/man3openssl/SSL_use_certificate.3openssl \
-    target=SSL_CTX_use_certificate.3openssl
-link path=usr/share/man/man3openssl/SSL_use_certificate_ASN1.3openssl \
-    target=SSL_CTX_use_certificate.3openssl
-link path=usr/share/man/man3openssl/SSL_use_certificate_file.3openssl \
-    target=SSL_CTX_use_certificate.3openssl
-link path=usr/share/man/man3openssl/SSL_use_psk_identity_hint.3openssl \
-    target=SSL_CTX_use_psk_identity_hint.3openssl
-file path=usr/share/man/man3openssl/SSL_want.3openssl
-link path=usr/share/man/man3openssl/SSL_want_nothing.3openssl \
-    target=SSL_want.3openssl
-link path=usr/share/man/man3openssl/SSL_want_read.3openssl \
-    target=SSL_want.3openssl
-link path=usr/share/man/man3openssl/SSL_want_write.3openssl \
-    target=SSL_want.3openssl
-link path=usr/share/man/man3openssl/SSL_want_x509_lookup.3openssl \
-    target=SSL_want.3openssl
-file path=usr/share/man/man3openssl/SSL_write.3openssl
-link path=usr/share/man/man3openssl/SSLeay.3openssl \
-    target=OPENSSL_VERSION_NUMBER.3openssl
-link path=usr/share/man/man3openssl/SSLeay_add_ssl_algorithms.3openssl \
-    target=SSL_library_init.3openssl
-link path=usr/share/man/man3openssl/SSLeay_version.3openssl \
-    target=OPENSSL_VERSION_NUMBER.3openssl
-link path=usr/share/man/man3openssl/UI_OpenSSL.3openssl target=ui.3openssl
-link path=usr/share/man/man3openssl/UI_add_error_string.3openssl \
-    target=ui.3openssl
-link path=usr/share/man/man3openssl/UI_add_info_string.3openssl \
-    target=ui.3openssl
-link path=usr/share/man/man3openssl/UI_add_input_boolean.3openssl \
-    target=ui.3openssl
-link path=usr/share/man/man3openssl/UI_add_input_string.3openssl \
-    target=ui.3openssl
-link path=usr/share/man/man3openssl/UI_add_user_data.3openssl target=ui.3openssl
-link path=usr/share/man/man3openssl/UI_add_verify_string.3openssl \
-    target=ui.3openssl
-link path=usr/share/man/man3openssl/UI_construct_prompt.3openssl \
-    target=ui.3openssl
-link path=usr/share/man/man3openssl/UI_ctrl.3openssl target=ui.3openssl
-link path=usr/share/man/man3openssl/UI_dup_error_string.3openssl \
-    target=ui.3openssl
-link path=usr/share/man/man3openssl/UI_dup_info_string.3openssl \
-    target=ui.3openssl
-link path=usr/share/man/man3openssl/UI_dup_input_boolean.3openssl \
-    target=ui.3openssl
-link path=usr/share/man/man3openssl/UI_dup_input_string.3openssl \
-    target=ui.3openssl
-link path=usr/share/man/man3openssl/UI_dup_verify_string.3openssl \
-    target=ui.3openssl
-link path=usr/share/man/man3openssl/UI_free.3openssl target=ui.3openssl
-link path=usr/share/man/man3openssl/UI_get0_result.3openssl target=ui.3openssl
-link path=usr/share/man/man3openssl/UI_get0_user_data.3openssl \
-    target=ui.3openssl
-link path=usr/share/man/man3openssl/UI_get_default_method.3openssl \
-    target=ui.3openssl
-link path=usr/share/man/man3openssl/UI_get_method.3openssl target=ui.3openssl
-link path=usr/share/man/man3openssl/UI_new.3openssl target=ui.3openssl
-link path=usr/share/man/man3openssl/UI_new_method.3openssl target=ui.3openssl
-link path=usr/share/man/man3openssl/UI_process.3openssl target=ui.3openssl
-link path=usr/share/man/man3openssl/UI_set_default_method.3openssl \
-    target=ui.3openssl
-link path=usr/share/man/man3openssl/UI_set_method.3openssl target=ui.3openssl
-link path=usr/share/man/man3openssl/X509_NAME_ENTRY_create_by_NID.3openssl \
-    target=X509_NAME_ENTRY_get_object.3openssl
-link path=usr/share/man/man3openssl/X509_NAME_ENTRY_create_by_OBJ.3openssl \
-    target=X509_NAME_ENTRY_get_object.3openssl
-link path=usr/share/man/man3openssl/X509_NAME_ENTRY_create_by_txt.3openssl \
-    target=X509_NAME_ENTRY_get_object.3openssl
-link path=usr/share/man/man3openssl/X509_NAME_ENTRY_get_data.3openssl \
-    target=X509_NAME_ENTRY_get_object.3openssl
-file path=usr/share/man/man3openssl/X509_NAME_ENTRY_get_object.3openssl
-link path=usr/share/man/man3openssl/X509_NAME_ENTRY_set_data.3openssl \
-    target=X509_NAME_ENTRY_get_object.3openssl
-link path=usr/share/man/man3openssl/X509_NAME_ENTRY_set_object.3openssl \
-    target=X509_NAME_ENTRY_get_object.3openssl
-link path=usr/share/man/man3openssl/X509_NAME_add_entry.3openssl \
-    target=X509_NAME_add_entry_by_txt.3openssl
-link path=usr/share/man/man3openssl/X509_NAME_add_entry_by_NID.3openssl \
-    target=X509_NAME_add_entry_by_txt.3openssl
-link path=usr/share/man/man3openssl/X509_NAME_add_entry_by_OBJ.3openssl \
-    target=X509_NAME_add_entry_by_txt.3openssl
-file path=usr/share/man/man3openssl/X509_NAME_add_entry_by_txt.3openssl
-link path=usr/share/man/man3openssl/X509_NAME_delete_entry.3openssl \
-    target=X509_NAME_add_entry_by_txt.3openssl
-link path=usr/share/man/man3openssl/X509_NAME_entry_count.3openssl \
-    target=X509_NAME_get_index_by_NID.3openssl
-link path=usr/share/man/man3openssl/X509_NAME_get_entry.3openssl \
-    target=X509_NAME_get_index_by_NID.3openssl
-file path=usr/share/man/man3openssl/X509_NAME_get_index_by_NID.3openssl
-link path=usr/share/man/man3openssl/X509_NAME_get_index_by_OBJ.3openssl \
-    target=X509_NAME_get_index_by_NID.3openssl
-link path=usr/share/man/man3openssl/X509_NAME_get_text_by_NID.3openssl \
-    target=X509_NAME_get_index_by_NID.3openssl
-link path=usr/share/man/man3openssl/X509_NAME_get_text_by_OBJ.3openssl \
-    target=X509_NAME_get_index_by_NID.3openssl
-link path=usr/share/man/man3openssl/X509_NAME_oneline.3openssl \
-    target=X509_NAME_print_ex.3openssl
-link path=usr/share/man/man3openssl/X509_NAME_print.3openssl \
-    target=X509_NAME_print_ex.3openssl
-file path=usr/share/man/man3openssl/X509_NAME_print_ex.3openssl
-link path=usr/share/man/man3openssl/X509_NAME_print_ex_fp.3openssl \
-    target=X509_NAME_print_ex.3openssl
-link path=usr/share/man/man3openssl/X509_STORE_CTX_cleanup.3openssl \
-    target=X509_STORE_CTX_new.3openssl
-link path=usr/share/man/man3openssl/X509_STORE_CTX_free.3openssl \
-    target=X509_STORE_CTX_new.3openssl
-link path=usr/share/man/man3openssl/X509_STORE_CTX_get0_param.3openssl \
-    target=X509_STORE_CTX_new.3openssl
-link path=usr/share/man/man3openssl/X509_STORE_CTX_get1_chain.3openssl \
-    target=X509_STORE_CTX_get_error.3openssl
-link path=usr/share/man/man3openssl/X509_STORE_CTX_get_current_cert.3openssl \
-    target=X509_STORE_CTX_get_error.3openssl
-file path=usr/share/man/man3openssl/X509_STORE_CTX_get_error.3openssl
-link path=usr/share/man/man3openssl/X509_STORE_CTX_get_error_depth.3openssl \
-    target=X509_STORE_CTX_get_error.3openssl
-link path=usr/share/man/man3openssl/X509_STORE_CTX_get_ex_data.3openssl \
-    target=X509_STORE_CTX_get_ex_new_index.3openssl
-file path=usr/share/man/man3openssl/X509_STORE_CTX_get_ex_new_index.3openssl
-link path=usr/share/man/man3openssl/X509_STORE_CTX_init.3openssl \
-    target=X509_STORE_CTX_new.3openssl
-file path=usr/share/man/man3openssl/X509_STORE_CTX_new.3openssl
-link path=usr/share/man/man3openssl/X509_STORE_CTX_set0_crls.3openssl \
-    target=X509_STORE_CTX_new.3openssl
-link path=usr/share/man/man3openssl/X509_STORE_CTX_set0_param.3openssl \
-    target=X509_STORE_CTX_new.3openssl
-link path=usr/share/man/man3openssl/X509_STORE_CTX_set_cert.3openssl \
-    target=X509_STORE_CTX_new.3openssl
-link path=usr/share/man/man3openssl/X509_STORE_CTX_set_chain.3openssl \
-    target=X509_STORE_CTX_new.3openssl
-link path=usr/share/man/man3openssl/X509_STORE_CTX_set_default.3openssl \
-    target=X509_STORE_CTX_new.3openssl
-link path=usr/share/man/man3openssl/X509_STORE_CTX_set_error.3openssl \
-    target=X509_STORE_CTX_get_error.3openssl
-link path=usr/share/man/man3openssl/X509_STORE_CTX_set_ex_data.3openssl \
-    target=X509_STORE_CTX_get_ex_new_index.3openssl
-file path=usr/share/man/man3openssl/X509_STORE_CTX_set_verify_cb.3openssl
-link path=usr/share/man/man3openssl/X509_STORE_CTX_trusted_stack.3openssl \
-    target=X509_STORE_CTX_new.3openssl
-link path=usr/share/man/man3openssl/X509_STORE_set_verify_cb.3openssl \
-    target=X509_STORE_set_verify_cb_func.3openssl
-file path=usr/share/man/man3openssl/X509_STORE_set_verify_cb_func.3openssl
-link path=usr/share/man/man3openssl/X509_VERIFY_PARAM_add0_policy.3openssl \
-    target=X509_VERIFY_PARAM_set_flags.3openssl
-link path=usr/share/man/man3openssl/X509_VERIFY_PARAM_clear_flags.3openssl \
-    target=X509_VERIFY_PARAM_set_flags.3openssl
-link path=usr/share/man/man3openssl/X509_VERIFY_PARAM_get_depth.3openssl \
-    target=X509_VERIFY_PARAM_set_flags.3openssl
-link path=usr/share/man/man3openssl/X509_VERIFY_PARAM_get_flags.3openssl \
-    target=X509_VERIFY_PARAM_set_flags.3openssl
-link path=usr/share/man/man3openssl/X509_VERIFY_PARAM_set1_policies.3openssl \
-    target=X509_VERIFY_PARAM_set_flags.3openssl
-link path=usr/share/man/man3openssl/X509_VERIFY_PARAM_set_depth.3openssl \
-    target=X509_VERIFY_PARAM_set_flags.3openssl
-file path=usr/share/man/man3openssl/X509_VERIFY_PARAM_set_flags.3openssl
-link path=usr/share/man/man3openssl/X509_VERIFY_PARAM_set_purpose.3openssl \
-    target=X509_VERIFY_PARAM_set_flags.3openssl
-link path=usr/share/man/man3openssl/X509_VERIFY_PARAM_set_time.3openssl \
-    target=X509_VERIFY_PARAM_set_flags.3openssl
-link path=usr/share/man/man3openssl/X509_VERIFY_PARAM_set_trust.3openssl \
-    target=X509_VERIFY_PARAM_set_flags.3openssl
-link path=usr/share/man/man3openssl/X509_free.3openssl target=X509_new.3openssl
-file path=usr/share/man/man3openssl/X509_new.3openssl
-file path=usr/share/man/man3openssl/X509_verify_cert.3openssl
-link path=usr/share/man/man3openssl/X509_verify_cert_error_string.3openssl \
-    target=X509_STORE_CTX_get_error.3openssl
-file path=usr/share/man/man3openssl/bio.3openssl
-file path=usr/share/man/man3openssl/blowfish.3openssl
-file path=usr/share/man/man3openssl/bn.3openssl
-link path=usr/share/man/man3openssl/bn_add_words.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_check_top.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_cmp_words.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_div_words.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_dump.3openssl target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_expand.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_expand2.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_fix_top.3openssl \
-    target=bn_internal.3openssl
-file path=usr/share/man/man3openssl/bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_mul_add_words.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_mul_comba4.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_mul_comba8.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_mul_high.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_mul_low_normal.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_mul_low_recursive.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_mul_normal.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_mul_part_recursive.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_mul_recursive.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_mul_words.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_print.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_set_high.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_set_low.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_set_max.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_sqr_comba4.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_sqr_comba8.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_sqr_normal.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_sqr_recursive.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_sqr_words.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_sub_words.3openssl \
-    target=bn_internal.3openssl
-link path=usr/share/man/man3openssl/bn_wexpand.3openssl \
-    target=bn_internal.3openssl
-file path=usr/share/man/man3openssl/buffer.3openssl
-file path=usr/share/man/man3openssl/crypto.3openssl
-link path=usr/share/man/man3openssl/d2i_509_CRL_fp.3openssl \
-    target=d2i_X509_CRL.3openssl
-file path=usr/share/man/man3openssl/d2i_ASN1_OBJECT.3openssl
-file path=usr/share/man/man3openssl/d2i_DHparams.3openssl
-link path=usr/share/man/man3openssl/d2i_DSAPrivateKey.3openssl \
-    target=d2i_DSAPublicKey.3openssl
-file path=usr/share/man/man3openssl/d2i_DSAPublicKey.3openssl
-link path=usr/share/man/man3openssl/d2i_DSA_PUBKEY.3openssl \
-    target=d2i_DSAPublicKey.3openssl
-link path=usr/share/man/man3openssl/d2i_DSA_SIG.3openssl \
-    target=d2i_DSAPublicKey.3openssl
-link path=usr/share/man/man3openssl/d2i_Netscape_RSA.3openssl \
-    target=d2i_RSAPublicKey.3openssl
-file path=usr/share/man/man3openssl/d2i_PKCS8PrivateKey.3openssl
-link path=usr/share/man/man3openssl/d2i_PKCS8PrivateKey_bio.3openssl \
-    target=d2i_PKCS8PrivateKey.3openssl
-link path=usr/share/man/man3openssl/d2i_PKCS8PrivateKey_fp.3openssl \
-    target=d2i_PKCS8PrivateKey.3openssl
-link path=usr/share/man/man3openssl/d2i_RSAPrivateKey.3openssl \
-    target=d2i_RSAPublicKey.3openssl
-file path=usr/share/man/man3openssl/d2i_RSAPublicKey.3openssl
-link path=usr/share/man/man3openssl/d2i_RSA_PUBKEY.3openssl \
-    target=d2i_RSAPublicKey.3openssl
-file path=usr/share/man/man3openssl/d2i_SSL_SESSION.3openssl
-file path=usr/share/man/man3openssl/d2i_X509.3openssl
-file path=usr/share/man/man3openssl/d2i_X509_ALGOR.3openssl
-file path=usr/share/man/man3openssl/d2i_X509_CRL.3openssl
-link path=usr/share/man/man3openssl/d2i_X509_CRL_bio.3openssl \
-    target=d2i_X509_CRL.3openssl
-file path=usr/share/man/man3openssl/d2i_X509_NAME.3openssl
-file path=usr/share/man/man3openssl/d2i_X509_REQ.3openssl
-link path=usr/share/man/man3openssl/d2i_X509_REQ_bio.3openssl \
-    target=d2i_X509_REQ.3openssl
-link path=usr/share/man/man3openssl/d2i_X509_REQ_fp.3openssl \
-    target=d2i_X509_REQ.3openssl
-file path=usr/share/man/man3openssl/d2i_X509_SIG.3openssl
-link path=usr/share/man/man3openssl/d2i_X509_bio.3openssl \
-    target=d2i_X509.3openssl
-link path=usr/share/man/man3openssl/d2i_X509_fp.3openssl \
-    target=d2i_X509.3openssl
-file path=usr/share/man/man3openssl/des.3openssl
-link path=usr/share/man/man3openssl/des_read_2passwords.3openssl \
-    target=ui_compat.3openssl
-link path=usr/share/man/man3openssl/des_read_password.3openssl \
-    target=ui_compat.3openssl
-link path=usr/share/man/man3openssl/des_read_pw.3openssl \
-    target=ui_compat.3openssl
-link path=usr/share/man/man3openssl/des_read_pw_string.3openssl \
-    target=ui_compat.3openssl
-file path=usr/share/man/man3openssl/dh.3openssl
-file path=usr/share/man/man3openssl/dsa.3openssl
-file path=usr/share/man/man3openssl/ecdsa.3openssl
-file path=usr/share/man/man3openssl/engine.3openssl
-file path=usr/share/man/man3openssl/err.3openssl
-file path=usr/share/man/man3openssl/evp.3openssl
-file path=usr/share/man/man3openssl/hmac.3openssl
-link path=usr/share/man/man3openssl/i2d_ASN1_OBJECT.3openssl \
-    target=d2i_ASN1_OBJECT.3openssl
-file path=usr/share/man/man3openssl/i2d_CMS_bio_stream.3openssl
-link path=usr/share/man/man3openssl/i2d_DHparams.3openssl \
-    target=d2i_DHparams.3openssl
-link path=usr/share/man/man3openssl/i2d_DSAPrivateKey.3openssl \
-    target=d2i_DSAPublicKey.3openssl
-link path=usr/share/man/man3openssl/i2d_DSAPublicKey.3openssl \
-    target=d2i_DSAPublicKey.3openssl
-link path=usr/share/man/man3openssl/i2d_DSA_PUBKEY.3openssl \
-    target=d2i_DSAPublicKey.3openssl
-link path=usr/share/man/man3openssl/i2d_DSA_SIG.3openssl \
-    target=d2i_DSAPublicKey.3openssl
-link path=usr/share/man/man3openssl/i2d_Netscape_RSA.3openssl \
-    target=d2i_RSAPublicKey.3openssl
-file path=usr/share/man/man3openssl/i2d_PKCS7_bio_stream.3openssl
-link path=usr/share/man/man3openssl/i2d_PKCS8PrivateKey_bio.3openssl \
-    target=d2i_PKCS8PrivateKey.3openssl
-link path=usr/share/man/man3openssl/i2d_PKCS8PrivateKey_fp.3openssl \
-    target=d2i_PKCS8PrivateKey.3openssl
-link path=usr/share/man/man3openssl/i2d_PKCS8PrivateKey_nid_bio.3openssl \
-    target=d2i_PKCS8PrivateKey.3openssl
-link path=usr/share/man/man3openssl/i2d_PKCS8PrivateKey_nid_fp.3openssl \
-    target=d2i_PKCS8PrivateKey.3openssl
-link path=usr/share/man/man3openssl/i2d_RSAPrivateKey.3openssl \
-    target=d2i_RSAPublicKey.3openssl
-link path=usr/share/man/man3openssl/i2d_RSAPublicKey.3openssl \
-    target=d2i_RSAPublicKey.3openssl
-link path=usr/share/man/man3openssl/i2d_RSA_PUBKEY.3openssl \
-    target=d2i_RSAPublicKey.3openssl
-link path=usr/share/man/man3openssl/i2d_SSL_SESSION.3openssl \
-    target=d2i_SSL_SESSION.3openssl
-link path=usr/share/man/man3openssl/i2d_X509.3openssl target=d2i_X509.3openssl
-link path=usr/share/man/man3openssl/i2d_X509_ALGOR.3openssl \
-    target=d2i_X509_ALGOR.3openssl
-link path=usr/share/man/man3openssl/i2d_X509_CRL.3openssl \
-    target=d2i_X509_CRL.3openssl
-link path=usr/share/man/man3openssl/i2d_X509_CRL_bio.3openssl \
-    target=d2i_X509_CRL.3openssl
-link path=usr/share/man/man3openssl/i2d_X509_CRL_fp.3openssl \
-    target=d2i_X509_CRL.3openssl
-link path=usr/share/man/man3openssl/i2d_X509_NAME.3openssl \
-    target=d2i_X509_NAME.3openssl
-link path=usr/share/man/man3openssl/i2d_X509_REQ.3openssl \
-    target=d2i_X509_REQ.3openssl
-link path=usr/share/man/man3openssl/i2d_X509_REQ_bio.3openssl \
-    target=d2i_X509_REQ.3openssl
-link path=usr/share/man/man3openssl/i2d_X509_REQ_fp.3openssl \
-    target=d2i_X509_REQ.3openssl
-link path=usr/share/man/man3openssl/i2d_X509_SIG.3openssl \
-    target=d2i_X509_SIG.3openssl
-link path=usr/share/man/man3openssl/i2d_X509_bio.3openssl \
-    target=d2i_X509.3openssl
-link path=usr/share/man/man3openssl/i2d_X509_fp.3openssl \
-    target=d2i_X509.3openssl
-link path=usr/share/man/man3openssl/lh_delete.3openssl target=lhash.3openssl
-link path=usr/share/man/man3openssl/lh_doall.3openssl target=lhash.3openssl
-link path=usr/share/man/man3openssl/lh_doall_arg.3openssl target=lhash.3openssl
-link path=usr/share/man/man3openssl/lh_error.3openssl target=lhash.3openssl
-link path=usr/share/man/man3openssl/lh_free.3openssl target=lhash.3openssl
-link path=usr/share/man/man3openssl/lh_insert.3openssl target=lhash.3openssl
-link path=usr/share/man/man3openssl/lh_new.3openssl target=lhash.3openssl
-link path=usr/share/man/man3openssl/lh_node_stats.3openssl \
-    target=lh_stats.3openssl
-link path=usr/share/man/man3openssl/lh_node_stats_bio.3openssl \
-    target=lh_stats.3openssl
-link path=usr/share/man/man3openssl/lh_node_usage_stats.3openssl \
-    target=lh_stats.3openssl
-link path=usr/share/man/man3openssl/lh_node_usage_stats_bio.3openssl \
-    target=lh_stats.3openssl
-link path=usr/share/man/man3openssl/lh_retrieve.3openssl target=lhash.3openssl
-file path=usr/share/man/man3openssl/lh_stats.3openssl
-link path=usr/share/man/man3openssl/lh_stats_bio.3openssl \
-    target=lh_stats.3openssl
-file path=usr/share/man/man3openssl/lhash.3openssl
-file path=usr/share/man/man3openssl/md5.3openssl
-file path=usr/share/man/man3openssl/mdc2.3openssl
-file path=usr/share/man/man3openssl/pem.3openssl
-file path=usr/share/man/man3openssl/rand.3openssl
-file path=usr/share/man/man3openssl/rc4.3openssl
-file path=usr/share/man/man3openssl/ripemd.3openssl
-file path=usr/share/man/man3openssl/rsa.3openssl
-file path=usr/share/man/man3openssl/sha.3openssl
-file path=usr/share/man/man3openssl/ssl.3openssl
-file path=usr/share/man/man3openssl/threads.3openssl
-file path=usr/share/man/man3openssl/ui.3openssl
-file path=usr/share/man/man3openssl/ui_compat.3openssl
-file path=usr/share/man/man3openssl/x509.3openssl
-file path=usr/share/man/man5openssl/config.5openssl
-file path=usr/share/man/man5openssl/x509v3_config.5openssl
-file path=usr/share/man/man7openssl/des_modes.7openssl
-legacy pkg=SUNWopensslr desc="OpenSSL Libraries (Root)" \
-    name="OpenSSL Libraries (Root)"
-license openssl-1.0.1.license license="OpenSSL, SSLeay"
--- a/components/openssl/openssl-1.0.1/patches-post-config/opensslconf.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
---- /tmp/opensslconf.h	Fri Feb 11 15:36:12 2011
-+++ openssl-1.0.0d/crypto/opensslconf.h	Fri Feb 11 16:58:36 2011
-@@ -181,7 +181,11 @@
- 
- #if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
- #if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
-+#if defined(__sparcv9) || defined(__x86_64)
-+#define ENGINESDIR "/lib/openssl/engines/64"
-+#else
- #define ENGINESDIR "/lib/openssl/engines"
-+#endif
- #define OPENSSLDIR "/etc/openssl"
- #endif
- #endif
-@@ -228,21 +232,39 @@
- /* 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
-+#if defined(__sparcv9) || defined(__x86_64)
-+#define DES_LONG unsigned int
-+#else
- #define DES_LONG unsigned long
- #endif
- #endif
-+#endif
- 
- #if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
- #define CONFIG_HEADER_BN_H
-+/*
-+ * OpenSSL revision 1.521 from 2005-12-15 in OpenSSL_1_0_0-stable branch changed
-+ * 64 bit sparcv9 configuration from SIXTY_FOUR_BIT_LONG to BN_LLONG.
-+ */
-+#if defined(__x86_64)
-+#undef BN_LLONG
-+#else
- #define BN_LLONG
-+#endif
- 
- /* Should we define BN_DIV2W here? */
- 
- /* Only one for the following should be defined */
-+#if defined(__x86_64)
-+#define SIXTY_FOUR_BIT_LONG
-+#undef THIRTY_TWO_BIT
-+#else
- #undef SIXTY_FOUR_BIT_LONG
- #undef SIXTY_FOUR_BIT
- #define THIRTY_TWO_BIT
- #endif
-+#undef SIXTY_FOUR_BIT
-+#endif
- 
- #if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
- #define CONFIG_HEADER_RC4_LOCL_H
--- a/components/openssl/openssl-1.0.1/patches/08-6193522.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-diff -ruN openssl-0.9.8a/apps/CA.pl.in openssl-0.9.8a/apps/CA.pl.in
---- openssl-0.9.8a/apps/CA.pl.in	2005-07-04 23:44:22.000000000 +0200
-+++ openssl-0.9.8a/apps/CA.pl.in	2009-04-21 16:08:45.354925289 +0200
-@@ -53,7 +53,7 @@
- $X509="$openssl x509";
- $PKCS12="$openssl pkcs12";
- 
--$CATOP="./demoCA";
-+$CATOP="/etc/openssl";
- $CAKEY="cakey.pem";
- $CAREQ="careq.pem";
- $CACERT="cacert.pem";
-diff -ruN openssl-0.9.8a/apps/openssl.cnf openssl-0.9.8a/apps/openssl.cnf
---- openssl-0.9.8a/apps/openssl.cnf	2005-09-16 14:20:24.000000000 +0200
-+++ openssl-0.9.8a/apps/openssl.cnf	2009-04-21 16:07:13.910980196 +0200
-@@ -39,7 +39,7 @@
- ####################################################################
- [ CA_default ]
- 
--dir		= ./demoCA		# Where everything is kept
-+dir		= /etc/openssl		# Where everything is kept
- certs		= $dir/certs		# Where the issued certs are kept
- crl_dir		= $dir/crl		# Where the issued crl are kept
- database	= $dir/index.txt	# database index file.
-@@ -49,7 +49,7 @@
- 
- certificate	= $dir/cacert.pem 	# The CA certificate
- serial		= $dir/serial 		# The current serial number
--crlnumber	= $dir/crlnumber	# the current crl number
-+#crlnumber	= $dir/crlnumber	# the current crl number
- 					# must be commented out to leave a V1 CRL
- crl		= $dir/crl.pem 		# The current CRL
- private_key	= $dir/private/cakey.pem# The private key
-@@ -126,17 +126,17 @@
- 
- [ req_distinguished_name ]
- countryName			= Country Name (2 letter code)
--countryName_default		= AU
-+#countryName_default		= US
- countryName_min			= 2
- countryName_max			= 2
- 
- stateOrProvinceName		= State or Province Name (full name)
--stateOrProvinceName_default	= Some-State
-+#stateOrProvinceName_default	= Some-State
- 
- localityName			= Locality Name (eg, city)
- 
- 0.organizationName		= Organization Name (eg, company)
--0.organizationName_default	= Internet Widgits Pty Ltd
-+#0.organizationName_default	= Unconfigured OpenSSL Installation
- 
- # we can do this but it is not needed normally :-)
- #1.organizationName		= Second Organization Name (eg, company)
--- a/components/openssl/openssl-1.0.1/patches/11-6546806.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-diff -ruN openssl-0.9.8a/doc/crypto/hmac.pod openssl-0.9.8a/doc/crypto/hmac.pod
---- openssl-0.9.8a/doc/crypto/hmac.pod	2002-07-18 20:54:45.000000000 +0200
-+++ openssl-0.9.8a/doc/crypto/hmac.pod	2009-04-10 11:09:46.449071541 +0200
-@@ -2,7 +2,7 @@
- 
- =head1 NAME
- 
--HMAC, HMAC_Init, HMAC_Update, HMAC_Final, HMAC_cleanup - HMAC message
-+HMAC, HMAC_CTX_init, HMAC_Init, HMAC_Init_ex, HMAC_Update, HMAC_Final, HMAC_CTX_cleanup, HMAC_cleanup - HMAC message
- authentication code
- 
- =head1 SYNOPSIS
--- a/components/openssl/openssl-1.0.1/patches/14-manpage_openssl.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-diff -ruN openssl-0.9.8a/util/extract-section.pl openssl-0.9.8a/util/extract-section.pl
---- openssl-0.9.8a/util/extract-section.pl	2004-11-25 18:47:31.000000000 +0100
-+++ openssl-0.9.8a/util/extract-section.pl	2009-04-08 12:05:03.128230348 +0200
-@@ -3,10 +3,10 @@
- while(<STDIN>) {
- 	if (/=for\s+comment\s+openssl_manual_section:(\S+)/)
- 		{
--		print "$1\n";
-+		print "${1}openssl\n";
- 		exit 0;
- 		}
- }
- 
--print "$ARGV[0]\n";
-+print "${ARGV[0]}openssl\n";
- 
--- a/components/openssl/openssl-1.0.1/patches/15-pkcs11_engine-0.9.8a.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,196 +0,0 @@
-#
-# This patch file adds the Solaris's pkcs11 engine.
-# This is Solaris-specific (developed in house): not suitable for upstream.
-#
---- /tmp/Configure	Fri Feb 11 14:40:39 2011
-+++ openssl-1.0.0d/Configure	Fri Feb 11 14:41:36 2011
-@@ -10,7 +10,7 @@
- 
- # see INSTALL for instructions.
- 
--my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [experimental-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-krb5] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
-+my $usage="Usage: Configure --pk11-libname=PK11_LIB_LOCATION [no-<cipher> ...] [enable-<cipher> ...] [experimental-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-dso] [no-krb5] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
- 
- # Options:
- #
-@@ -19,6 +19,9 @@
- # --prefix      prefix for the OpenSSL include, lib and bin directories
- #               (Default: the OPENSSLDIR directory)
- #
-+# --pk11-libname  PKCS#11 library name.
-+#               (Default: none)
-+#
- # --install_prefix  Additional prefix for package builders (empty by
- #               default).  This needn't be set in advance, you can
- #               just as well use "make INSTALL_PREFIX=/whatever install".
-@@ -657,6 +661,9 @@
- my $idx_arflags = $idx++;
- my $idx_multilib = $idx++;
- 
-+# PKCS#11 engine patch
-+my $pk11_libname="";
-+
- my $prefix="";
- my $libdir="";
- my $openssldir="";
-@@ -882,6 +888,10 @@
-				$_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei;
-				$flags.=$_." ";
-				}
-+			elsif (/^--pk11-libname=(.*)$/)
-+				{
-+				$pk11_libname=$1;
-+				}
-			elsif (/^--prefix=(.*)$/)
-				{
-				$prefix=$1;
-@@ -1049,6 +1059,13 @@
- 	exit 0;
- }
- 
-+if (! $pk11_libname)
-+        {
-+        print STDERR "You must set --pk11-libname for PKCS#11 library.\n";
-+        print STDERR "See README.pkcs11 for more information.\n";
-+        exit 1;
-+        }
-+
- if ($target =~ m/^CygWin32(-.*)$/) {
- 	$target = "Cygwin".$1;
- }
-@@ -1215,6 +1232,8 @@
- if ($flags ne "")	{ $cflags="$flags$cflags"; }
- else			{ $no_user_cflags=1;       }
- 
-+$cflags="-DPK11_LIB_LOCATION=\"$pk11_libname\" $cflags";
-+
- # Kerberos settings.  The flavor must be provided from outside, either through
- # the script "config" or manually.
- if (!$no_krb5)
-@@ -1604,6 +1623,7 @@
- 	s/^VERSION=.*/VERSION=$version/;
- 	s/^MAJOR=.*/MAJOR=$major/;
- 	s/^MINOR=.*/MINOR=$minor/;
-+	s/^PK11_LIB_LOCATION=.*/PK11_LIB_LOCATION=$pk11_libname/;
- 	s/^SHLIB_VERSION_NUMBER=.*/SHLIB_VERSION_NUMBER=$shlib_version_number/;
- 	s/^SHLIB_VERSION_HISTORY=.*/SHLIB_VERSION_HISTORY=$shlib_version_history/;
- 	s/^SHLIB_MAJOR=.*/SHLIB_MAJOR=$shlib_major/;
---- /tmp/Makefile.org	Fri Feb 11 14:41:54 2011
-+++ openssl-1.0.0d/Makefile.org	Fri Feb 11 14:38:01 2011
-@@ -26,6 +26,9 @@
- INSTALL_PREFIX=
- INSTALLTOP=/usr/local/ssl
- 
-+# You must set this through --pk11-libname configure option.
-+PK11_LIB_LOCATION=
-+
- # Do not edit this manually. Use Configure --openssldir=DIR do change this!
- OPENSSLDIR=/usr/local/ssl
- 
---- /tmp/Makefile	Mon Feb 14 14:59:22 2011
-+++ openssl-1.0.0d/engines/Makefile	Mon Feb 14 15:00:35 2011
-@@ -26,7 +26,8 @@
- APPS=
- 
- LIB=$(TOP)/libcrypto.a
--LIBNAMES= 4758cca aep atalla cswift gmp chil nuron sureware ubsec padlock capi
-+LIBNAMES= 4758cca aep atalla cswift gmp chil nuron sureware ubsec padlock capi \
-+	  pk11
- 
- LIBSRC=	e_4758cca.c \
- 	e_aep.c \
-@@ -38,7 +39,8 @@
- 	e_sureware.c \
- 	e_ubsec.c \
- 	e_padlock.c \
--	e_capi.c
-+	e_capi.c \
-+	e_pk11.c
- LIBOBJ= e_4758cca.o \
- 	e_aep.o \
- 	e_atalla.o \
-@@ -49,7 +51,8 @@
- 	e_sureware.o \
- 	e_ubsec.o \
- 	e_padlock.o \
--	e_capi.o
-+	e_capi.o \
-+	e_pk11.o
- 
- SRC= $(LIBSRC)
- 
-@@ -63,7 +66,8 @@
- 	e_nuron_err.c e_nuron_err.h \
- 	e_sureware_err.c e_sureware_err.h \
- 	e_ubsec_err.c e_ubsec_err.h \
--	e_capi_err.c e_capi_err.h
-+	e_capi_err.c e_capi_err.h \
-+	e_pk11.h e_pk11_uri.h e_pk11_err.h e_pk11_pub.c e_pk11_uri.c e_pk11_err.c
- 
- ALL=    $(GENERAL) $(SRC) $(HEADER)
- 
-@@ -78,7 +82,7 @@
- 		for l in $(LIBNAMES); do \
- 			$(MAKE) -f ../Makefile.shared -e \
- 				LIBNAME=$$l LIBEXTRAS=e_$$l.o \
--				LIBDEPS='-L.. -lcrypto $(EX_LIBS)' \
-+				LIBDEPS='-L.. -lcrypto -lcryptoutil $(EX_LIBS)' \
- 				link_o.$(SHLIB_TARGET); \
- 		done; \
- 	else \
---- crypto/engine/eng_all.c Thu Sep  5 12:59:50 2013
-+++ openssl-1.0.1e/crypto/engine/eng_all.c Thu Sep  5 12:59:50 2013
-@@ -60,6 +60,16 @@
- #include "cryptlib.h"
- #include "eng_int.h"
-
-+/*
-+ * pkcs11 engine no longer is a built-in engine, and ENGINE_load_pk11() needs to be
-+ * defined in libcrypto.so for ssh.  Instead of load pkcs11 engine, it load dynamic
-+ * engines.
-+ */
-+void ENGINE_load_pk11(void)
-+	{
-+	ENGINE_load_dynamic();
-+	}
-+
- void ENGINE_load_builtin_engines(void)
- {
-     /* Some ENGINEs need this */
---- crypto/dso/dso_lib.c Thu Sep  5 12:59:50 2013
-+++ openssl-1.0.1e/crypto/dso/dso_lib.c Thu Sep  5 12:59:50 2013
-@@ -396,6 +396,24 @@
-         DSOerr(DSO_F_DSO_CONVERT_FILENAME, DSO_R_NO_FILENAME);
-         return (NULL);
-     }
-+    /*
-+     * For pkcs11 engine, use libpk11.so (instead of libpkcs11.so) to
-+     * avoid the name collision with PKCS#11 library.
-+     */
-+    if (strcmp(filename, "pkcs11") == 0) {
-+#ifdef  _LP64
-+        static const char fullpath[] = "/lib/openssl/engines/64/libpk11.so";
-+#else
-+        static const char fullpath[] = "/lib/openssl/engines/libpk11.so";
-+#endif
-+        result = OPENSSL_malloc(strlen(fullpath) + 1);
-+        if(result == NULL) {
-+            DSOerr(DSO_F_DSO_CONVERT_FILENAME, ERR_R_MALLOC_FAILURE);
-+            return(NULL);
-+        }
-+        BUF_strlcpy(result, fullpath, strlen(fullpath) + 1);
-+        return (result);
-+    }
-     if ((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) {
-         if (dso->name_converter != NULL)
-             result = dso->name_converter(dso, filename);
---- /tmp/engine.h       Fri Feb 11 14:46:24 2011
-+++ openssl-1.0.0d/crypto/engine/engine.h       Fri Feb 11 14:47:32 2011
-@@ -413,6 +413,7 @@
- #  endif
- # endif
- void ENGINE_load_cryptodev(void);
-+void ENGINE_load_pk11(void);
- void ENGINE_load_rsax(void);
- void ENGINE_load_rdrand(void);
- void ENGINE_load_builtin_engines(void);
--- a/components/openssl/openssl-1.0.1/patches/18-compiler_opts.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-#
-# This was developed in house to support Solaris-specific options.
-# Not suitable for upstream.
-#
---- openssl-1.0.0d/Configure	Thu Feb 10 20:02:41 2011
-+++ /tmp/Configure	Thu Feb 10 20:01:51 2011
-@@ -257,6 +257,20 @@
- #"sunos-cc", "cc:-O4 -DNOPROTO -DNOCONST::(unknown):SUNOS::DES_UNROLL:${no_asm}::",
- "sunos-gcc","gcc:-O3 -mcpu=v8 -Dssize_t=int::(unknown):SUNOS::BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL DES_PTR DES_RISC1:${no_asm}::",
- 
-+#### Solaris configs, used for OpenSSL as delivered by S11.
-+"solaris-x86-cc-sunw","cc:-m32 -xO3 -xspace -Xa::-D_REENTRANT::-lsocket -lnsl -lc:BN_LLONG RC4_CHUNK DES_PTR DES_UNROLL BF_PTR:${x86_elf_asm}:dlfcn:solaris-shared:-KPIC:-m32 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign -M/usr/lib/ld/map.noexdata:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-+#
-+"solaris64-x86_64-cc-sunw","cc:-xO3 -m64 -xstrconst -Xa -DL_ENDIAN::-D_REENTRANT::-lsocket -lnsl -lc:SIXTY_FOUR_BIT_LONG RC4_CHUNK BF_PTR DES_PTR DES_INT DES_UNROLL:${x86_64_asm}:elf:dlfcn:solaris-shared:-KPIC:-m64 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign -M/usr/lib/ld/map.noexdata:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-+#
-+"solaris-sparcv9-cc-sunw","cc:-xtarget=ultra -m32 -Qoption cg -xregs=no%appl -xO5 -xstrconst -xdepend -Xa -DB_ENDIAN -DBN_DIV2W::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -lc:BN_LLONG RC4_CHUNK_LL DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-m32 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-+#
-+"solaris64-sparcv9-cc-sunw","cc:-xtarget=ultra -m64 -Qoption cg -xregs=no%appl -xO5 -xstrconst -xdepend -xspace -Xa -DB_ENDIAN::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl -lc:BN_LLONG RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-m64 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):/usr/bin/ar rs::/64",
-+# Option -xF=%all instructs the compiler to place functions and data
-+# variables into separate section fragments, and option -xannotate=no removes
-+# the .annotate section. This enables the link editor to discard unused sections
-+# and files when linking wanboot-openssl.o
-+"solaris64-sparcv9-cc-sunw-wanboot","cc:-xtarget=ultra -m64 -Qoption cg -xregs=no%appl -xO5 -xstrconst -xdepend -xspace -xannotate=no -xF=%all -Xa -DB_ENDIAN::-D_REENTRANT:ULTRASPARC:-lsocket -lnsl:BN_LLONG RC4_CHUNK DES_INT DES_PTR DES_RISC1 DES_UNROLL BF_PTR:${sparcv9_asm}:dlfcn:solaris-shared:-KPIC:-m64 -G -dy -z text -zdefs -Bdirect -zignore -M/usr/lib/ld/map.pagealign:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):/usr/bin/ar rs::/64",
-+
- #### IRIX 5.x configs
- # -mips2 flag is added by ./config when appropriate.
- "irix-gcc","gcc:-O3 -DB_ENDIAN::(unknown):::BN_LLONG MD2_CHAR RC4_INDEX RC4_CHAR RC4_CHUNK DES_UNROLL DES_RISC2 DES_PTR BF_PTR:${mips32_asm}:o32:dlfcn:irix-shared:::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
--- a/components/openssl/openssl-1.0.1/patches/20-remove_rpath.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
---- /export/openssl/openssl-1.0.0d/Makefile.shared	Sat Aug 21 13:36:49 2010
-+++ openssl-1.0.0d/Makefile.shared	Mon Feb 14 14:25:51 2011
-@@ -393,7 +393,7 @@
- 	@ if $(DETECT_GNU_LD); then \
- 		$(DO_GNU_APP); \
- 	else \
--		LDFLAGS="$(CFLAGS) -R $(LIBRPATH)"; \
-+		LDFLAGS="$(CFLAGS)"; \
- 	fi; \
- 	$(LINK_APP)
- 
--- a/components/openssl/openssl-1.0.1/patches/23-noexstack.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
---- /tmp/Makefile.shared	Mon Feb 14 14:33:05 2011
-+++ openssl-1.0.0d/Makefile.shared	Mon Feb 14 14:35:56 2011
-@@ -389,6 +389,7 @@
- 		SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX -Wl,-Bsymbolic"; \
- 	fi; \
- 	$(LINK_SO_A)
-+# Make sure the apps have non-executable stacks and data (x86/x64 only).
- link_app.solaris:
- 	@ if $(DETECT_GNU_LD); then \
- 		$(DO_GNU_APP); \
-@@ -395,6 +396,10 @@
- 	else \
- 		LDFLAGS="$(CFLAGS)"; \
- 	fi; \
-+	if expr $(PLATFORM) : '.*x86.*' > /dev/null; then \
-+		LDFLAGS="$${LDFLAGS} -M/usr/lib/ld/map.noexdata"; \
-+	fi; \
-+	LDFLAGS="$${LDFLAGS} -M/usr/lib/ld/map.noexstk -M/usr/lib/ld/map.pagealign"; \
- 	$(LINK_APP)
- 
- # OpenServer 5 native compilers used
--- a/components/openssl/openssl-1.0.1/patches/27-6978791.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
---- /tmp/Makefile.shared	Mon Feb 14 14:39:29 2011
-+++ openssl-1.0.0d/Makefile.shared	Mon Feb 14 14:50:52 2011
-@@ -387,6 +387,9 @@
- 		ALLSYMSFLAGS="$${MINUSZ}allextract"; \
- 		NOALLSYMSFLAGS="$${MINUSZ}defaultextract"; \
- 		SHAREDFLAGS="$(CFLAGS) $(SHARED_LDFLAGS) -h $$SHLIB$$SHLIB_SOVER$$SHLIB_SUFFIX -Wl,-Bsymbolic"; \
-+		if [ $(LIBNAME) = "ssl" ]; then \
-+			SHAREDFLAGS="$$SHAREDFLAGS $${MINUSZ}nodelete"; \
-+		fi; \
- 	fi; \
- 	$(LINK_SO_A)
- # Make sure the apps have non-executable stacks and data (x86/x64 only).
--- a/components/openssl/openssl-1.0.1/patches/28-enginesdir.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-#
-# This was developed in house to configure the engine dir.
-# Not suitable for upstream.
-#
---- /tmp/18/Configure	Fri Feb 11 15:15:50 2011
-+++ openssl-1.0.0d/Configure	Fri Feb 11 15:18:09 2011
-@@ -18,6 +18,8 @@
- #               --prefix option is given; /usr/local/ssl otherwise)
- # --prefix      prefix for the OpenSSL include, lib and bin directories
- #               (Default: the OPENSSLDIR directory)
-+# --enginesdir  engines shared library location
-+#               (Default: $prefix/lib/engines)
- #
- # --pk11-libname  PKCS#11 library name.
- #               (Default: none)
-@@ -679,6 +679,7 @@
- my $prefix="";
- my $libdir="";
- my $openssldir="";
-+my $enginesdir="";
- my $exe_ext="";
- my $install_prefix= "$ENV{'INSTALL_PREFIX'}";
- my $cross_compile_prefix="";
-@@ -917,6 +920,10 @@
- 				{
- 				$openssldir=$1;
- 				}
-+			elsif (/^--enginesdir=(.*)$/)
-+				{
-+				$enginesdir=$1;
-+				}
- 			elsif (/^--install.prefix=(.*)$/)
- 				{
- 				$install_prefix=$1;
-@@ -1224,6 +1231,10 @@
- # we're ready to tolerate, so don't...
- $multilib="" if !-d "$prefix/lib$multilib";
- 
-+if ($enginesdir eq "") {
-+	$enginesdir = "$prefix/lib/engines";
-+}
-+
- $libdir="lib$multilib" if $libdir eq "";
- 
- $cflags = "$cflags$exp_cflags";
-@@ -1846,7 +1857,7 @@
- 		}
- 	elsif	(/^#define\s+ENGINESDIR/)
- 		{
--		my $foo = "$prefix/$libdir/engines";
-+		my $foo = "$enginesdir";
- 		$foo =~ s/\\/\\\\/g;
- 		print OUT "#define ENGINESDIR \"$foo\"\n";
- 		}
--- a/components/openssl/openssl-1.0.1/patches/29_fork_safe.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,275 +0,0 @@
-#
-# This file adds the code to setup internal mutexes and callback function.
-#	PSARC/2014/077
-#	PSARC/2015/043
-# This change was implemented in-house.  The issue was brought up to
-# the upstream engineers, but there was no commitment.
-#
---- openssl-1.0.1f/crypto/cryptlib.c.~1~	Fri Feb  7 10:41:36 2014
-+++ openssl-1.0.1f/crypto/cryptlib.c	Thu Feb  6 16:03:58 2014
-@@ -116,6 +116,7 @@
- 
- #include "cryptlib.h"
- #include <openssl/safestack.h>
-+#include <pthread.h>
- 
- #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
- static double SSLeay_MSVC5_hack = 0.0; /* and for VC1.5 */
-@@ -184,6 +185,8 @@
-  */
- static STACK_OF(CRYPTO_dynlock) *dyn_locks = NULL;
- 
-+static pthread_mutex_t *solaris_openssl_locks;
-+
- static void (MS_FAR *locking_callback) (int mode, int type,
-                                         const char *file, int line) = 0;
- static int (MS_FAR *add_lock_callback) (int *pointer, int amount,
-@@ -373,7 +376,10 @@
- void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func)
-                                          (const char *file, int line))
- {
--    dynlock_create_callback = func;
-+    /*
-+     * we now setup our own dynamic locking callback, and disallow
-+     * setting of another locking callback.
-+     */
- }
-
- void CRYPTO_set_dynlock_lock_callback(void (*func) (int mode,
-@@ -382,7 +388,10 @@
-                                                     const char *file,
-                                                     int line))
- {
--    dynlock_lock_callback = func;
-+    /*
-+     * we now setup our own dynamic locking callback, and disallow
-+     * setting of another locking callback.
-+     */
- }
-
- void CRYPTO_set_dynlock_destroy_callback(void (*func)
-@@ -389,7 +398,10 @@
-                                           (struct CRYPTO_dynlock_value *l,
-                                            const char *file, int line))
- {
--    dynlock_destroy_callback = func;
-+    /*
-+     * we now setup our own dynamic locking callback, and disallow
-+     * setting of another locking callback.
-+     */
- }
-
- void (*CRYPTO_get_locking_callback(void)) (int mode, int type,
-@@ -402,6 +414,129@@
-     return (add_lock_callback);
- }
-
-+/*
-+ * This is the locking callback function which all applications will be
-+ * using when CRYPTO_lock() is called.
-+ */ 
-+static void solaris_locking_callback(int mode, int type, const char *file,
-+    int line)
-+{
-+    if (mode & CRYPTO_LOCK) {
-+        pthread_mutex_lock(&solaris_openssl_locks[type]);
-+    } else {
-+        pthread_mutex_unlock(&solaris_openssl_locks[type]);
-+    }
-+}
-+
-+
-+/*
-+ * Implement Solaris's own dynamic locking routines.
-+ */
-+static struct CRYPTO_dynlock_value *
-+solaris_dynlock_create(const char *file, int line)
-+{
-+    int                        ret;
-+    pthread_mutex_t    *dynlock;
-+
-+    dynlock = OPENSSL_malloc(sizeof(pthread_mutex_t));
-+    if (dynlock == NULL) {
-+        return (NULL);
-+    }
-+
-+    ret = pthread_mutex_init(dynlock, NULL);
-+    OPENSSL_assert(ret);
-+
-+    return ((struct CRYPTO_dynlock_value *)dynlock);
-+}
-+
-+static void
-+solaris_dynlock_lock(int mode, struct CRYPTO_dynlock_value *dynlock,
-+    const char *file, int line)
-+{
-+    int        ret;
-+
-+    if (mode & CRYPTO_LOCK) {
-+        ret = pthread_mutex_lock((pthread_mutex_t *)dynlock);
-+    } else {
-+        ret = pthread_mutex_unlock((pthread_mutex_t *)dynlock);
-+    }
-+
-+    OPENSSL_assert(ret == 0);
-+}
-+
-+static void
-+solaris_dynlock_destroy(struct CRYPTO_dynlock_value *dynlock,
-+    const char *file, int line)
-+{
-+    int ret;
-+    ret = pthread_mutex_destroy((pthread_mutex_t *)dynlock);
-+    OPENSSL_assert(ret);
-+}
-+
-+
-+/*
-+ * This function is called when a child process is forked to setup its own
-+ * global locking callback function ptr and mutexes.
-+ */
-+static void solaris_fork_child(void)
-+{
-+    /*
-+     * clear locking_callback to indicate that locks should
-+     * be reinitialized.
-+     */
-+    locking_callback = NULL;
-+    solaris_locking_setup();
-+}
-+
-+/*
-+ * This function allocates and initializes the global mutex array, and
-+ * sets the locking callback.
-+ */
-+void solaris_locking_setup()
-+{
-+    int i;
-+    int num_locks;
-+
-+    /* setup the dynlock callback if not already */
-+    if (dynlock_create_callback == NULL) {
-+        dynlock_create_callback = solaris_dynlock_create;
-+    }
-+    if (dynlock_lock_callback == NULL) {
-+        dynlock_lock_callback = solaris_dynlock_lock;
-+    }
-+    if (dynlock_destroy_callback == NULL) {
-+        dynlock_destroy_callback = solaris_dynlock_destroy;
-+    }
-+
-+    /* locking callback is already setup. Nothing to do */
-+    if (locking_callback != NULL) {
-+        return;
-+    }
-+
-+    /*
-+     * Set atfork handler so that child can setup its own mutexes and
-+     * locking callbacks when it is forked
-+     */
-+    (void) pthread_atfork(NULL, NULL, solaris_fork_child);
-+
-+    /* allocate locks needed by OpenSSL  */
-+    num_locks = CRYPTO_num_locks();
-+    solaris_openssl_locks =
-+        OPENSSL_malloc(sizeof (pthread_mutex_t) * num_locks);
-+    if (solaris_openssl_locks == NULL) {
-+        fprintf(stderr,
-+            "solaris_locking_setup: memory allocation failure.\n");
-+        abort();
-+    }
-+
-+    /* initialize openssl mutexes */
-+    for (i = 0; i < num_locks; i++) {
-+        pthread_mutex_init(&solaris_openssl_locks[i], NULL);
-+    }
-+    locking_callback = solaris_locking_callback;
-+
-+}
-+
- void CRYPTO_set_locking_callback(void (*func) (int mode, int type,
-                                                const char *file, int line))
- {
-@@ -410,7 +486,11 @@
-      * started.
-      */
-     OPENSSL_init();
--    locking_callback = func;
-+
-+    /*
-+     * we now setup our own locking callback and mutexes, and disallow
-+     * setting of another locking callback.
-+     */
- }
- 
- void CRYPTO_set_add_lock_callback(int (*func) (int *num, int mount, int type,
-@@ -471,9 +551,10 @@
- 
- int CRYPTO_THREADID_set_callback(void (*func) (CRYPTO_THREADID *))
- {
--    if (threadid_callback)
--        return 0;
--    threadid_callback = func;
-+    /*
-+     * Use the backup method (the address of 'errno') to identify the
-+     * thread and disallow setting the threadid callback.
-+     */
-     return 1;
- }
- 
-@@ -531,7 +611,10 @@
- 
- void CRYPTO_set_id_callback(unsigned long (*func) (void))
- {
--    id_callback = func;
-+    /*
-+     * Use the backup method to identify the thread/process.
-+     * Setting the id callback is disallowed.
-+     */
- }
- 
- unsigned long CRYPTO_thread_id(void)
---- openssl-1.0.1f/crypto/cryptlib.h.~1~	Fri Feb  7 10:41:42 2014
-+++ openssl-1.0.1f/crypto/cryptlib.h	Thu Feb  6 16:04:16 2014
-@@ -104,6 +104,8 @@
- void *OPENSSL_stderr(void);
- extern int OPENSSL_NONPIC_relocated;
- 
-+void solaris_locking_setup();
-+
- #ifdef  __cplusplus
- }
- #endif
---- openssl-1.0.1f/crypto/sparccpuid.S.~1~	Fri Feb  7 10:41:37 2014
-+++ openssl-1.0.1f/crypto/sparccpuid.S	Thu Feb  6 16:04:14 2014
-@@ -398,5 +398,7 @@
- .size	OPENSSL_cleanse,.-OPENSSL_cleanse
-
- .section	".init",#alloc,#execinstr
-+	call	solaris_locking_setup
-+	nop
- 	call	OPENSSL_cpuid_setup
- 	nop
---- openssl-1.0.1f/crypto/x86_64cpuid.pl.~1~	Wed Feb 12 13:20:09 2014
-+++ openssl-1.0.1f/crypto/x86_64cpuid.pl	Wed Feb 12 13:21:20 2014
-@@ -20,7 +20,10 @@
- print<<___;
- .extern		OPENSSL_cpuid_setup
- .hidden		OPENSSL_cpuid_setup
-+.extern		solaris_locking_setup
-+.hidden		solaris_locking_setup
- .section	.init
-+	call	solaris_locking_setup
- 	call	OPENSSL_cpuid_setup
- 
- .hidden	OPENSSL_ia32cap_P
---- openssl-1.0.1f/crypto/x86cpuid.pl.~1~	Wed Feb 12 13:38:03 2014
-+++ openssl-1.0.1f/crypto/x86cpuid.pl	Wed Feb 12 13:38:31 2014
-@@ -353,6 +353,7 @@
- 	&ret	();
- &function_end_B("OPENSSL_ia32_rdrand");
- 
-+&initseg("solaris_locking_setup");
- &initseg("OPENSSL_cpuid_setup");
- 
- &asm_finish();
--- a/components/openssl/openssl-1.0.1/patches/30_wanboot.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,486 +0,0 @@
-#
-# This patch file makes the changes neccessary to build wanboot-openssl.o
-# binary. This is Solaris-specific: not suitable for upstream.
-#
---- openssl-1.0.0g/Makefile.org    2010-01-27 08:06:58.000000000 -0800
-+++ openssl-1.0.0g-1/Makefile.org    2012-03-26 03:04:08.440194448 -0700
-@@ -138,7 +138,13 @@
-
- BASEADDR=
-
-+# For wanboot, we only need crypto and ssl.
-+# 'apps' are not patched to work in stand-alone environment anyway.
-+ifeq ($(PLATFORM), solaris64-sparcv9-cc-sunw-wanboot)
-+DIRS=   crypto ssl
-+else
- DIRS=   crypto ssl engines apps test tools
-+endif
- ENGDIRS= ccgost
- SHLIBDIRS= crypto ssl
-
---- openssl-1.0.0g/Makefile    2012-01-18 05:42:28.000000000 -0800
-+++ openssl-1.0.0g-1/Makefile    2012-03-26 03:03:59.170540344 -0700
-@@ -137,7 +137,13 @@
-
- BASEADDR=0xFB00000
-
-+# For wanboot, we only need crypto and ssl.
-+# 'apps' are not patched to work in stand-alone environment anyway.
-+ifeq ($(PLATFORM), solaris64-sparcv9-cc-sunw-wanboot)
-+DIRS=   crypto ssl
-+else
- DIRS=   crypto ssl engines apps test tools
-+endif
- ENGDIRS= ccgost
- SHLIBDIRS= crypto ssl
-
---- openssl-1.0.0e/crypto/cryptlib.c    2011-06-22 08:39:00.000000000 -0700
-+++ openssl-1.0.0e_patched/crypto/cryptlib.c    2011-12-12 06:17:45.422476900 -0800
-@@ -421,11 +421,13 @@
- static void solaris_locking_callback(int mode, int type, const char *file,
-     int line)
- {
-+#ifndef    _BOOT
-     if (mode & CRYPTO_LOCK) {
-         pthread_mutex_lock(&solaris_openssl_locks[type]);
-     } else {
-         pthread_mutex_unlock(&solaris_openssl_locks[type]);
-     }
-+#endif
- }
- 
- 
-@@ -435,6 +437,7 @@
- static struct CRYPTO_dynlock_value *
- solaris_dynlock_create(const char *file, int line)
- {
-+#ifndef    _BOOT
-     int                        ret;
-     pthread_mutex_t    *dynlock;
-
-@@ -447,6 +450,9 @@
-     OPENSSL_assert(ret);
-
-     return ((struct CRYPTO_dynlock_value *)dynlock);
-+#else
-+    return (NULL);
-+#endif
- }
-
- static void
-@@ -453,6 +459,7 @@
- solaris_dynlock_lock(int mode, struct CRYPTO_dynlock_value *dynlock,
-     const char *file, int line)
- {
-+#ifndef    _BOOT
-     int        ret;
- 
-     if (mode & CRYPTO_LOCK) {
-@@ -462,6 +469,7 @@
-     }
-
-     OPENSSL_assert(ret == 0);
-+#endif
- }
-
- static void
-@@ -468,9 +476,11 @@
- solaris_dynlock_destroy(struct CRYPTO_dynlock_value *dynlock,
-     const char *file, int line)
- {
-+#ifndef    _BOOT
-     int ret;
-     ret = pthread_mutex_destroy((pthread_mutex_t *)dynlock);
-     OPENSSL_assert(ret);
-+#endif
- }
-
-
-@@ -514,6 +524,12 @@
-     }
- 
-     /*
-+     * pthread_* can't be used in wanboot.
-+     * wanboot needs not be thread-safe and mutexes and locking callback
-+     * function will not be setup for wanboot.
-+     */
-+#ifndef    _BOOT
-+    /*
-      * Set atfork handler so that child can setup its own mutexes and
-      * locking callbacks when it is forked
-      */
-@@ -534,7 +550,7 @@
-         pthread_mutex_init(&solaris_openssl_locks[i], NULL);
-     }
-     locking_callback = solaris_locking_callback;
--
-+#endif
- }
- 
- void CRYPTO_set_locking_callback(void (*func) (int mode, int type,
-@@ -1084,6 +1100,12 @@
-         MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONSTOP);
- }
- #else
-+/*
-+ * Solaris libsa.a used for WAN boot doesn't provide for vfprintf(). Since
-+ * OPENSSL_showfatal() is not used anywhere else then here we can safely use
-+ * the code from 0.9.7d version.
-+ */
-+#ifndef    _BOOT
- void OPENSSL_showfatal(const char *fmta, ...)
- {
-     va_list ap;
-@@ -1092,6 +1114,7 @@
-     vfprintf(stderr, fmta, ap);
-     va_end(ap);
- }
-+#endif    /* _BOOT */
- 
- int OPENSSL_isservice(void)
- {
-@@ -1101,9 +1124,15 @@
- 
- void OpenSSLDie(const char *file, int line, const char *assertion)
- {
-+#ifndef    _BOOT        
-     OPENSSL_showfatal
-         ("%s(%d): OpenSSL internal error, assertion failed: %s\n", file, line,
-          assertion);
-+#else
-+    fprintf(stderr,
-+        "%s(%d): OpenSSL internal error, assertion failed: %s\n",
-+        file,line,assertion);
-+#endif    
- #if !defined(_WIN32) || defined(__CYGWIN__)
-     abort();
- #else
---- openssl-1.0.0e/crypto/err/err_all.c    2009-08-09 07:58:05.000000000 -0700
-+++ openssl-1.0.0e_patched/crypto/err/err_all.c    2011-12-13 05:22:01.205351400 -0800
-@@ -148,7 +148,9 @@
-     ERR_load_X509V3_strings();
-     ERR_load_PKCS12_strings();
-     ERR_load_RAND_strings();
-+#ifndef _BOOT
-     ERR_load_DSO_strings();
-+#endif /* _BOOT */
-     ERR_load_TS_strings();
- # ifndef OPENSSL_NO_ENGINE
-     ERR_load_ENGINE_strings();
---- openssl-1.0.0e/crypto/evp/evp_key.c    2010-03-27 12:27:50.000000000 -0700
-+++ openssl-1.0.0e_patched/crypto/evp/evp_key.c    2011-12-13 05:19:32.956908600 -0800
-@@ -83,7 +83,7 @@
-     else
-         return (prompt_string);
- }
--
-+#ifndef    _BOOT
- /*
-  * For historical reasons, the standard function for reading passwords is in
-  * the DES library -- if someone ever wants to disable DES, this function
-@@ -115,6 +115,7 @@
-     OPENSSL_cleanse(buff, BUFSIZ);
-     return ret;
- }
-+#endif    /* !_BOOT */
- 
- int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
-                    const unsigned char *salt, const unsigned char *data,
---- openssl-1.0.0e/crypto/rand/rand_unix.c    2009-04-06 07:31:36.000000000 -0700
-+++ openssl-1.0.0e_patched/crypto/rand/rand_unix.c    2011-12-19 07:28:39.988944800 -0800
-@@ -122,7 +122,11 @@
- # include <sys/time.h>
- # include <sys/times.h>
- # include <sys/stat.h>
-+#ifdef    _BOOT
-+# include <sys/fcntl.h>
-+#else
- # include <fcntl.h>
-+#endif
- # include <unistd.h>
- # include <time.h>
- # if defined(OPENSSL_SYS_LINUX) /* should actually be available virtually
-@@ -259,6 +263,11 @@
-     const char **egdsocket = NULL;
- #  endif
- 
-+#ifdef _BOOT
-+/* open() is provided by standalone libsa not visible from here */
-+extern int open(const char *, int);
-+#endif
-+
- #  ifdef DEVRANDOM
-     memset(randomstats, 0, sizeof(randomstats));
-     /*
-@@ -307,11 +316,15 @@
-             do {
-                 int try_read = 0;
-
--#   if defined(OPENSSL_SYS_BEOS_R5)
-+#   if defined(OPENSSL_SYS_BEOS_R5) || defined(_BOOT)
-                 /*
-                  * select() is broken in BeOS R5, so we simply try to read
-                  * something and snooze if we couldn't
-                  */
-+               /*
-+                * select() is not available when linking stand-alone
-+                * library for wanboot
-+                */
-                 try_read = 1;
- 
- #   elif defined(OPENSSL_SYS_LINUX)
-@@ -365,6 +378,7 @@
-                 } else
-                     r = -1;
-
-+#ifndef        _BOOT
-                 /*
-                  * Some Unixen will update t in select(), some won't.  For
-                  * those who won't, or if we didn't use select() in the first
-@@ -377,13 +391,17 @@
-             while ((r > 0 ||
-                     (errno == EINTR || errno == EAGAIN)) && usec != 0
-                    && n < ENTROPY_NEEDED);
-+#else  /* _BOOT */
-+            }
-+            while (r > 0 && n < ENTROPY_NEEDED);
-+#endif /* _BOOT */
-
-             close(fd);
-         }
-     }
- #  endif                        /* defined(DEVRANDOM) */
-
--#  ifdef DEVRANDOM_EGD
-+#  if defined(DEVRANDOM_EGD) && !defined(_BOOT)
-     /*
-      * Use an EGD socket to read entropy from an EGD or PRNGD entropy
-      * collecting daemon.
-@@ -407,6 +424,7 @@
-     }
- #  endif
- 
-+#ifndef    _BOOT
-     /* put in some default random data, we need more than just this */
-     l = curr_pid;
-     RAND_add(&l, sizeof(l), 0.0);
-@@ -415,6 +433,7 @@
- 
-     l = time(NULL);
-     RAND_add(&l, sizeof(l), 0.0);
-+#endif /* !_BOOT */    
- 
- #  if defined(OPENSSL_SYS_BEOS)
-     {
---- openssl-1.0.0e/crypto/rand/randfile.c    2011-03-19 02:44:37.000000000 -0700
-+++ openssl-1.0.0e_patched/crypto/rand/randfile.c    2011-12-13 05:26:51.884824200 -0800
-@@ -57,9 +57,11 @@
-  */
- 
- /* We need to define this to get macros like S_IFBLK and S_IFCHR */
-+#ifndef    _BOOT
- #if !defined(OPENSSL_SYS_VXWORKS)
- # define _XOPEN_SOURCE 500
- #endif
-+#endif    /* _BOOT */
- 
- #include <errno.h>
- #include <stdio.h>
-@@ -191,6 +193,7 @@
-     return (ret);
- }
- 
-+#ifndef    _BOOT
- int RAND_write_file(const char *file)
- {
-     unsigned char buf[BUFSIZE];
-@@ -335,3 +338,5 @@
- #endif
-     return (buf);
- }
-+
-+#endif /* _BOOT */
---- openssl-1.0.0e/crypto/x509v3/v3_utl.c    2009-07-27 14:08:53.000000000 -0700
-+++ openssl-1.0.0e_patched/crypto/x509v3/v3_utl.c    2011-12-13 05:10:08.844191400 -0800
-@@ -715,9 +715,50 @@
-     }
- }
- 
-+#if    defined(_BOOT)
-+/* This function was copied from bio/b_sock.c */
-+static int get_ip(const char *str, unsigned char ip[4])
-+{
-+    unsigned int tmp[4];
-+    int num = 0, c, ok = 0;
-+
-+    tmp[0]=tmp[1]=tmp[2]=tmp[3]=0;
-+
-+    for (;;) {
-+        c = *(str++);
-+        if ((c >= '0') && (c <= '9')) {
-+            ok = 1;
-+            tmp[num] = tmp[num]*10+c-'0';
-+            if (tmp[num] > 255)
-+                return(0);
-+        } else if (c == '.') {
-+            if (!ok)
-+                return (-1);
-+            if (num == 3)
-+                return (0);
-+            num++;
-+            ok = 0;
-+        } else if (c == '\0' && (num == 3) && ok)
-+            break;
-+        else
-+            return(0);
-+        }
-+    ip[0]=tmp[0];
-+    ip[1]=tmp[1];
-+    ip[2]=tmp[2];
-+    ip[3]=tmp[3];
-+    return(1);
-+}
-+#endif /* _BOOT */
-+
- static int ipv4_from_asc(unsigned char *v4, const char *in)
- {
-     int a0, a1, a2, a3;
-+
-+#if    defined(_BOOT)
-+    if (get_ip(in, v4) != 1)
-+        return 0;
-+#else    /* _BOOT */
-     if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4)
-         return 0;
-     if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255)
-@@ -727,6 +768,7 @@
-     v4[1] = a1;
-     v4[2] = a2;
-     v4[3] = a3;
-+#endif    /* _BOOT */
-     return 1;
- }
-
---- openssl-1.0.0e/e_os.h    2011-12-19 04:17:51.631087400 -0800
-+++ openssl-1.0.0e_patched/e_os.h    2011-12-19 04:15:15.776668900 -0800
-@@ -213,10 +213,19 @@
- #  define get_last_socket_error() errno
- #  define clear_socket_error()    errno=0
- #  define ioctlsocket(a,b,c)      ioctl(a,b,c)
-+#ifdef    _BOOT
-+#include <netinet/in.h>
-+extern int socket_read(int, void *, size_t, int);
-+extern int socket_close(int);
-+#  define closesocket(s)          socket_close(s)
-+#  define readsocket(s,b,n)       socket_read((s),(b),(n), 200)
-+#  define writesocket(s,b,n)      send((s),(b),(n), 0)
-+#else  /* !_BOOT */
- #  define closesocket(s)          close(s)
- #  define readsocket(s,b,n)       read((s),(b),(n))
- #  define writesocket(s,b,n)      write((s),(b),(n))
- # endif
-+#endif
- 
- # ifdef WIN16                   /* never the case */
- #  define MS_CALLBACK   _far _loadds
---- openssl-1.0.0e/crypto/sparcv9cap.c	2010-09-05 12:48:01.000000000 -0700
-+++ openssl-1.0.0e_patched/crypto/sparcv9cap.c	2011-12-23 05:24:02.011607700 -0800
-@@ -12,7 +12,11 @@
- #define SPARCV9_VIS2            (1<<3) /* reserved */
- #define SPARCV9_FMADD           (1<<4) /* reserved for SPARC64 V */
- 
-+#ifndef        _BOOT
- static int OPENSSL_sparcv9cap_P = SPARCV9_TICK_PRIVILEGED;
-+#else
-+static int OPENSSL_sparcv9cap_P = SPARCV9_VIS1;
-+#endif
- 
- 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)
-@@ -36,6 +40,7 @@
- void _sparcv9_vis2_probe(void);
- void _sparcv9_fmadd_probe(void);
- 
-+#ifndef _BOOT
- unsigned long OPENSSL_rdtsc(void)
- {
-     if (OPENSSL_sparcv9cap_P & SPARCV9_TICK_PRIVILEGED)
-@@ -47,8 +52,19 @@
-     else
-         return _sparcv9_rdtick();
- }
-+#endif
-+
-+#if defined(_BOOT)
-+/*
-+ * Hardcoding sparc capabilities for wanboot.
-+ * Older CPUs are EOLed anyway.
-+ */
-+void OPENSSL_cpuid_setup(void)
-+       {
-+       OPENSSL_sparcv9cap_P = SPARCV9_VIS1;
-+       }
-
--#if 0 && defined(__sun) && defined(__SVR4)
-+#elif 0 && defined(__sun) && defined(__SVR4)
- /*
-  * This code path is disabled, because of incompatibility of libdevinfo.so.1
-  * and libmalloc.so.1 (see below for details)
---- openssl-1.0.0e/crypto/sparccpuid.S	2010-09-05 12:48:01.000000000 -0700
-+++ openssl-1.0.0e_patched/crypto/sparccpuid.S	2012-02-13 07:42:58.259478325 -0800
-@@ -397,8 +397,13 @@
- .type	OPENSSL_cleanse,#function
- .size	OPENSSL_cleanse,.-OPENSSL_cleanse
- 
-+#ifndef _BOOT
- .section	".init",#alloc,#execinstr
- 	call	solaris_locking_setup
- 	nop
- 	call	OPENSSL_cpuid_setup
- 	nop
-+#else
-+	nop
-+	nop
-+#endif
---- openssl-1.0.1c/crypto/Makefile      Thu Aug  2 12:56:38 2012
-+++ openssl-1.0.1c/crypto/Makefile.new  Thu Aug  2 12:59:43 2012
-@@ -36,9 +36,9 @@
- LIB= $(TOP)/libcrypto.a
- SHARED_LIB= libcrypto$(SHLIB_EXT)
- LIBSRC=	cryptlib.c mem.c mem_clr.c mem_dbg.c cversion.c ex_data.c cpt_err.c \
--	ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fips.c o_init.c fips_ers.c
-+	ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fips.c o_init.c fips_ers.c wanboot-stubs.c
- LIBOBJ= cryptlib.o mem.o mem_dbg.o cversion.o ex_data.o cpt_err.o ebcdic.o \
--	uid.o o_time.o o_str.o o_dir.o o_fips.o o_init.o fips_ers.o $(CPUID_OBJ)
-+	uid.o o_time.o o_str.o o_dir.o o_fips.o o_init.o fips_ers.o wanboot-stubs.o $(CPUID_OBJ)
-
- SRC= $(LIBSRC)
-
---- openssl-1.0.1f/ssl/s3_clnt.c    Thu Jan 30 02:53:33 2014
-+++ openssl-1.0.1f/ssl/s3_clnt.c.new   Thu Jan 30 02:57:51 2014
-@@ -668,7 +668,11 @@
- 
-         p = s->s3->client_random;
-
-+#ifndef    _BOOT
-         if (ssl_fill_hello_random(s, 0, p, SSL3_RANDOM_SIZE) <= 0)
-+#else
-+        if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE) <= 0)
-+#endif
-             goto err;
- 
-         /* Do the message type and length last */
---- openssl-1.0.1f/ssl/s3_lib.c       Wed Oct 15 11:18:30 2014
-+++ openssl-1.0.1f/ssl/s3_lib.c.new    Wed Oct 15 11:20:07 2014
-@@ -3343,7 +3343,11 @@
-          * Apparently we're using a version-flexible SSL_METHOD (not at its
-          * highest protocol version).
-          */
-+#ifndef    _BOOT
-         if (s->ctx->method->version == SSLv23_method()->version) {
-+#else
-+        if (s->ctx->method->version == TLS1_2_VERSION) {
-+#endif
- #if TLS_MAX_VERSION != TLS1_2_VERSION
- # error Code needs update for SSLv23_method() support beyond TLS1_2_VERSION.
- #endif
--- a/components/openssl/openssl-1.0.1/patches/32_aes_cbc_len_check.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-#
-# This was developed in house and reported to the upstream.
-#
---- openssl-1.0.1e/crypto/evp/e_aes.c        Tue Jul  2 11:03:12 2013
-+++ openssl-1.0.1e/crypto/evp/e_aes.c.new    Tue Jul  2 11:04:56 2013
-@@ -536,8 +536,12 @@
- static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-                           const unsigned char *in, size_t len)
- {
-+    size_t	bl = ctx->cipher->block_size;
-     EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data;
- 
-+    if (len < bl)
-+        return 1;
-+
-     if (dat->stream.cbc)
-         (*dat->stream.cbc) (in, out, len, &dat->ks, ctx->iv, ctx->encrypt);
-     else if (ctx->encrypt)
--- a/components/openssl/openssl-1.0.1/patches/33_cert_chain.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +0,0 @@
-This patch comes from OpenSSL upstream code, and the change has been commited to OpenSSL 1.0.2.
-  http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=fbd2164044f92383955a801ad1b2857d71e83f27
-  http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=51e7a4378a78bb0870a2cdc5c524c230c929ebcb
-  http://git.openssl.org/gitweb/?p=openssl.git;a=commit;h=2dabd822366df7b2608b55d5ca5f31d5d484cbaf
-
-Index: openssl/crypto/x509/x509_trs.c
-============================================================================
-$ diff -ru crypto/x509/x509_trs.c crypto/x509/x509_trs.c 
---- openssl/crypto/x509/x509_trs.c.orig    4 Dec 2012 17:26:04 -0000    1.133.2.11.2.6.2.3
-+++ openssl/crypto/x509/x509_trs.c    14 Dec 2012 14:30:45 -0000    1.133.2.11.2.6.2.4
-@@ -119,6 +119,14 @@ int X509_check_trust(X509 *x, int id, int flags)
-     int idx;
-     if (id == -1)
-         return 1;
-+    /* We get this as a default value */
-+    if (id == 0) {
-+        int rv;
-+        rv = obj_trust(NID_anyExtendedKeyUsage, x, 0);
-+        if (rv != X509_TRUST_UNTRUSTED)
-+            return rv;
-+        return trust_compat(NULL, x, 0);
-+    }
-     idx = X509_TRUST_get_by_id(id);
-     if (idx == -1)
-         return default_trust(id, x, flags);
-Index: openssl/crypto/x509/x509_vfy.c
-============================================================================
-$ cvs diff -u -r1.105.2.9.2.4.2.3 -r1.105.2.9.2.4.2.4 x509_vfy.c
---- openssl/crypto/x509/x509_vfy.c    14 Dec 2012 12:53:48 -0000    1.105.2.9.2.4.2.3
-+++ openssl/crypto/x509/x509_vfy.c    14 Dec 2012 14:30:46 -0000    1.105.2.9.2.4.2.4
-@@ -149,6 +149,33 @@
- }
- #endif
- 
-+/* Given a certificate try and find an exact match in the store */
-+
-+static X509 *lookup_cert_match(X509_STORE_CTX *ctx, X509 *x)
-+    {
-+    STACK_OF(X509) *certs;
-+    X509 *xtmp = NULL;
-+    int i;
-+    /* Lookup all certs with matching subject name */
-+    certs = ctx->lookup_certs(ctx, X509_get_subject_name(x));
-+    if (certs == NULL)
-+        return NULL;
-+    /* Look for exact match */
-+    for (i = 0; i < sk_X509_num(certs); i++)
-+        {
-+        xtmp = sk_X509_value(certs, i);
-+        if (!X509_cmp(xtmp, x))
-+            break;
-+        }
-+    if (i < sk_X509_num(certs))
-+        CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509);
-+    else
-+        xtmp = NULL;
-+    sk_X509_pop_free(certs, X509_free);
-+    return xtmp;
-+    }
-+
-+
- int X509_verify_cert(X509_STORE_CTX *ctx)
- {
-     X509 *x, *xtmp, *xtmp2, *chain_ss = NULL;
-@@ -304,8 +331,17 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
-         }
-     } while (retry);
- 
--    /* Is last certificate looked up self signed? */
--    if (!ctx->check_issued(ctx, x, x)) {
-+    i = check_trust(ctx);
-+
-+    /* If explicitly rejected error */
-+    if (i == X509_TRUST_REJECTED)
-+        goto end;
-+    /*
-+     * If not explicitly trusted then indicate error unless it's a single
-+     * self signed certificate in which case we've indicated an error already
-+     * and set bad_chain == 1
-+     */
-+    if (i != X509_TRUST_TRUSTED && !bad_chain) {
-         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;
-@@ -340,14 +376,6 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
-     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 */
-@@ -630,28 +658,53 @@ static int check_name_constraints(X509_STORE_CTX *ctx)
- 
- static int check_trust(X509_STORE_CTX *ctx)
- {
--#ifdef OPENSSL_NO_CHAIN_VERIFY
--    return 1;
--#else
-     int i, ok;
--    X509 *x;
-+    X509 *x = NULL;
-     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
-+    /* Check all trusted certificates in chain */
-+    for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++) {
-+        x = sk_X509_value(ctx->chain, i);
-+        ok = X509_check_trust(x, ctx->param->trust, 0);
-+        /* If explicitly trusted return trusted */
-+        if (ok == X509_TRUST_TRUSTED)
-+            return X509_TRUST_TRUSTED;
-+        /*
-+         * If explicitly rejected notify callback and reject if not
-+         * overridden.
-+         */
-+        if (ok == X509_TRUST_REJECTED) {
-+            ctx->error_depth = i;
-+            ctx->current_cert = x;
-+            ctx->error = X509_V_ERR_CERT_REJECTED;
-+            ok = cb(0, ctx);
-+            if (!ok)
-+                return X509_TRUST_REJECTED;
-+        }
-+    }
-+    /*
-+     * If we accept partial chains and have at least one trusted certificate
-+     * return success.
-+     */
-+    if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN) {
-+        X509 *mx;
-+        if (ctx->last_untrusted < sk_X509_num(ctx->chain))
-+            return X509_TRUST_TRUSTED;
-+        x = sk_X509_value(ctx->chain, 0);
-+        mx = lookup_cert_match(ctx, x);
-+        if (mx) {
-+            (void)sk_X509_set(ctx->chain, 0, mx);
-+            X509_free(x);
-+            ctx->last_untrusted = 0;
-+            return X509_TRUST_TRUSTED;
-+        }
-+    }
-+
-+    /*
-+     * If no trusted certs in chain at all return untrusted and allow
-+     * standard (no issuer cert) etc errors to be indicated.
-+     */
-+    return X509_TRUST_UNTRUSTED;
- }
- 
- static int check_revocation(X509_STORE_CTX *ctx)
-@@ -1526,6 +1579,8 @@ static int internal_verify(X509_STORE_CTX *ctx)
-     if (ctx->check_issued(ctx, xi, xi))
-         xs = xi;
-     else {
-+        if (ctx->param->flags & X509_V_FLAG_PARTIAL_CHAIN && n == 0)
-+            return check_cert_time(ctx, xi);
-         if (n <= 0) {
-             ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE;
-             ctx->current_cert = xi;
-Index: openssl/crypto/x509/x509_vfy.h
-============================================================================
-$ cvs diff -u -r1.67.2.3.4.1 -r1.67.2.3.4.2 x509_vfy.h
---- openssl/crypto/x509/x509_vfy.h    26 Sep 2012 13:50:42 -0000    1.67.2.3.4.1
-+++ openssl/crypto/x509/x509_vfy.h    14 Dec 2012 14:30:46 -0000    1.67.2.3.4.2
-@@ -412,6 +412,9 @@
-  */
- # define X509_V_FLAG_NO_ALT_CHAINS               0x100000
- 
-+/* Allow partial chains if at least one certificate is in trusted store */
-+# define X509_V_FLAG_PARTIAL_CHAIN               0x80000
-+
- # define X509_VP_FLAG_DEFAULT                    0x1
- # define X509_VP_FLAG_OVERWRITE                  0x2
- # define X509_VP_FLAG_RESET_FLAGS                0x4
-Index: openssl/apps/apps.c
-============================================================================
-$ cvs diff -u -r1.133.2.11.2.6.2.3 -r1.133.2.11.2.6.2.4 apps.c
---- openssl/apps/apps.c    4 Dec 2012 17:26:04 -0000    1.133.2.11.2.6.2.3
-+++ openssl/apps/apps.c    14 Dec 2012 14:30:45 -0000    1.133.2.11.2.6.2.4
-@@ -2238,6 +2238,8 @@
-         flags |= X509_V_FLAG_NOTIFY_POLICY;
-     else if (!strcmp(arg, "-check_ss_sig"))
-         flags |= X509_V_FLAG_CHECK_SS_SIGNATURE;
-+    else if (!strcmp(arg, "-partial_chain"))
-+        flags |= X509_V_FLAG_PARTIAL_CHAIN;
-     else if (!strcmp(arg, "-no_alt_chains"))
-         flags |= X509_V_FLAG_NO_ALT_CHAINS;
-     else
--- a/components/openssl/openssl-1.0.1/patches/36_evp_leak.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,144 +0,0 @@
-Patch developed in-house.  Solaris-specific; not suitable for upstream.
-
---- openssl-1.0.1f/crypto/evp/evp_enc.c.orig    Mon Feb 11 07:26:04 2013
-+++ openssl-1.0.1f/crypto/evp/evp_enc.c    Mon Feb  3 16:40:48 2014
-@@ -379,11 +379,13 @@
-
-     if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
-         ret = M_do_cipher(ctx, out, NULL, 0);
--        if (ret < 0)
--            return 0;
--        else
-+        if (ret < 0) {
-+            ret = 0;
-+            goto cleanup;
-+        } else
-             *outl = ret;
--        return 1;
-+        ret = 1;
-+        goto cleanup;
-     }
-
-     b = ctx->cipher->block_size;
-@@ -390,7 +392,8 @@
-     OPENSSL_assert(b <= sizeof ctx->buf);
-     if (b == 1) {
-         *outl = 0;
--        return 1;
-+        ret = 1;
-+        goto cleanup;
-     }
-     bl = ctx->buf_len;
-     if (ctx->flags & EVP_CIPH_NO_PADDING) {
-@@ -397,10 +400,12 @@
-         if (bl) {
-             EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX,
-                    EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
--            return 0;
-+            ret = 0;
-+            goto cleanup;
-         }
-         *outl = 0;
--        return 1;
-+        ret = 1;
-+        goto cleanup;
-     }
- 
-     n = b - bl;
-@@ -411,6 +416,11 @@
-     if (ret)
-         *outl = b;
- 
-+cleanup:
-+    if (ctx->cipher->cleanup) {
-+        ctx->cipher->cleanup(ctx);
-+    }
-+
-     return ret;
- }
- 
-@@ -478,6 +488,7 @@
- int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
- {
-     int i, n;
-+    int err = 1;
-     unsigned int b;
-     *outl = 0;
- 
-@@ -483,11 +494,13 @@
-
-     if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) {
-         i = M_do_cipher(ctx, out, NULL, 0);
--        if (i < 0)
--            return 0;
--        else
-+        if (i < 0) {
-+            err = 0;
-+            goto cleanup;
-+        } else
-             *outl = i;
--        return 1;
-+        err = 1;
-+        goto cleanup;
-     }
-
-     b = ctx->cipher->block_size;
-@@ -495,10 +508,12 @@
-         if (ctx->buf_len) {
-             EVPerr(EVP_F_EVP_DECRYPTFINAL_EX,
-                    EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
--            return 0;
-+            err = 0;
-+            goto cleanup;
-         }
-         *outl = 0;
--        return 1;
-+        err = 1;
-+        goto cleanup;
-     }
-     if (b > 1) {
-         if (ctx->buf_len || !ctx->final_used) {
-@@ -503,7 +518,8 @@
-     if (b > 1) {
-         if (ctx->buf_len || !ctx->final_used) {
-             EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_WRONG_FINAL_BLOCK_LENGTH);
--            return (0);
-+            err = 0;
-+            goto cleanup;
-         }
-         OPENSSL_assert(b <= sizeof ctx->final);
- 
-@@ -514,7 +530,8 @@
-         n = ctx->final[b - 1];
-         if (n == 0 || n > (int)b) {
-             EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT);
--            return (0);
-+            err = 0;
-+            goto cleanup;
-         }
-         for (i = 0; i < n; i++) {
-             if (ctx->final[--b] != n) {
-@@ -519,7 +536,8 @@
-         for (i = 0; i < n; i++) {
-             if (ctx->final[--b] != n) {
-                 EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT);
--                return (0);
-+                err = 0;
-+                goto cleanup;
-             }
-         }
-         n = ctx->cipher->block_size - n;
-@@ -528,7 +546,12 @@
-         *outl = n;
-     } else
-         *outl = 0;
--    return (1);
-+    err = 1;
-+cleanup:
-+    if (ctx->cipher->cleanup) {
-+        ctx->cipher->cleanup(ctx);
-+    }
-+    return err;
- }
- 
- void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx)
--- a/components/openssl/openssl-1.0.1/patches/37_openssl_t4_inline.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2276 +0,0 @@
-#
-# This file adds inline T4 instruction support to OpenSSL upstream code.
-# The change was brought in from OpenSSL 1.0.2.
-#
-Index: Configure
-===================================================================
-diff -ru openssl-1.0.1e/Configure openssl-1.0.1e/Configure
---- openssl-1.0.1e/Configure 2011-05-24 17:02:24.000000000 -0700
-+++ openssl-1.0.1e/Configure 2011-07-27 10:48:17.817470000 -0700
-@@ -135,7 +135,7 @@
-
- my $x86_64_asm="x86_64cpuid.o:x86_64-gcc.o x86_64-mont.o x86_64-mont5.o x86_64-gf2m.o modexp512-x86_64.o::aes-x86_64.o vpaes-x86_64.o bsaes-x86_64.o aesni-x86_64.o aesni-sha1-x86_64.o::md5-x86_64.o:sha1-x86_64.o sha256-x86_64.o sha512-x86_64.o::rc4-x86_64.o rc4-md5-x86_64.o:::wp-x86_64.o:cmll-x86_64.o cmll_misc.o:ghash-x86_64.o:";
- my $ia64_asm="ia64cpuid.o:bn-ia64.o ia64-mont.o::aes_core.o aes_cbc.o aes-ia64.o::md5-ia64.o:sha1-ia64.o sha256-ia64.o sha512-ia64.o::rc4-ia64.o rc4_skey.o:::::ghash-ia64.o::void";
--my $sparcv9_asm="sparcv9cap.o sparccpuid.o:bn-sparcv9.o sparcv9-mont.o sparcv9a-mont.o:des_enc-sparc.o fcrypt_b.o:aes_core.o aes_cbc.o aes-sparcv9.o:::sha1-sparcv9.o sha256-sparcv9.o sha512-sparcv9.o:::::::ghash-sparcv9.o::void";
-+my $sparcv9_asm="sparcv9cap.o sparccpuid.o:bn-sparcv9.o sparcv9-mont.o sparcv9a-mont.o vis3-mont.o sparct4-mont.o sparcv9-gf2m.o:des_enc-sparc.o fcrypt_b.o dest4-sparcv9.o:aes_core.o aes_cbc.o aes-sparcv9.o aest4-sparcv9.o::md5-sparcv9.o:sha1-sparcv9.o sha256-sparcv9.o sha512-sparcv9.o:::::::ghash-sparcv9.o::void";
- my $sparcv8_asm=":sparcv8.o:des_enc-sparc.o fcrypt_b.o:::::::::::::void";
- my $alpha_asm="alphacpuid.o:bn_asm.o alpha-mont.o:::::sha1-alpha.o:::::::ghash-alpha.o::void";
- my $mips32_asm=":bn-mips.o::aes_cbc.o aes-mips.o:::sha1-mips.o sha256-mips.o::::::::";
-Index: crypto/sparccpuid.S
-===================================================================
-diff -ru openssl-1.0.1e/crypto/sparccpuid.S openssl-1.0.1e/crypto/sparccpuid.S
---- openssl-1.0.1e/crypto/sparccpuid.S 2011-05-24 17:02:24.000000000 -0700
-+++ openssl-1.0.1e/crypto/sparccpuid.S 2011-07-27 10:48:17.817470000 -0700
-@@ -1,3 +1,7 @@
-+#ifdef OPENSSL_FIPSCANISTER
-+#include <openssl/fipssyms.h>
-+#endif
-+
- #if defined(__SUNPRO_C) && defined(__sparcv9)
- # define ABI64  /* They've said -xarch=v9 at command line */
- #elif defined(__GNUC__) && defined(__arch64__)
-@@ -235,10 +239,10 @@
- .global	_sparcv9_vis1_probe
- .align	8
- _sparcv9_vis1_probe:
-+	.word	0x81b00d80	!fxor	%f0,%f0,%f0
- 	add	%sp,BIAS+2,%o1
--	.word	0xc19a5a40	!ldda	[%o1]ASI_FP16_P,%f0
- 	retl
--	.word	0x81b00d80	!fxor	%f0,%f0,%f0
-+	.word	0xc19a5a40	!ldda	[%o1]ASI_FP16_P,%f0
- .type	_sparcv9_vis1_probe,#function
- .size	_sparcv9_vis1_probe,.-_sparcv9_vis1_probe
- 
-@@ -251,7 +255,12 @@
- !	UltraSPARC IIe		7
- !	UltraSPARC III		7
- !	UltraSPARC T1		24
-+!	SPARC T4		65(*)
- !
-+! (*)	result has lesser to do with VIS instruction latencies, rdtick
-+!	appears that slow, but it does the trick in sense that FP and
-+!	VIS code paths are still slower than integer-only ones.
-+!
- ! Numbers for T2 and SPARC64 V-VII are more than welcomed.
- !
- ! It would be possible to detect specifically US-T1 by instrumenting
-@@ -260,6 +269,8 @@
- .global	_sparcv9_vis1_instrument
- .align	8
- _sparcv9_vis1_instrument:
-+	.word	0x81b00d80	!fxor	%f0,%f0,%f0
-+	.word	0x85b08d82	!fxor	%f2,%f2,%f2
- 	.word	0x91410000	!rd	%tick,%o0
- 	.word	0x81b00d80	!fxor	%f0,%f0,%f0
- 	.word	0x85b08d82	!fxor	%f2,%f2,%f2
-@@ -314,6 +325,30 @@
- .type	_sparcv9_fmadd_probe,#function
- .size	_sparcv9_fmadd_probe,.-_sparcv9_fmadd_probe
- 
-+.global	_sparcv9_rdcfr
-+.align	8
-+_sparcv9_rdcfr:
-+	retl
-+	.word	0x91468000	!rd	%asr26,%o0
-+.type	_sparcv9_rdcfr,#function
-+.size	_sparcv9_rdcfr,.-_sparcv9_rdcfr
-+
-+.global	_sparcv9_vis3_probe
-+.align	8
-+_sparcv9_vis3_probe:
-+	retl
-+	.word	0x81b022a0	!xmulx	%g0,%g0,%g0
-+.type	_sparcv9_vis3_probe,#function
-+.size	_sparcv9_vis3_probe,.-_sparcv9_vis3_probe
-+
-+.global	_sparcv9_random
-+.align	8
-+_sparcv9_random:
-+	retl
-+	.word	0x91b002a0	!random	%o0
-+.type	_sparcv9_random,#function
-+.size	_sparcv9_random,.-_sparcv9_vis3_probe
-+
- .global	OPENSSL_cleanse
- .align	32
- OPENSSL_cleanse:
-@@ -398,6 +433,102 @@
- .size	OPENSSL_cleanse,.-OPENSSL_cleanse
- 
- #ifndef _BOOT
-+.global	_sparcv9_vis1_instrument_bus
-+.align	8
-+_sparcv9_vis1_instrument_bus:
-+    mov    %o1,%o3                    ! save cnt
-+    .word    0x99410000    !rd    %tick,%o4    ! tick
-+    mov    %o4,%o5                    ! lasttick = tick
-+    set    0,%g4                    ! diff
-+
-+    andn    %o0,63,%g1
-+    .word    0xc1985e00    !ldda    [%g1]0xf0,%f0    ! block load
-+    .word    0x8143e040    !membar    #Sync
-+    .word    0xc1b85c00    !stda    %f0,[%g1]0xe0    ! block store and commit
-+    .word    0x8143e040    !membar    #Sync
-+    ld    [%o0],%o4
-+    add    %o4,%g4,%g4
-+    .word    0xc9e2100c    !cas    [%o0],%o4,%g4
-+
-+.Loop:    .word    0x99410000    !rd    %tick,%o4
-+    sub    %o4,%o5,%g4                ! diff=tick-lasttick
-+    mov    %o4,%o5                    ! lasttick=tick
-+
-+    andn    %o0,63,%g1
-+    .word    0xc1985e00    !ldda    [%g1]0xf0,%f0    ! block load
-+    .word    0x8143e040    !membar    #Sync
-+    .word    0xc1b85c00    !stda    %f0,[%g1]0xe0    ! block store and commit
-+    .word    0x8143e040    !membar    #Sync
-+    ld    [%o0],%o4
-+    add    %o4,%g4,%g4
-+    .word    0xc9e2100c    !cas    [%o0],%o4,%g4
-+    subcc    %o1,1,%o1                ! --$cnt
-+    bnz    .Loop
-+    add    %o0,4,%o0                ! ++$out
-+
-+    retl
-+    mov    %o3,%o0
-+.type    _sparcv9_vis1_instrument_bus,#function
-+.size    _sparcv9_vis1_instrument_bus,.-_sparcv9_vis1_instrument_bus
-+
-+.global    _sparcv9_vis1_instrument_bus2
-+.align    8
-+_sparcv9_vis1_instrument_bus2:
-+    mov    %o1,%o3                    ! save cnt
-+    sll    %o1,2,%o1                ! cnt*=4
-+
-+    .word    0x99410000    !rd    %tick,%o4    ! tick
-+    mov    %o4,%o5                    ! lasttick = tick
-+    set    0,%g4                    ! diff
-+
-+    andn    %o0,63,%g1
-+    .word    0xc1985e00    !ldda    [%g1]0xf0,%f0    ! block load
-+    .word    0x8143e040    !membar    #Sync
-+    .word    0xc1b85c00    !stda    %f0,[%g1]0xe0    ! block store and commit
-+    .word    0x8143e040    !membar    #Sync
-+    ld    [%o0],%o4
-+    add    %o4,%g4,%g4
-+    .word    0xc9e2100c    !cas    [%o0],%o4,%g4
-+
-+    .word    0x99410000    !rd    %tick,%o4    ! tick
-+    sub    %o4,%o5,%g4                ! diff=tick-lasttick
-+    mov    %o4,%o5                    ! lasttick=tick
-+    mov    %g4,%g5                    ! lastdiff=diff
-+.Loop2:
-+    andn    %o0,63,%g1
-+    .word    0xc1985e00    !ldda    [%g1]0xf0,%f0    ! block load
-+    .word    0x8143e040    !membar    #Sync
-+    .word    0xc1b85c00    !stda    %f0,[%g1]0xe0    ! block store and commit
-+    .word    0x8143e040    !membar    #Sync
-+    ld    [%o0],%o4
-+    add    %o4,%g4,%g4
-+    .word    0xc9e2100c    !cas    [%o0],%o4,%g4
-+
-+    subcc    %o2,1,%o2                ! --max
-+    bz    .Ldone2
-+    nop
-+
-+    .word    0x99410000    !rd    %tick,%o4    ! tick
-+    sub    %o4,%o5,%g4                ! diff=tick-lasttick
-+    mov    %o4,%o5                    ! lasttick=tick
-+    cmp    %g4,%g5
-+    mov    %g4,%g5                    ! lastdiff=diff
-+
-+    .word    0x83408000    !rd    %ccr,%g1
-+    and    %g1,4,%g1                ! isolate zero flag
-+    xor    %g1,4,%g1                ! flip zero flag
-+
-+    subcc    %o1,%g1,%o1                ! conditional --$cnt
-+    bnz    .Loop2
-+    add    %o0,%g1,%o0                ! conditional ++$out
-+
-+.Ldone2:
-+    srl    %o1,2,%o1
-+    retl
-+    sub    %o3,%o1,%o0
-+.type    _sparcv9_vis1_instrument_bus2,#function
-+.size    _sparcv9_vis1_instrument_bus2,.-_sparcv9_vis1_instrument_bus2
-+
- .section	".init",#alloc,#execinstr
- 	call	solaris_locking_setup
- 	nop
-Index: crypto/sparcv9cap.c
-===================================================================
-diff -ru openssl-1.0.1e/crypto/sparcv9cap.c openssl-1.0.1e/crypto/sparcv9cap.c
---- openssl-1.0.1e/crypto/sparcv9cap.c 2011-05-24 17:02:24.000000000 -0700
-+++ openssl-1.0.1e/crypto/sparcv9cap.c 2011-07-27 10:48:17.817470000 -0700
-@@ -4,34 +4,58 @@
- #include <setjmp.h>
- #include <signal.h>
- #include <sys/time.h>
-+#include <unistd.h>
- #include <openssl/bn.h>
- 
--#define SPARCV9_TICK_PRIVILEGED (1<<0)
--#define SPARCV9_PREFER_FPU      (1<<1)
--#define SPARCV9_VIS1            (1<<2)
--#define SPARCV9_VIS2            (1<<3) /* reserved */
--#define SPARCV9_FMADD           (1<<4) /* reserved for SPARC64 V */
-+#include "sparc_arch.h"
- 
-+#if defined(__GNUC__) && defined(__linux)
-+__attribute__((visibility("hidden")))
-+#endif
- #ifndef        _BOOT
--static int OPENSSL_sparcv9cap_P = SPARCV9_TICK_PRIVILEGED;
-+unsigned int OPENSSL_sparcv9cap_P[2] = {SPARCV9_TICK_PRIVILEGED, 0};
- #else
--static int OPENSSL_sparcv9cap_P = SPARCV9_VIS1;
-+unsigned int OPENSSL_sparcv9cap_P[2] = {SPARCV9_VIS1, 0};
- #endif
- 
- 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)
- {
-+    int bn_mul_mont_vis3(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
-+                         const BN_ULONG *np,const BN_ULONG *n0, int num);
-     int bn_mul_mont_fpu(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
-                         const BN_ULONG *np, const BN_ULONG *n0, int num);
-     int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
-                         const BN_ULONG *np, const BN_ULONG *n0, int num);
- 
--    if (num >= 8 && !(num & 1) &&
--        (OPENSSL_sparcv9cap_P & (SPARCV9_PREFER_FPU | SPARCV9_VIS1)) ==
--        (SPARCV9_PREFER_FPU | SPARCV9_VIS1))
--        return bn_mul_mont_fpu(rp, ap, bp, np, n0, num);
--    else
--        return bn_mul_mont_int(rp, ap, bp, np, n0, num);
-+    if (!(num&1) && num>=6) {
-+        if ((num&15)==0 && num<=64 &&
-+            (OPENSSL_sparcv9cap_P[1]&(CFR_MONTMUL|CFR_MONTSQR))== 
-+                             (CFR_MONTMUL|CFR_MONTSQR))
-+            {
-+            typedef int (*bn_mul_mont_f)(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0);
-+            int bn_mul_mont_t4_8(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0);
-+            int bn_mul_mont_t4_16(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0);
-+            int bn_mul_mont_t4_24(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0);
-+            int bn_mul_mont_t4_32(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0);
-+            static const bn_mul_mont_f funcs[4] = {
-+                bn_mul_mont_t4_8,    bn_mul_mont_t4_16,
-+                bn_mul_mont_t4_24,    bn_mul_mont_t4_32 };
-+            bn_mul_mont_f worker = funcs[num/16-1];
-+
-+            if ((*worker)(rp,ap,bp,np,n0)) return 1;
-+            /* retry once and fall back */
-+            if ((*worker)(rp,ap,bp,np,n0)) return 1;
-+            return bn_mul_mont_vis3(rp,ap,bp,np,n0,num);
-+            }
-+        if ((OPENSSL_sparcv9cap_P[0]&SPARCV9_VIS3))
-+            return bn_mul_mont_vis3(rp,ap,bp,np,n0,num);
-+        else if (num>=8 &&
-+            (OPENSSL_sparcv9cap_P[0]&(SPARCV9_PREFER_FPU|SPARCV9_VIS1)) ==
-+            (SPARCV9_PREFER_FPU|SPARCV9_VIS1))
-+            return bn_mul_mont_fpu(rp,ap,bp,np,n0,num);
-+        }
-+    return bn_mul_mont_int(rp,ap,bp,np,n0,num);
- }
- 
- unsigned long _sparcv9_rdtick(void);
-@@ -39,11 +63,18 @@
- unsigned long _sparcv9_vis1_instrument(void);
- void _sparcv9_vis2_probe(void);
- void _sparcv9_fmadd_probe(void);
-+unsigned long _sparcv9_rdcfr(void);
-+void _sparcv9_vis3_probe(void);
-+unsigned long _sparcv9_random(void);
-+#ifndef _BOOT
-+size_t _sparcv9_vis1_instrument_bus(unsigned int *,size_t);
-+size_t _sparcv9_vis1_instrument_bus2(unsigned int *,size_t,size_t);
-+#endif
- 
- #ifndef _BOOT
- unsigned long OPENSSL_rdtsc(void)
- {
--    if (OPENSSL_sparcv9cap_P & SPARCV9_TICK_PRIVILEGED)
-+    if (OPENSSL_sparcv9cap_P[0] & SPARCV9_TICK_PRIVILEGED)
- #if defined(__sun) && defined(__SVR4)
-         return gethrtime();
- #else
-@@ -52,6 +83,24 @@
-     else
-         return _sparcv9_rdtick();
- }
-+
-+size_t OPENSSL_instrument_bus(unsigned int *out,size_t cnt)
-+{
-+    if ((OPENSSL_sparcv9cap_P[0]&(SPARCV9_TICK_PRIVILEGED|SPARCV9_BLK)) ==
-+            SPARCV9_BLK)
-+        return _sparcv9_vis1_instrument_bus(out,cnt);
-+    else
-+        return 0;
-+}
-+
-+size_t OPENSSL_instrument_bus2(unsigned int *out,size_t cnt,size_t max)
-+{
-+    if ((OPENSSL_sparcv9cap_P[0]&(SPARCV9_TICK_PRIVILEGED|SPARCV9_BLK)) ==
-+            SPARCV9_BLK)
-+        return _sparcv9_vis1_instrument_bus2(out,cnt,max);
-+    else
-+        return 0;
-+}
- #endif
-
- #if defined(_BOOT)
-@@ -61,7 +110,7 @@
-  */
- void OPENSSL_cpuid_setup(void)
-        {
--       OPENSSL_sparcv9cap_P = SPARCV9_VIS1;
-+       OPENSSL_sparcv9cap_P[0] = SPARCV9_VIS1;
-        }
- 
- #elif 0 && defined(__sun) && defined(__SVR4)
-@@ -90,11 +139,11 @@
-     if (!strcmp(name, "SUNW,UltraSPARC") ||
-         /* covers II,III,IV */
-         !strncmp(name, "SUNW,UltraSPARC-I", 17)) {
--        OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU | SPARCV9_VIS1;
-+        OPENSSL_sparcv9cap_P[0] |= SPARCV9_PREFER_FPU | SPARCV9_VIS1;
- 
-         /* %tick is privileged only on UltraSPARC-I/II, but not IIe */
-         if (name[14] != '\0' && name[17] != '\0' && name[18] != '\0')
--            OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
-+            OPENSSL_sparcv9cap_P[0] &= ~SPARCV9_TICK_PRIVILEGED;
- 
-         return DI_WALK_TERMINATE;
-     }
-@@ -100,7 +149,7 @@
-     }
-     /* This is expected to catch remaining UltraSPARCs, such as T1 */
-     else if (!strncmp(name, "SUNW,UltraSPARC", 15)) {
--        OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
-+        OPENSSL_sparcv9cap_P[0] &= ~SPARCV9_TICK_PRIVILEGED;
- 
-         return DI_WALK_TERMINATE;
-     }
-@@ -119,7 +168,7 @@
-     trigger = 1;
- 
-     if ((e = getenv("OPENSSL_sparcv9cap"))) {
--        OPENSSL_sparcv9cap_P = strtoul(e, NULL, 0);
-+        OPENSSL_sparcv9cap_P[0] = strtoul(e, NULL, 0);
-         return;
-     }
- 
-@@ -126,15 +175,15 @@
-     if (sysinfo(SI_MACHINE, si, sizeof(si)) > 0) {
-         if (strcmp(si, "sun4v"))
-             /* FPU is preferred for all CPUs, but US-T1/2 */
--            OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU;
-+            OPENSSL_sparcv9cap_P[0] |= SPARCV9_PREFER_FPU;
-     }
- 
-     if (sysinfo(SI_ISALIST, si, sizeof(si)) > 0) {
-         if (strstr(si, "+vis"))
--            OPENSSL_sparcv9cap_P |= SPARCV9_VIS1;
-+            OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS1 | SPARCV9_BLK;
-         if (strstr(si, "+vis2")) {
--            OPENSSL_sparcv9cap_P |= SPARCV9_VIS2;
--            OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
-+            OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS2;
-+            OPENSSL_sparcv9cap_P[0] &= ~SPARCV9_TICK_PRIVILEGED;
-             return;
-         }
-     }
-@@ -204,12 +253,14 @@
-     trigger = 1;
- 
-     if ((e = getenv("OPENSSL_sparcv9cap"))) {
--        OPENSSL_sparcv9cap_P = strtoul(e, NULL, 0);
-+        OPENSSL_sparcv9cap_P[0] = strtoul(e, NULL, 0);
-+        if ((e = strchr(e, ':')))
-+            OPENSSL_sparcv9cap_P[1] = strtoul(e + 1, NULL, 0);
-         return;
-     }
- 
-     /* Initial value, fits UltraSPARC-I&II... */
--    OPENSSL_sparcv9cap_P = SPARCV9_PREFER_FPU | SPARCV9_TICK_PRIVILEGED;
-+    OPENSSL_sparcv9cap_P[0] = SPARCV9_PREFER_FPU | SPARCV9_TICK_PRIVILEGED;
- 
-     sigfillset(&all_masked);
-     sigdelset(&all_masked, SIGILL);
-@@ -232,18 +283,18 @@
- 
-     if (sigsetjmp(common_jmp, 1) == 0) {
-         _sparcv9_rdtick();
--        OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED;
-+        OPENSSL_sparcv9cap_P[0] &= ~SPARCV9_TICK_PRIVILEGED;
-     }
- 
-     if (sigsetjmp(common_jmp, 1) == 0) {
-         _sparcv9_vis1_probe();
--        OPENSSL_sparcv9cap_P |= SPARCV9_VIS1;
-+        OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS1 | SPARCV9_BLK;
-         /* detect UltraSPARC-Tx, see sparccpud.S for details... */
-         if (_sparcv9_vis1_instrument() >= 12)
--            OPENSSL_sparcv9cap_P &= ~(SPARCV9_VIS1 | SPARCV9_PREFER_FPU);
-+            OPENSSL_sparcv9cap_P[0] &= ~(SPARCV9_VIS1 | SPARCV9_PREFER_FPU);
-         else {
-             _sparcv9_vis2_probe();
--            OPENSSL_sparcv9cap_P |= SPARCV9_VIS2;
-+            OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS2;
-         }
-     }
- 
-@@ -249,13 +300,50 @@
- 
-     if (sigsetjmp(common_jmp, 1) == 0) {
-         _sparcv9_fmadd_probe();
--        OPENSSL_sparcv9cap_P |= SPARCV9_FMADD;
-+        OPENSSL_sparcv9cap_P[0] |= SPARCV9_FMADD;
-     }
- 
-+    /*
-+     * VIS3 flag is tested independently from VIS1, unlike VIS2 that is,
-+     * because VIS3 defines even integer instructions.
-+     */
-+    if (sigsetjmp(common_jmp,1) == 0) {
-+        _sparcv9_vis3_probe();
-+        OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS3;
-+    }
-+
-+    if (sigsetjmp(common_jmp,1) == 0) {
-+        (void)_sparcv9_random();
-+        OPENSSL_sparcv9cap_P[0] |= SPARCV9_RANDOM;
-+    }
-+
-+    /*
-+     * In wait for better solution _sparcv9_rdcfr is masked by
-+     * VIS3 flag, because it goes to uninterruptable endless
-+     * loop on UltraSPARC II running Solaris. Things might be
-+     * different on Linux...
-+     */
-+    if ((OPENSSL_sparcv9cap_P[0]&SPARCV9_VIS3) &&
-+        sigsetjmp(common_jmp, 1) == 0) {
-+        OPENSSL_sparcv9cap_P[1] = (unsigned int)_sparcv9_rdcfr();
-+    }
-+
-     sigaction(SIGBUS, &bus_oact, NULL);
-     sigaction(SIGILL, &ill_oact, NULL);
- 
-     sigprocmask(SIG_SETMASK, &oset, NULL);
-+
-+    if (sizeof(size_t) == 8)
-+        OPENSSL_sparcv9cap_P[0] |= SPARCV9_64BIT_STACK;
-+#ifdef __linux
-+    else
-+        {
-+        int ret = syscall(340);
-+
-+        if (ret >= 0 && ret & 1)
-+            OPENSSL_sparcv9cap_P[0] |= SPARCV9_64BIT_STACK;
-+        }
-+#endif
- }
- 
- #endif
-Index: crypto/md5/Makefile
-===================================================================
-diff -ru openssl-1.0.1e/crypto/md5/Makefile openssl-1.0.1e/crypto/md5/Makefile
---- openssl-1.0.1e/crypto/md5/Makefile	2011-05-24 17:02:24.000000000 -0700
-+++ openssl-1.0.1e/crypto/md5/Makefile	2011-07-27 10:48:17.817470000 -0700
-@@ -52,6 +52,9 @@
- 	$(CC) $(CFLAGS) -E asm/md5-ia64.S | \
- 	$(PERL) -ne 's/;\s+/;\n/g; print;' > $@
- 
-+md5-sparcv9.S:	asm/md5-sparcv9.pl
-+	$(PERL) asm/md5-sparcv9.pl $@ $(CFLAGS)
-+
- files:
- 	$(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
- 
-Index: crypto/md5/md5_locl.h
-===================================================================
-diff -ru openssl-1.0.1e/crypto/md5/md5_locl.h openssl-1.0.1e/crypto/md5/md5_locl.h
---- openssl-1.0.1e/crypto/md5/md5_locl.h    2011-05-24 17:02:24.000000000 -0700
-+++ openssl-1.0.1e/crypto/md5/md5_locl.h    2011-07-27 10:48:17.817470000 -0700
-@@ -71,6 +71,8 @@
- #  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
-+# elif defined(__sparc) || defined(__sparc__)
-+#  define md5_block_data_order md5_block_asm_data_order
- # endif
- #endif
-
-Index: crypto/sha/Makefile
-===================================================================
-diff -ru openssl-1.0.1e/crypto/sha/Makefile openssl-1.0.1e/crypto/sha/Makefile
---- openssl-1.0.1e/crypto/sha/Makefile    2011-05-24 17:02:24.000000000 -0700
-+++ openssl-1.0.1e/crypto/sha/Makefile    2011-07-27 10:48:17.817470000 -0700
-@@ -68,9 +68,9 @@
- sha1-x86_64.s:	asm/sha1-x86_64.pl;	$(PERL) asm/sha1-x86_64.pl $(PERLASM_SCHEME) > $@
- sha256-x86_64.s:asm/sha512-x86_64.pl;	$(PERL) asm/sha512-x86_64.pl $(PERLASM_SCHEME) $@
- sha512-x86_64.s:asm/sha512-x86_64.pl;	$(PERL) asm/sha512-x86_64.pl $(PERLASM_SCHEME) $@
--sha1-sparcv9.s:	asm/sha1-sparcv9.pl;	$(PERL) asm/sha1-sparcv9.pl $@ $(CFLAGS)
--sha256-sparcv9.s:asm/sha512-sparcv9.pl;	$(PERL) asm/sha512-sparcv9.pl $@ $(CFLAGS)
--sha512-sparcv9.s:asm/sha512-sparcv9.pl;	$(PERL) asm/sha512-sparcv9.pl $@ $(CFLAGS)
-+sha1-sparcv9.S:	asm/sha1-sparcv9.pl;	$(PERL) asm/sha1-sparcv9.pl $@ $(CFLAGS)
-+sha256-sparcv9.S:asm/sha512-sparcv9.pl;	$(PERL) asm/sha512-sparcv9.pl $@ $(CFLAGS)
-+sha512-sparcv9.S:asm/sha512-sparcv9.pl;	$(PERL) asm/sha512-sparcv9.pl $@ $(CFLAGS)
- 
- sha1-ppc.s:	asm/sha1-ppc.pl;	$(PERL) asm/sha1-ppc.pl $(PERLASM_SCHEME) $@
- sha256-ppc.s:	asm/sha512-ppc.pl;	$(PERL) asm/sha512-ppc.pl $(PERLASM_SCHEME) $@
-Index: crypto/sha/asm/sha1-sparcv9.pl
-===================================================================
-diff -ru openssl-1.0.1e/crypto/sha/asm/sha1-sparcv9.pl openssl-1.0.1e/crypto/sha/asm/sha1-sparcv9.pl
---- openssl-1.0.1e/crypto/sha/asm/sha1-sparcv9.pl 2011-05-24 17:02:24.000000000 -0700
-+++ openssl-1.0.1e/crypto/sha/asm/sha1-sparcv9.pl 2011-07-27 10:48:17.817470000 -0700
-@@ -5,6 +5,8 @@
- # project. The module is, however, dual licensed under OpenSSL and
- # CRYPTOGAMS licenses depending on where you obtain it. For further
- # details see http://www.openssl.org/~appro/cryptogams/.
-+#
-+# Hardware SPARC T4 support by David S. Miller <[email protected]>.
- # ====================================================================
- 
- # Performance improvement is not really impressive on pre-T1 CPU: +8%
-@@ -18,6 +20,11 @@
- # ensure scalability on UltraSPARC T1, or rather to avoid decay when
- # amount of active threads exceeds the number of physical cores.
- 
-+# SPARC T4 SHA1 hardware achieves 3.72 cycles per byte, which is 3.1x
-+# faster than software. Multi-process benchmark saturates at 11x
-+# single-process result on 8-core processor, or ~9GBps per 2.85GHz
-+# socket.
-+
- $bits=32;
- for (@ARGV)	{ $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
- if ($bits==64)	{ $bias=2047; $frame=192; }
-@@ -183,11 +190,93 @@
- .register	%g3,#scratch
- ___
- $code.=<<___;
-+#include "sparc_arch.h"
-+
- .section	".text",#alloc,#execinstr
- 
-+#ifdef __PIC__
-+SPARC_PIC_THUNK(%g1)
-+#endif
-+
- .align	32
- .globl	sha1_block_data_order
- sha1_block_data_order:
-+    SPARC_LOAD_ADDRESS_LEAF(OPENSSL_sparcv9cap_P,%g1,%g5)
-+    ld    [%g1+4],%g1        ! OPENSSL_sparcv9cap_P[1]
-+
-+    andcc    %g1, CFR_SHA1, %g0
-+    be    .Lsoftware
-+    nop
-+
-+    ld    [%o0 + 0x00], %f0    ! load context
-+    ld    [%o0 + 0x04], %f1
-+    ld    [%o0 + 0x08], %f2
-+    andcc    %o1, 0x7, %g0
-+    ld    [%o0 + 0x0c], %f3
-+    bne,pn    %icc, .Lhwunaligned
-+     ld    [%o0 + 0x10], %f4
-+
-+.Lhw_loop:
-+    ldd    [%o1 + 0x00], %f8
-+    ldd    [%o1 + 0x08], %f10
-+    ldd    [%o1 + 0x10], %f12
-+    ldd    [%o1 + 0x18], %f14
-+    ldd    [%o1 + 0x20], %f16
-+    ldd    [%o1 + 0x28], %f18
-+    ldd    [%o1 + 0x30], %f20
-+    subcc    %o2, 1, %o2        ! done yet? 
-+    ldd    [%o1 + 0x38], %f22
-+    add    %o1, 0x40, %o1
-+
-+    .word    0x81b02820        ! SHA1
-+
-+    bne,pt    `$bits==64?"%xcc":"%icc"`, .Lhw_loop
-+    nop
-+
-+.Lhwfinish:
-+    st    %f0, [%o0 + 0x00]    ! store context
-+    st    %f1, [%o0 + 0x04]
-+    st    %f2, [%o0 + 0x08]
-+    st    %f3, [%o0 + 0x0c]
-+    retl
-+    st    %f4, [%o0 + 0x10]
-+
-+.align    8
-+.Lhwunaligned:
-+    alignaddr %o1, %g0, %o1
-+
-+    ldd    [%o1 + 0x00], %f10
-+.Lhwunaligned_loop:
-+    ldd    [%o1 + 0x08], %f12
-+    ldd    [%o1 + 0x10], %f14
-+    ldd    [%o1 + 0x18], %f16
-+    ldd    [%o1 + 0x20], %f18
-+    ldd    [%o1 + 0x28], %f20
-+    ldd    [%o1 + 0x30], %f22
-+    ldd    [%o1 + 0x38], %f24
-+    subcc    %o2, 1, %o2        ! done yet?
-+    ldd    [%o1 + 0x40], %f26
-+    add    %o1, 0x40, %o1
-+
-+    faligndata %f10, %f12, %f8
-+    faligndata %f12, %f14, %f10
-+    faligndata %f14, %f16, %f12
-+    faligndata %f16, %f18, %f14
-+    faligndata %f18, %f20, %f16
-+    faligndata %f20, %f22, %f18
-+    faligndata %f22, %f24, %f20
-+    faligndata %f24, %f26, %f22
-+
-+    .word    0x81b02820        ! SHA1
-+
-+    bne,pt    `$bits==64?"%xcc":"%icc"`, .Lhwunaligned_loop
-+    for    %f26, %f26, %f10    ! %f10=%f26
-+
-+    ba    .Lhwfinish
-+    nop
-+
-+.align    16
-+.Lsoftware:
- 	save	%sp,-$frame,%sp
- 	sllx	$len,6,$len
- 	add	$inp,$len,$len
-@@ -279,6 +368,62 @@
- .align	4
- ___
- 
--$code =~ s/\`([^\`]*)\`/eval $1/gem;
--print $code;
-+# Purpose of these subroutines is to explicitly encode VIS instructions,
-+# so that one can compile the module without having to specify VIS
-+# extentions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a.
-+# Idea is to reserve for option to produce "universal" binary and let
-+# programmer detect if current CPU is VIS capable at run-time.
-+sub unvis {
-+my ($mnemonic,$rs1,$rs2,$rd)=@_;
-+my $ref,$opf;
-+my %visopf = (    "faligndata"    => 0x048,
-+        "for"        => 0x07c    );
-+
-+    $ref = "$mnemonic\t$rs1,$rs2,$rd";
-+
-+    if ($opf=$visopf{$mnemonic}) {
-+    foreach ($rs1,$rs2,$rd) {
-+        return $ref if (!/%f([0-9]{1,2})/);
-+        $_=$1;
-+        if ($1>=32) {
-+        return $ref if ($1&1);
-+        # re-encode for upper double register addressing
-+        $_=($1|$1>>5)&31;
-+        }
-+    }
-+
-+    return    sprintf ".word\t0x%08x !%s",
-+            0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
-+            $ref;
-+    } else {
-+    return $ref;
-+    }
-+}
-+sub unalignaddr {
-+my ($mnemonic,$rs1,$rs2,$rd)=@_;
-+my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 );
-+my $ref="$mnemonic\t$rs1,$rs2,$rd";
-+
-+    foreach ($rs1,$rs2,$rd) {
-+    if (/%([goli])([0-7])/)    { $_=$bias{$1}+$2; }
-+    else            { return $ref; }
-+    }
-+    return  sprintf ".word\t0x%08x !%s",
-+            0x81b00300|$rd<<25|$rs1<<14|$rs2,
-+            $ref;
-+}
-+
-+foreach (split("\n",$code)) {
-+    s/\`([^\`]*)\`/eval $1/ge;
-+
-+    s/\b(f[^\s]*)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})/
-+        &unvis($1,$2,$3,$4)
-+     /ge;
-+    s/\b(alignaddr)\s+(%[goli][0-7]),\s*(%[goli][0-7]),\s*(%[goli][0-7])/
-+        &unalignaddr($1,$2,$3,$4)
-+     /ge;
-+
-+    print $_,"\n";
-+}
-+
- close STDOUT;
-
-Index: crypto/sha/asm/sha512-sparcv9.pl
-===================================================================
-diff -ru openssl-1.0.1e/crypto/sha/asm/sha512-sparcv9.pl openssl-1.0.1e/crypto/sha/asm/sha512-sparcv9.pl
---- openssl-1.0.1e/crypto/sha/asm/sha512-sparcv9.pl 2011-05-24 17:02:24.000000000 -0700
-+++ openssl-1.0.1e/crypto/sha/asm/sha512-sparcv9.pl 2011-07-27 10:48:17.817470000 -0700
-@@ -5,6 +5,8 @@
- # project. The module is, however, dual licensed under OpenSSL and
- # CRYPTOGAMS licenses depending on where you obtain it. For further
- # details see http://www.openssl.org/~appro/cryptogams/.
-+#
-+# Hardware SPARC T4 support by David S. Miller <[email protected]>.
- # ====================================================================
- 
- # SHA256 performance improvement over compiler generated code varies
-@@ -41,6 +43,12 @@
- #	loads are always slower than one 64-bit load. Once again this
- #	is unlike pre-T1 UltraSPARC, where, if scheduled appropriately,
- #	2x32-bit loads can be as fast as 1x64-bit ones.
-+#
-+# SPARC T4 SHA256/512 hardware achieves 3.17/2.01 cycles per byte,
-+# which is 9.3x/11.1x faster than software. Multi-process benchmark
-+# saturates at 11.5x single-process result on 8-core processor, or
-+# ~11/16GBps per 2.85GHz socket.
-+
- 
- $bits=32;
- for (@ARGV)	{ $bits=64 if (/\-m64/ || /\-xarch\=v9/); }
-@@ -386,6 +394,8 @@
- .register	%g3,#scratch
- ___
- $code.=<<___;
-+#include "sparc_arch.h"
-+
- .section	".text",#alloc,#execinstr
- 
- .align	64
-@@ -457,8 +467,196 @@
- }
- $code.=<<___;
- .size	K${label},.-K${label}
-+
-+#ifdef __PIC__
-+SPARC_PIC_THUNK(%g1)
-+#endif
-+
- .globl	sha${label}_block_data_order
-+.align	32
- sha${label}_block_data_order:
-+    SPARC_LOAD_ADDRESS_LEAF(OPENSSL_sparcv9cap_P,%g1,%g5)
-+    ld    [%g1+4],%g1        ! OPENSSL_sparcv9cap_P[1]
-+
-+    andcc    %g1, CFR_SHA${label}, %g0
-+    be    .Lsoftware
-+    nop
-+___
-+$code.=<<___ if ($SZ==8);         # SHA512
-+    ldd    [%o0 + 0x00], %f0    ! load context
-+    ldd    [%o0 + 0x08], %f2
-+    ldd    [%o0 + 0x10], %f4
-+    ldd    [%o0 + 0x18], %f6
-+    ldd    [%o0 + 0x20], %f8
-+    ldd    [%o0 + 0x28], %f10
-+    andcc    %o1, 0x7, %g0
-+    ldd    [%o0 + 0x30], %f12
-+    bne,pn    %icc, .Lhwunaligned
-+     ldd    [%o0 + 0x38], %f14
-+
-+.Lhwaligned_loop:
-+    ldd    [%o1 + 0x00], %f16
-+    ldd    [%o1 + 0x08], %f18
-+    ldd    [%o1 + 0x10], %f20
-+    ldd    [%o1 + 0x18], %f22
-+    ldd    [%o1 + 0x20], %f24
-+    ldd    [%o1 + 0x28], %f26
-+    ldd    [%o1 + 0x30], %f28
-+    ldd    [%o1 + 0x38], %f30
-+    ldd    [%o1 + 0x40], %f32
-+    ldd    [%o1 + 0x48], %f34
-+    ldd    [%o1 + 0x50], %f36
-+    ldd    [%o1 + 0x58], %f38
-+    ldd    [%o1 + 0x60], %f40
-+    ldd    [%o1 + 0x68], %f42
-+    ldd    [%o1 + 0x70], %f44
-+    subcc    %o2, 1, %o2        ! done yet?
-+    ldd    [%o1 + 0x78], %f46
-+    add    %o1, 0x80, %o1
-+
-+    .word    0x81b02860        ! SHA512
-+
-+    bne,pt    `$bits==64?"%xcc":"%icc"`, .Lhwaligned_loop
-+    nop
-+
-+.Lhwfinish:
-+    std    %f0, [%o0 + 0x00]    ! store context
-+    std    %f2, [%o0 + 0x08]
-+    std    %f4, [%o0 + 0x10]
-+    std    %f6, [%o0 + 0x18]
-+    std    %f8, [%o0 + 0x20]
-+    std    %f10, [%o0 + 0x28]
-+    std    %f12, [%o0 + 0x30]
-+    retl
-+     std    %f14, [%o0 + 0x38]
-+
-+.align    16
-+.Lhwunaligned:
-+    alignaddr %o1, %g0, %o1
-+
-+    ldd    [%o1 + 0x00], %f18
-+.Lhwunaligned_loop:
-+    ldd    [%o1 + 0x08], %f20
-+    ldd    [%o1 + 0x10], %f22
-+    ldd    [%o1 + 0x18], %f24
-+    ldd    [%o1 + 0x20], %f26
-+    ldd    [%o1 + 0x28], %f28
-+    ldd    [%o1 + 0x30], %f30
-+    ldd    [%o1 + 0x38], %f32
-+    ldd    [%o1 + 0x40], %f34
-+    ldd    [%o1 + 0x48], %f36
-+    ldd    [%o1 + 0x50], %f38
-+    ldd    [%o1 + 0x58], %f40
-+    ldd    [%o1 + 0x60], %f42
-+    ldd    [%o1 + 0x68], %f44
-+    ldd    [%o1 + 0x70], %f46
-+    ldd    [%o1 + 0x78], %f48
-+    subcc    %o2, 1, %o2        ! done yet?
-+    ldd    [%o1 + 0x80], %f50
-+    add    %o1, 0x80, %o1
-+
-+    faligndata %f18, %f20, %f16
-+    faligndata %f20, %f22, %f18
-+    faligndata %f22, %f24, %f20
-+    faligndata %f24, %f26, %f22
-+    faligndata %f26, %f28, %f24
-+    faligndata %f28, %f30, %f26
-+    faligndata %f30, %f32, %f28
-+    faligndata %f32, %f34, %f30
-+    faligndata %f34, %f36, %f32
-+    faligndata %f36, %f38, %f34
-+    faligndata %f38, %f40, %f36
-+    faligndata %f40, %f42, %f38
-+    faligndata %f42, %f44, %f40
-+    faligndata %f44, %f46, %f42
-+    faligndata %f46, %f48, %f44
-+    faligndata %f48, %f50, %f46
-+
-+    .word    0x81b02860        ! SHA512
-+
-+    bne,pt    `$bits==64?"%xcc":"%icc"`, .Lhwunaligned_loop
-+    for    %f50, %f50, %f18    ! %f18=%f50
-+
-+    ba    .Lhwfinish
-+    nop
-+___
-+$code.=<<___ if ($SZ==4);         # SHA256
-+    ld    [%o0 + 0x00], %f0
-+    ld    [%o0 + 0x04], %f1
-+    ld    [%o0 + 0x08], %f2
-+    ld    [%o0 + 0x0c], %f3
-+    ld    [%o0 + 0x10], %f4
-+    ld    [%o0 + 0x14], %f5
-+    andcc    %o1, 0x7, %g0
-+    ld    [%o0 + 0x18], %f6
-+    bne,pn    %icc, .Lhwunaligned
-+     ld    [%o0 + 0x1c], %f7
-+
-+.Lhwloop:
-+    ldd    [%o1 + 0x00], %f8
-+    ldd    [%o1 + 0x08], %f10
-+    ldd    [%o1 + 0x10], %f12
-+    ldd    [%o1 + 0x18], %f14
-+    ldd    [%o1 + 0x20], %f16
-+    ldd    [%o1 + 0x28], %f18
-+    ldd    [%o1 + 0x30], %f20
-+    subcc    %o2, 1, %o2        ! done yet?
-+    ldd    [%o1 + 0x38], %f22
-+    add    %o1, 0x40, %o1
-+
-+    .word    0x81b02840        ! SHA256
-+
-+    bne,pt    `$bits==64?"%xcc":"%icc"`, .Lhwloop
-+    nop
-+
-+.Lhwfinish:
-+    st    %f0, [%o0 + 0x00]    ! store context
-+    st    %f1, [%o0 + 0x04]
-+    st    %f2, [%o0 + 0x08]
-+    st    %f3, [%o0 + 0x0c]
-+    st    %f4, [%o0 + 0x10]
-+    st    %f5, [%o0 + 0x14]
-+    st    %f6, [%o0 + 0x18]
-+    retl
-+     st    %f7, [%o0 + 0x1c]
-+
-+.align    8
-+.Lhwunaligned:
-+    alignaddr %o1, %g0, %o1
-+
-+    ldd    [%o1 + 0x00], %f10
-+.Lhwunaligned_loop:
-+    ldd    [%o1 + 0x08], %f12
-+    ldd    [%o1 + 0x10], %f14
-+    ldd    [%o1 + 0x18], %f16
-+    ldd    [%o1 + 0x20], %f18
-+    ldd    [%o1 + 0x28], %f20
-+    ldd    [%o1 + 0x30], %f22
-+    ldd    [%o1 + 0x38], %f24
-+    subcc    %o2, 1, %o2        ! done yet?
-+    ldd    [%o1 + 0x40], %f26
-+    add    %o1, 0x40, %o1
-+
-+    faligndata %f10, %f12, %f8
-+    faligndata %f12, %f14, %f10
-+    faligndata %f14, %f16, %f12
-+    faligndata %f16, %f18, %f14
-+    faligndata %f18, %f20, %f16
-+    faligndata %f20, %f22, %f18
-+    faligndata %f22, %f24, %f20
-+    faligndata %f24, %f26, %f22
-+
-+    .word    0x81b02840        ! SHA256
-+
-+    bne,pt    `$bits==64?"%xcc":"%icc"`, .Lhwunaligned_loop
-+    for    %f26, %f26, %f10    ! %f10=%f26
-+
-+    ba    .Lhwfinish
-+    nop
-+___
-+$code.=<<___;
-+.align    16
-+.Lsoftware:
- 	save	%sp,`-$frame-$locals`,%sp
- 	and	$inp,`$align-1`,$tmp31
- 	sllx	$len,`log(16*$SZ)/log(2)`,$len
-@@ -589,6 +787,62 @@
- .align	4
- ___
- 
--$code =~ s/\`([^\`]*)\`/eval $1/gem;
--print $code;
-+# Purpose of these subroutines is to explicitly encode VIS instructions,
-+# so that one can compile the module without having to specify VIS
-+# extentions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a.
-+# Idea is to reserve for option to produce "universal" binary and let
-+# programmer detect if current CPU is VIS capable at run-time.
-+sub unvis {
-+my ($mnemonic,$rs1,$rs2,$rd)=@_;
-+my $ref,$opf;
-+my %visopf = (    "faligndata"    => 0x048,
-+        "for"        => 0x07c    );
-+
-+    $ref = "$mnemonic\t$rs1,$rs2,$rd";
-+
-+    if ($opf=$visopf{$mnemonic}) {
-+    foreach ($rs1,$rs2,$rd) {
-+        return $ref if (!/%f([0-9]{1,2})/);
-+        $_=$1;
-+        if ($1>=32) {
-+        return $ref if ($1&1);
-+        # re-encode for upper double register addressing
-+        $_=($1|$1>>5)&31;
-+        }
-+    }
-+
-+    return    sprintf ".word\t0x%08x !%s",
-+            0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
-+            $ref;
-+    } else {
-+    return $ref;
-+    }
-+}
-+sub unalignaddr {
-+my ($mnemonic,$rs1,$rs2,$rd)=@_;
-+my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 );
-+my $ref="$mnemonic\t$rs1,$rs2,$rd";
-+
-+    foreach ($rs1,$rs2,$rd) {
-+    if (/%([goli])([0-7])/)    { $_=$bias{$1}+$2; }
-+    else            { return $ref; }
-+    }
-+    return  sprintf ".word\t0x%08x !%s",
-+            0x81b00300|$rd<<25|$rs1<<14|$rs2,
-+            $ref;
-+}
-+
-+foreach (split("\n",$code)) {
-+    s/\`([^\`]*)\`/eval $1/ge;
-+
-+    s/\b(f[^\s]*)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})/
-+        &unvis($1,$2,$3,$4)
-+     /ge;
-+    s/\b(alignaddr)\s+(%[goli][0-7]),\s*(%[goli][0-7]),\s*(%[goli][0-7])/
-+        &unalignaddr($1,$2,$3,$4)
-+     /ge;
-+
-+    print $_,"\n";
-+}
-+
- close STDOUT;
-Index: crypto/des/Makefile
-===================================================================
-diff -ru openssl-1.0.1e/crypto/des/Makefile.orig openssl-1.0.1e/crypto/des/Makefile
---- a/crypto/des/Makefile
-+++ b/crypto/des/Makefile
-@@ -61,6 +61,8 @@ des: des.o cbc3_enc.o lib
- 
- des_enc-sparc.S:	asm/des_enc.m4
- 	m4 -B 8192 asm/des_enc.m4 > des_enc-sparc.S
-+dest4-sparcv9.s:	asm/dest4-sparcv9.pl
-+	$(PERL) asm/dest4-sparcv9.pl $(CFLAGS) > $@
- 
- des-586.s:	asm/des-586.pl ../perlasm/x86asm.pl ../perlasm/cbc.pl
- 	$(PERL) asm/des-586.pl $(PERLASM_SCHEME) $(CFLAGS) > $@
-Index: crypto/evp/e_des.c
-===================================================================
-diff -ru openssl-1.0.1e/crypto/evp/e_des.c.orig openssl-1.0.1e/crypto/evp/e_des.c
---- a/crypto/evp/e_des.c
-+++ b/crypto/evp/e_des.c
-@@ -65,6 +65,30 @@
- # include <openssl/des.h>
- # include <openssl/rand.h>
- 
-+typedef struct {
-+    union { double align; DES_key_schedule ks; } ks;
-+    union {
-+        void (*cbc)(const void *,void *,size_t,const void *,void *);
-+    } stream;
-+} EVP_DES_KEY;
-+
-+#if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
-+/* ---------^^^ this is not a typo, just a way to detect that
-+ * assembler support was in general requested...
-+ */
-+#include "sparc_arch.h"
-+
-+extern unsigned int OPENSSL_sparcv9cap_P[];
-+
-+#define SPARC_DES_CAPABLE    (OPENSSL_sparcv9cap_P[1] & CFR_DES)
-+
-+void    des_t4_key_expand(const void *key, DES_key_schedule *ks);
-+void    des_t4_cbc_encrypt(const void *inp,void *out,size_t len,
-+                DES_key_schedule *ks,unsigned char iv[8]);
-+void    des_t4_cbc_decrypt(const void *inp,void *out,size_t len,
-+                DES_key_schedule *ks,unsigned char iv[8]);
-+#endif
-+
- 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);
-@@ -102,6 +126,12 @@ static int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
- static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-                           const unsigned char *in, size_t inl)
- {
-+    EVP_DES_KEY *dat = (EVP_DES_KEY *)ctx->cipher_data;
-+
-+    if (dat->stream.cbc) {
-+        (*dat->stream.cbc)(in,out,inl,&dat->ks.ks,ctx->iv);
-+        return 1;
-+    }
-     while (inl >= EVP_MAXCHUNK) {
-         DES_ncbc_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data,
-                          (DES_cblock *)ctx->iv, ctx->encrypt);
-@@ -179,16 +209,16 @@
-     return 1;
- }
- 
--BLOCK_CIPHER_defs(des, DES_key_schedule, NID_des, 8, 8, 8, 64,
-+BLOCK_CIPHER_defs(des, EVP_DES_KEY, 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,
-+BLOCK_CIPHER_def_cfb(des, EVP_DES_KEY, 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,
-+BLOCK_CIPHER_def_cfb(des, EVP_DES_KEY, 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)
- 
-@@ -196,8 +226,23 @@ 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;
-+    EVP_DES_KEY *dat = (EVP_DES_KEY *)ctx->cipher_data;
-+
-+    dat->stream.cbc = NULL;
-+#if defined(SPARC_DES_CAPABLE)
-+    if (SPARC_DES_CAPABLE) {
-+        int mode = ctx->cipher->flags & EVP_CIPH_MODE;
-+
-+        if (mode == EVP_CIPH_CBC_MODE) {
-+            des_t4_key_expand(key,&dat->ks.ks);
-+            dat->stream.cbc = enc ? des_t4_cbc_encrypt :
-+                        des_t4_cbc_decrypt;
-+            return 1;
-+        }
-+    }
-+#endif
- # ifdef EVP_CHECK_DES_KEY
--    if (DES_set_key_checked(deskey, ctx->cipher_data) != 0)
-+    if (DES_set_key_checked(deskey, dat->ks.ks) != 0)
-         return 0;
- # else
-     DES_set_key_unchecked(deskey, ctx->cipher_data);
-Index: crypto/evp/e_des3.c
-===================================================================
-diff -ru openssl-1.0.1e/crypto/evp/e_des3.c.orig openssl-1.0.1e/crypto/evp/e_des3.c
---- a/crypto/evp/e_des3.c
-+++ b/crypto/evp/e_des3.c
-@@ -65,6 +65,32 @@
- # include <openssl/des.h>
- # include <openssl/rand.h>
- 
-+typedef struct {
-+    union { double align; DES_key_schedule ks[3]; } ks;
-+    union {
-+        void (*cbc)(const void *,void *,size_t,const void *,void *);
-+    } stream;
-+} DES_EDE_KEY;
-+#define ks1 ks.ks[0]
-+#define ks2 ks.ks[1]
-+#define ks3 ks.ks[2]
-+
-+#if defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
-+/* ---------^^^ this is not a typo, just a way to detect that
-+ * assembler support was in general requested... */
-+#include "sparc_arch.h"
-+
-+extern unsigned int OPENSSL_sparcv9cap_P[];
-+
-+#define SPARC_DES_CAPABLE    (OPENSSL_sparcv9cap_P[1] & CFR_DES)
-+
-+void    des_t4_key_expand(const void *key, DES_key_schedule *ks);
-+void    des_t4_ede3_cbc_encrypt(const void *inp,void *out,size_t len,
-+                DES_key_schedule *ks,unsigned char iv[8]);
-+void    des_t4_ede3_cbc_decrypt(const void *inp,void *out,size_t len,
-+                DES_key_schedule *ks,unsigned char iv[8]);
-+#endif
-+
- # ifndef OPENSSL_FIPS
- 
- static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-@@ -75,12 +100,6 @@ static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-
- 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)
-
- /*
-@@ -123,6 +117,7 @@ static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
- static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-                               const unsigned char *in, size_t inl)
- {
-+    DES_EDE_KEY *dat = data(ctx);
- #  ifdef KSSL_DEBUG
-     {
-         int i;
-@@ -134,11 +155,15 @@
-         fprintf(stderr, "\n");
-     }
- #  endif                        /* KSSL_DEBUG */
-+    if (dat->stream.cbc) {
-+        (*dat->stream.cbc)(in,out,inl,&dat->ks,ctx->iv);
-+        return 1;
-+    }
-+
-     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);
-+                             &dat->ks1, &dat->ks2, &dat->ks3,
-+                             (DES_cblock *)ctx->iv, ctx->encrypt);
-         inl -= EVP_MAXCHUNK;
-         in += EVP_MAXCHUNK;
-         out += EVP_MAXCHUNK;
-@@ -145,9 +170,8 @@ static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-     }
-     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);
-+                             &dat->ks1, &dat->ks2, &dat->ks3,
-+                             (DES_cblock *)ctx->iv, ctx->encrypt);
-     return 1;
- }
-
-@@ -215,39 +239,58 @@ static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
- }
-
- 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)
-+                  EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_DEFAULT_ASN1,
-+                  des_ede_init_key, NULL, NULL, NULL,
-+                 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)
-+        EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
-+        des_ede3_init_key, NULL, NULL, NULL,
-+        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)
-+        EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
-+        des_ede3_init_key, NULL, NULL, NULL,
-+        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)
-+        EVP_CIPH_RAND_KEY|EVP_CIPH_FLAG_FIPS|EVP_CIPH_FLAG_DEFAULT_ASN1,
-+        des_ede3_init_key, NULL, NULL, NULL,
-+        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_EDE_KEY *dat = data(ctx);
-+
-+    dat->stream.cbc = NULL;
-+#if defined(SPARC_DES_CAPABLE)
-+    if (SPARC_DES_CAPABLE) {
-+        int mode = ctx->cipher->flags & EVP_CIPH_MODE;
-+
-+        if (mode == EVP_CIPH_CBC_MODE) {
-+            des_t4_key_expand(&deskey[0],&dat->ks1);
-+            des_t4_key_expand(&deskey[1],&dat->ks2);
-+            memcpy(&dat->ks3,&dat->ks1,sizeof(dat->ks1));
-+            dat->stream.cbc = enc ? des_t4_ede3_cbc_encrypt :
-+                        des_t4_ede3_cbc_decrypt;
-+            return 1;
-+        }
-+    }
-+#endif
- #  ifdef EVP_CHECK_DES_KEY
--    if (DES_set_key_checked(&deskey[0], &data(ctx)->ks1)
--        || DES_set_key_checked(&deskey[1], &data(ctx)->ks2))
-+    if (DES_set_key_checked(&deskey[0],&dat->ks1)
-+        || DES_set_key_checked(&deskey[1],&dat->ks2))
-         return 0;
- #  else
--    DES_set_key_unchecked(&deskey[0], &data(ctx)->ks1);
--    DES_set_key_unchecked(&deskey[1], &data(ctx)->ks2);
-+    DES_set_key_unchecked(&deskey[0],&dat->ks1);
-+    DES_set_key_unchecked(&deskey[1],&dat->ks2);
- #  endif
--    memcpy(&data(ctx)->ks3, &data(ctx)->ks1, sizeof(data(ctx)->ks1));
-+    memcpy(&dat->ks3,&dat->ks1, sizeof(dat->ks1));
-     return 1;
- }
-
-@@ -255,6 +298,8 @@ 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_EDE_KEY *dat = data(ctx);
-+
- #  ifdef KSSL_DEBUG
-     {
-         int i;
-@@ -272,15 +317,30 @@ static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-     }
- #  endif                        /* KSSL_DEBUG */
-
-+    dat->stream.cbc = NULL;
-+#if defined(SPARC_DES_CAPABLE)
-+    if (SPARC_DES_CAPABLE) {
-+        int mode = ctx->cipher->flags & EVP_CIPH_MODE;
-+
-+        if (mode == EVP_CIPH_CBC_MODE) {
-+            des_t4_key_expand(&deskey[0],&dat->ks1);
-+            des_t4_key_expand(&deskey[1],&dat->ks2);
-+            des_t4_key_expand(&deskey[2],&dat->ks3);
-+            dat->stream.cbc = enc ? des_t4_ede3_cbc_encrypt :
-+                        des_t4_ede3_cbc_decrypt;
-+            return 1;
-+        }
-+    }
-+#endif
- #  ifdef EVP_CHECK_DES_KEY
--    if (DES_set_key_checked(&deskey[0], &data(ctx)->ks1)
--        || DES_set_key_checked(&deskey[1], &data(ctx)->ks2)
--        || DES_set_key_checked(&deskey[2], &data(ctx)->ks3))
-+    if (DES_set_key_checked(&deskey[0],&dat->ks1)
-+        || DES_set_key_checked(&deskey[1],&dat->ks2)
-+        || DES_set_key_checked(&deskey[2],&dat->ks3))
-         return 0;
- #  else
--    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);
-+    DES_set_key_unchecked(&deskey[0],&dat->ks1);
-+    DES_set_key_unchecked(&deskey[1],&dat->ks2);
-+    DES_set_key_unchecked(&deskey[2],&dat->ks3);
- #  endif
-     return 1;
- }
-Index: openssl/crypto/bn/Makefile
-===================================================================
-diff -ru openssl-1.0.1e/crypto/bn/Makefile openssl-1.0.1e/crypto/bn/Makefile.new
---- openssl-1.0.1e/crypto/bn/Makefile 2011-05-24 17:02:24.000000000 -0700
-+++ openssl-1.0.1e/crypto/bn/Makefile 2011-07-27 10:48:17.817470000 -0700
-@@ -77,6 +77,12 @@
- 	$(PERL) asm/sparcv9a-mont.pl $(CFLAGS) > $@
- sparcv9-mont.s:		asm/sparcv9-mont.pl
- 	$(PERL) asm/sparcv9-mont.pl $(CFLAGS) > $@
-+vis3-mont.s:		asm/vis3-mont.pl
-+	$(PERL) asm/vis3-mont.pl $(CFLAGS) > $@
-+sparct4-mont.S:	asm/sparct4-mont.pl
-+	$(PERL) asm/sparct4-mont.pl $(CFLAGS) > $@
-+sparcv9-gf2m.S:	asm/sparcv9-gf2m.pl
-+	$(PERL) asm/sparcv9-gf2m.pl $(CFLAGS) > $@
- 
- bn-mips3.o:	asm/mips3.s
- 	@if [ "$(CC)" = "gcc" ]; then \
-Index: openssl/crypto/bn/bn_exp.c
-===================================================================
-diff -ru openssl-1.0.1e/crypto/bn/bn_exp.c openssl-1.0.1e/crypto/bn/bn_exp.c.new
---- bn_exp.c    2011/10/29 19:25:13    1.38
-+++ bn_exp.c    2012/11/17 10:34:11    1.39
-@@ -122,8 +122,15 @@
- # ifndef alloca
- #  define alloca(s) __builtin_alloca((s))
- # endif
-+#else
-+#include <alloca.h>
- #endif
- 
-+#if defined(OPENSSL_BN_ASM_MONT) && defined(__sparc)
-+# include "sparc_arch.h"
-+extern unsigned int OPENSSL_sparcv9cap_P[];
-+#endif
-+
- /* maximum precomputation table size for *variable* sliding windows */
- #define TABLE_SIZE      32
- 
-@@ -464,8 +471,16 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
-     wstart = bits - 1;          /* The top bit of the window */
-     wend = 0;                   /* The bottom bit of the window */
- 
-+#if 1    /* by Shay Gueron's suggestion */
-+    j = mont->N.top;    /* borrow j */
-+    if (bn_wexpand(r,j) == NULL) goto err;
-+    r->d[0] = (0-m->d[0])&BN_MASK2;        /* 2^(top*BN_BITS2) - m */
-+    for(i=1;i<j;i++) r->d[i] = (~m->d[i])&BN_MASK2;
-+    r->top = j;
-+#else
-     if (!BN_to_montgomery(r, BN_value_one(), mont, ctx))
-         goto err;
-+#endif
-     for (;;) {
-         if (BN_is_bit_set(p, wstart) == 0) {
-             if (!start) {
-@@ -515,6 +530,17 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
-         if (wstart < 0)
-             break;
-     }
-+#if defined(OPENSSL_BN_ASM_MONT) && (defined(__sparc__) || defined(__sparc))
-+    if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3|SPARCV9_PREFER_FPU)) {
-+        j = mont->N.top;    /* borrow j */
-+        val[0]->d[0] = 1;    /* borrow val[0] */
-+        for (i=1;i<j;i++)
-+            val[0]->d[i] = 0;
-+        val[0]->top = j;
-+        if (!BN_mod_mul_montgomery(rr, r, val[0], mont, ctx))
-+            goto err;
-+    } else
-+#endif
-     if (!BN_from_montgomery(rr, r, mont, ctx))
-         goto err;
-     ret = 1;
-@@ -526,6 +552,26 @@ err:
-     return (ret);
- }
-
-+#if defined(OPENSSL_BN_ASM_MONT) && (defined(__sparc__) || defined(__sparc))
-+static BN_ULONG bn_get_bits(const BIGNUM *a, int bitpos) {
-+    BN_ULONG ret = 0;
-+    int wordpos;
-+
-+    wordpos = bitpos / BN_BITS2;
-+    bitpos %= BN_BITS2;
-+    if (wordpos>=0 && wordpos < a->top) {
-+        ret = a->d[wordpos]&BN_MASK2;
-+        if (bitpos) {
-+            ret >>= bitpos;
-+            if (++wordpos < a->top)
-+                ret |= a->d[wordpos]<<(BN_BITS2-bitpos);
-+        }
-+    }
-+
-+    return ret & BN_MASK2;
-+}
-+#endif
-+
- /*
-  * 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
-@@ -594,6 +640,9 @@
-     int powerbufLen = 0;
-     unsigned char *powerbuf = NULL;
-     BIGNUM tmp, am;
-+#if defined(OPENSSL_BN_ASM_MONT) && defined(__sparc)
-+    unsigned int t4=0;
-+#endif
-
-     bn_check_top(a);
-     bn_check_top(p);
-@@ -628,10 +677,18 @@
-
-     /* Get the window size to use with size of p. */
-     window = BN_window_bits_for_ctime_exponent_size(bits);
-+#if defined(OPENSSL_BN_ASM_MONT) && defined(__sparc)
-+    if (window>=5 && (top&15)==0 && top<=64 &&
-+        (OPENSSL_sparcv9cap_P[1]&(CFR_MONTMUL|CFR_MONTSQR))==
-+        (CFR_MONTMUL|CFR_MONTSQR) && (t4=OPENSSL_sparcv9cap_P[0]))
-+            window=5;
-+    else
-+#endif
- #if defined(OPENSSL_BN_ASM_MONT5)
-     if (window == 6 && bits <= 1024)
-         window = 5;             /* ~5% improvement of 2048-bit RSA sign */
- #endif
-+    (void) 0;
-
-     /*
-      * Allocate a buffer large enough to hold all of the pre-computed powers
-@@ -670,14 +727,14 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
-     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
-+#if 1    /* by Shay Gueron's suggestion */
-     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;
-+#else
-+    if (!BN_to_montgomery(&tmp,BN_value_one(),mont,ctx))
-+        goto err;
- #endif
-
-     /* prepare a^1 in Montgomery domain */
-@@ -689,6 +746,122 @@
-     } else if (!BN_to_montgomery(&am, a, mont, ctx))
-         goto err;
-
-+#if defined(OPENSSL_BN_ASM_MONT) && defined(__sparc)
-+    if (t4) {
-+        typedef int (*bn_pwr5_mont_f)(BN_ULONG *tp,const BN_ULONG *np,
-+            const BN_ULONG *n0,const void *table,int power,int bits);
-+        int bn_pwr5_mont_t4_8(BN_ULONG *tp,const BN_ULONG *np,
-+            const BN_ULONG *n0,const void *table,int power,int bits);
-+        int bn_pwr5_mont_t4_16(BN_ULONG *tp,const BN_ULONG *np,
-+            const BN_ULONG *n0,const void *table,int power,int bits);
-+        int bn_pwr5_mont_t4_24(BN_ULONG *tp,const BN_ULONG *np,
-+            const BN_ULONG *n0,const void *table,int power,int bits);
-+        int bn_pwr5_mont_t4_32(BN_ULONG *tp,const BN_ULONG *np,
-+            const BN_ULONG *n0,const void *table,int power,int bits);
-+        static const bn_pwr5_mont_f pwr5_funcs[4] = {
-+            bn_pwr5_mont_t4_8,    bn_pwr5_mont_t4_16,
-+            bn_pwr5_mont_t4_24,    bn_pwr5_mont_t4_32 };
-+        bn_pwr5_mont_f pwr5_worker = pwr5_funcs[top/16-1];
-+
-+        typedef int (*bn_mul_mont_f)(BN_ULONG *rp,const BN_ULONG *ap,
-+            const void *bp,const BN_ULONG *np,const BN_ULONG *n0);
-+        int bn_mul_mont_t4_8(BN_ULONG *rp,const BN_ULONG *ap,
-+            const void *bp,const BN_ULONG *np,const BN_ULONG *n0);
-+        int bn_mul_mont_t4_16(BN_ULONG *rp,const BN_ULONG *ap,
-+            const void *bp,const BN_ULONG *np,const BN_ULONG *n0);
-+        int bn_mul_mont_t4_24(BN_ULONG *rp,const BN_ULONG *ap,
-+            const void *bp,const BN_ULONG *np,const BN_ULONG *n0);
-+        int bn_mul_mont_t4_32(BN_ULONG *rp,const BN_ULONG *ap,
-+            const void *bp,const BN_ULONG *np,const BN_ULONG *n0);
-+        static const bn_mul_mont_f mul_funcs[4] = {
-+            bn_mul_mont_t4_8,    bn_mul_mont_t4_16,
-+            bn_mul_mont_t4_24,    bn_mul_mont_t4_32 };
-+        bn_mul_mont_f mul_worker = mul_funcs[top/16-1];
-+
-+        void bn_mul_mont_vis3(BN_ULONG *rp,const BN_ULONG *ap,
-+            const void *bp,const BN_ULONG *np,
-+            const BN_ULONG *n0,int num);
-+        void bn_mul_mont_t4(BN_ULONG *rp,const BN_ULONG *ap,
-+            const void *bp,const BN_ULONG *np,
-+            const BN_ULONG *n0,int num);
-+        void bn_mul_mont_gather5_t4(BN_ULONG *rp,const BN_ULONG *ap,
-+            const void *table,const BN_ULONG *np,
-+            const BN_ULONG *n0,int num,int power);
-+        void bn_flip_n_scatter5_t4(const BN_ULONG *inp,size_t num,
-+            void *table,size_t power);
-+        void bn_gather5_t4(BN_ULONG *out,size_t num,
-+            void *table,size_t power);
-+        void bn_flip_t4(BN_ULONG *dst,BN_ULONG *src,size_t num);
-+
-+        BN_ULONG *np=mont->N.d, *n0=mont->n0;
-+        int stride = 5*(6-(top/16-1));    /* multiple of 5, but less than 32 */
-+
-+        /*
-+         * 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_flip_n_scatter5_t4(tmp.d,top,powerbuf,0);
-+        bn_flip_n_scatter5_t4(am.d,top,powerbuf,1);
-+        if (!(*mul_worker)(tmp.d,am.d,am.d,np,n0) &&
-+        !(*mul_worker)(tmp.d,am.d,am.d,np,n0))
-+        bn_mul_mont_vis3(tmp.d,am.d,am.d,np,n0,top);
-+        bn_flip_n_scatter5_t4(tmp.d,top,powerbuf,2);
-+
-+        for (i=3; i<32; i++) {
-+        /* Calculate a^i = a^(i-1) * a */
-+        if (!(*mul_worker)(tmp.d,tmp.d,am.d,np,n0) &&
-+            !(*mul_worker)(tmp.d,tmp.d,am.d,np,n0))
-+            bn_mul_mont_vis3(tmp.d,tmp.d,am.d,np,n0,top);
-+        bn_flip_n_scatter5_t4(tmp.d,top,powerbuf,i);
-+        }
-+
-+        /* switch to 64-bit domain */
-+        np = alloca(top*sizeof(BN_ULONG));
-+        top /= 2;
-+        bn_flip_t4(np,mont->N.d,top);
-+
-+        bits--;
-+        for (wvalue=0, i=bits%5; i>=0; i--,bits--)
-+        wvalue = (wvalue<<1)+BN_is_bit_set(p,bits);
-+        bn_gather5_t4(tmp.d,top,powerbuf,wvalue);
-+
-+        /* Scan the exponent one window at a time starting from the most
-+         * significant bits.
-+         */
-+        while (bits >= 0) {
-+        if (bits < stride)
-+            stride = bits+1;
-+        bits -= stride;
-+        wvalue = (bn_get_bits(p,bits+1));
-+
-+        if ((*pwr5_worker)(tmp.d,np,n0,powerbuf,wvalue,stride))
-+            continue;
-+        /* retry once and fall back */
-+        if ((*pwr5_worker)(tmp.d,np,n0,powerbuf,wvalue,stride))
-+            continue;
-+
-+        bits += stride-5;
-+        wvalue >>= stride-5;
-+        wvalue &= 31;
-+        bn_mul_mont_t4(tmp.d,tmp.d,tmp.d,np,n0,top);
-+        bn_mul_mont_t4(tmp.d,tmp.d,tmp.d,np,n0,top);
-+        bn_mul_mont_t4(tmp.d,tmp.d,tmp.d,np,n0,top);
-+        bn_mul_mont_t4(tmp.d,tmp.d,tmp.d,np,n0,top);
-+        bn_mul_mont_t4(tmp.d,tmp.d,tmp.d,np,n0,top);
-+        bn_mul_mont_gather5_t4(tmp.d,tmp.d,powerbuf,np,n0,top,wvalue);
-+        }
-+
-+        bn_flip_t4(tmp.d,tmp.d,top);
-+        top *= 2;
-+        /* back to 32-bit domain */
-+        tmp.top=top;
-+        bn_correct_top(&tmp);
-+        OPENSSL_cleanse(np,top*sizeof(BN_ULONG));
-+    } else
-+#endif
- #if defined(OPENSSL_BN_ASM_MONT5)
-     if (window == 5 && top > 1) {
-         /*
-@@ -844,6 +1017,15 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
-     }
-
-     /* Convert the final result from montgomery to standard format */
-+#if defined(OPENSSL_BN_ASM_MONT) && (defined(__sparc__) || defined(__sparc))
-+    if (OPENSSL_sparcv9cap_P[0] & (SPARCV9_VIS3|SPARCV9_PREFER_FPU)) {
-+        am.d[0] = 1;    /* borrow am */
-+        for (i = 1; i < top; i++)
-+            am.d[i] = 0;
-+        if (!BN_mod_mul_montgomery(rr,&tmp,&am,mont,ctx))
-+            goto err;
-+    } else
-+#endif
-     if (!BN_from_montgomery(rr, &tmp, mont, ctx))
-         goto err;
-     ret = 1;
-Index: openssl/apps/speed.c
-===================================================================
-diff -ru openssl-1.0.1e/apps/spped.c openssl-1.0.1e/apps/speed.c
---- openssl-1.0.1e/apps/speed.c 2011-05-24 17:02:24.000000000 -0700
-+++ openssl-1.0.1e/apps/spped.c 2011-07-27 10:48:17.817470000 -0700
-@@ -1586,8 +1586,7 @@
-             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);
-+                MD5(buf, lengths[j], md5);
-             d = Time_F(STOP);
-             print_result(D_MD5, j, count, d);
-         }
-@@ -1622,8 +1621,7 @@
-             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);
-+                SHA1(buf, lengths[j], sha);
-             d = Time_F(STOP);
-             print_result(D_SHA1, j, count, d);
-         }
-Index: openssl/crypto/aes/Makefile
-===================================================================
---- Makefile	Thu May  2 13:42:37 2013
-+++ Makefile.orig	Thu May  2 13:41:51 2013
-@@ -69,6 +69,9 @@
- aes-sparcv9.s: asm/aes-sparcv9.pl
- 	$(PERL) asm/aes-sparcv9.pl $(CFLAGS) > $@
- 
-+aest4-sparcv9.s: asm/aest4-sparcv9.pl
-+	$(PERL) asm/aest4-sparcv9.pl $(CFLAGS) > $@
-+
- aes-ppc.s:	asm/aes-ppc.pl
- 	$(PERL) asm/aes-ppc.pl $(PERLASM_SCHEME) $@
- 
-Index: openssl/crypto/evp/e_aes.c
-===================================================================
---- e_aes.c    Mon Feb 11 07:26:04 2013
-+++ e_aes.c.56    Thu May  2 14:26:35 2013
-@@ -56,12 +58,11 @@
- # include <assert.h>
- # include <openssl/aes.h>
- # include "evp_locl.h"
--# ifndef OPENSSL_FIPS
- #  include "modes_lcl.h"
- #  include <openssl/rand.h>
-
- typedef struct {
--    AES_KEY ks;
-+    union { double align; AES_KEY ks; } ks;
-     block128_f block;
-     union {
-         cbc128_f cbc;
-@@ -70,7 +69,7 @@
- } EVP_AES_KEY;
-
- typedef struct {
--    AES_KEY ks;                 /* AES key schedule to use */
-+    union { double align; AES_KEY ks; } 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;
-@@ -83,7 +82,7 @@
- } EVP_AES_GCM_CTX;
-
- typedef struct {
--    AES_KEY ks1, ks2;           /* AES key schedules to use */
-+    union { double align; AES_KEY ks; } ks1, ks2;    /* AES key schedules to use */
-     XTS128_CONTEXT xts;
-     void (*stream) (const unsigned char *in,
-                     unsigned char *out, size_t length,
-@@ -92,7 +91,7 @@
- } EVP_AES_XTS_CTX;
-
- typedef struct {
--    AES_KEY ks;                 /* AES key schedule to use */
-+    union { double align; AES_KEY ks; } 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 */
-@@ -155,7 +154,7 @@
-         defined(_M_AMD64)       || defined(_M_X64)      || \
-         defined(__INTEL__)                              )
-
--extern unsigned int OPENSSL_ia32cap_P[2];
-+extern unsigned int OPENSSL_ia32cap_P[];
-
- #   ifdef VPAES_ASM
- #    define VPAES_CAPABLE   (OPENSSL_ia32cap_P[1]&(1<<(41-32)))
-@@ -297,7 +296,7 @@
-     if (!iv && !key)
-         return 1;
-     if (key) {
--        aesni_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks);
-+        aesni_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks);
-         CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f) aesni_encrypt);
-         gctx->ctr = (ctr128_f) aesni_ctr32_encrypt_blocks;
-         /*
-@@ -336,17 +335,17 @@
-     if (key) {
-         /* key_len is two AES keys */
-         if (enc) {
--            aesni_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1);
-+            aesni_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
-             xctx->xts.block1 = (block128_f) aesni_encrypt;
-             xctx->stream = aesni_xts_encrypt;
-         } else {
--            aesni_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1);
-+            aesni_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
-             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);
-+                              ctx->key_len * 4, &xctx->ks2.ks);
-         xctx->xts.block2 = (block128_f) aesni_encrypt;
-
-         xctx->xts.key1 = &xctx->ks1;
-@@ -371,7 +370,7 @@
-     if (!iv && !key)
-         return 1;
-     if (key) {
--        aesni_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks);
-+        aesni_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks.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 :
-@@ -432,6 +431,364 @@
- const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
- { return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; }
-
-+#elif    defined(AES_ASM) && (defined(__sparc) || defined(__sparc__))
-+
-+#include "sparc_arch.h"
-+
-+extern unsigned int OPENSSL_sparcv9cap_P[];
-+
-+#define    SPARC_AES_CAPABLE    (OPENSSL_sparcv9cap_P[1] & CFR_AES)
-+
-+void    aes_t4_set_encrypt_key (const unsigned char *key, int bits,
-+                AES_KEY *ks);
-+void    aes_t4_set_decrypt_key (const unsigned char *key, int bits,
-+                AES_KEY *ks);
-+void    aes_t4_encrypt (const unsigned char *in, unsigned char *out,
-+                const AES_KEY *key);
-+void    aes_t4_decrypt (const unsigned char *in, unsigned char *out,
-+                const AES_KEY *key);
-+/*
-+ * Key-length specific subroutines were chosen for following reason.
-+ * Each SPARC T4 core can execute up to 8 threads which share core's
-+ * resources. Loading as much key material to registers allows to
-+ * minimize references to shared memory interface, as well as amount
-+ * of instructions in inner loops [much needed on T4]. But then having
-+ * non-key-length specific routines would require conditional branches
-+ * either in inner loops or on subroutines' entries. Former is hardly
-+ * acceptable, while latter means code size increase to size occupied
-+ * by multiple key-length specfic subroutines, so why fight?
-+ */
-+void    aes128_t4_cbc_encrypt (const unsigned char *in, unsigned char *out,
-+                size_t len, const AES_KEY *key,
-+                unsigned char *ivec);
-+void    aes128_t4_cbc_decrypt (const unsigned char *in, unsigned char *out,
-+                size_t len, const AES_KEY *key,
-+                unsigned char *ivec);
-+void    aes192_t4_cbc_encrypt (const unsigned char *in, unsigned char *out,
-+                size_t len, const AES_KEY *key,
-+                unsigned char *ivec);
-+void    aes192_t4_cbc_decrypt (const unsigned char *in, unsigned char *out,
-+                size_t len, const AES_KEY *key,
-+                unsigned char *ivec);
-+void    aes256_t4_cbc_encrypt (const unsigned char *in, unsigned char *out,
-+                size_t len, const AES_KEY *key,
-+                unsigned char *ivec);
-+void    aes256_t4_cbc_decrypt (const unsigned char *in, unsigned char *out,
-+                size_t len, const AES_KEY *key,
-+                unsigned char *ivec);
-+void    aes128_t4_ctr32_encrypt (const unsigned char *in, unsigned char *out,
-+                size_t blocks, const AES_KEY *key,
-+                unsigned char *ivec);
-+void    aes192_t4_ctr32_encrypt (const unsigned char *in, unsigned char *out,
-+                size_t blocks, const AES_KEY *key,
-+                unsigned char *ivec);
-+void    aes256_t4_ctr32_encrypt (const unsigned char *in, unsigned char *out,
-+                size_t blocks, const AES_KEY *key,
-+                unsigned char *ivec);
-+
-+static int aes_t4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
-+           const unsigned char *iv, int enc)
-+{
-+    int ret, mode, bits;
-+    EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
-+
-+    mode = ctx->cipher->flags & EVP_CIPH_MODE;
-+    bits = ctx->key_len*8;
-+    if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) && !enc) {
-+            ret = 0;
-+            aes_t4_set_decrypt_key(key, bits, ctx->cipher_data);
-+            dat->block    = (block128_f)aes_t4_decrypt;
-+            switch (bits) {
-+            case 128:
-+            dat->stream.cbc    = mode==EVP_CIPH_CBC_MODE ?
-+                        (cbc128_f)aes128_t4_cbc_decrypt :
-+                        NULL;
-+            break;
-+            case 192:
-+            dat->stream.cbc    = mode==EVP_CIPH_CBC_MODE ?
-+                        (cbc128_f)aes192_t4_cbc_decrypt :
-+                        NULL;
-+            break;
-+            case 256:
-+            dat->stream.cbc    = mode==EVP_CIPH_CBC_MODE ?
-+                        (cbc128_f)aes256_t4_cbc_decrypt :
-+                        NULL;
-+            break;
-+            default:
-+            ret = -1;
-+        }
-+    } else    {
-+            ret = 0;
-+            aes_t4_set_encrypt_key(key, bits, ctx->cipher_data);
-+            dat->block    = (block128_f)aes_t4_encrypt;
-+            switch (bits) {
-+            case 128:
-+            if (mode==EVP_CIPH_CBC_MODE)
-+                dat->stream.cbc    = (cbc128_f)aes128_t4_cbc_encrypt;
-+            else if (mode==EVP_CIPH_CTR_MODE)
-+                dat->stream.ctr = (ctr128_f)aes128_t4_ctr32_encrypt;
-+            else
-+                dat->stream.cbc = NULL;
-+            break;
-+            case 192:
-+            if (mode==EVP_CIPH_CBC_MODE)
-+                dat->stream.cbc    = (cbc128_f)aes192_t4_cbc_encrypt;
-+            else if (mode==EVP_CIPH_CTR_MODE)
-+                dat->stream.ctr = (ctr128_f)aes192_t4_ctr32_encrypt;
-+            else
-+                dat->stream.cbc = NULL;
-+            break;
-+            case 256:
-+            if (mode==EVP_CIPH_CBC_MODE)
-+                dat->stream.cbc    = (cbc128_f)aes256_t4_cbc_encrypt;
-+            else if (mode==EVP_CIPH_CTR_MODE)
-+                dat->stream.ctr = (ctr128_f)aes256_t4_ctr32_encrypt;
-+            else
-+                dat->stream.cbc = NULL;
-+            break;
-+            default:
-+            ret = -1;
-+        }
-+    }
-+
-+    if (ret < 0) {
-+        EVPerr(EVP_F_AES_T4_INIT_KEY,EVP_R_AES_KEY_SETUP_FAILED);
-+        return 0;
-+    }
-+
-+    return 1;
-+}
-+
-+#define aes_t4_cbc_cipher aes_cbc_cipher
-+static int aes_t4_cbc_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
-+    const unsigned char *in, size_t len);
-+
-+#define aes_t4_ecb_cipher aes_ecb_cipher
-+static int aes_t4_ecb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
-+    const unsigned char *in, size_t len);
-+
-+#define aes_t4_ofb_cipher aes_ofb_cipher
-+static int aes_t4_ofb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
-+    const unsigned char *in,size_t len);
-+
-+#define aes_t4_cfb_cipher aes_cfb_cipher
-+static int aes_t4_cfb_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
-+    const unsigned char *in,size_t len);
-+
-+#define aes_t4_cfb8_cipher aes_cfb8_cipher
-+static int aes_t4_cfb8_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
-+    const unsigned char *in,size_t len);
-+
-+#define aes_t4_cfb1_cipher aes_cfb1_cipher
-+static int aes_t4_cfb1_cipher(EVP_CIPHER_CTX *ctx,unsigned char *out,
-+    const unsigned char *in,size_t len);
-+
-+#define aes_t4_ctr_cipher aes_ctr_cipher
-+static int aes_t4_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+        const unsigned char *in, size_t len);
-+
-+static int aes_t4_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) {
-+        int bits = ctx->key_len * 8;
-+        aes_t4_set_encrypt_key(key, bits, &gctx->ks.ks);
-+        CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
-+                (block128_f)aes_t4_encrypt);
-+        switch (bits) {
-+        case 128:
-+            gctx->ctr = (ctr128_f)aes128_t4_ctr32_encrypt;
-+            break;
-+         case 192:
-+            gctx->ctr = (ctr128_f)aes192_t4_ctr32_encrypt;
-+            break;
-+         case 256:
-+            gctx->ctr = (ctr128_f)aes256_t4_ctr32_encrypt;
-+            break;
-+         default:
-+            return 0;
-+     }
-+        /* 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 aes_t4_gcm_cipher aes_gcm_cipher
-+static int aes_t4_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+        const unsigned char *in, size_t len);
-+
-+static int aes_t4_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) {
-+        int bits = ctx->key_len * 4;
-+        /* key_len is two AES keys */
-+        if (enc) {
-+            aes_t4_set_encrypt_key(key, bits, &xctx->ks1.ks);
-+            xctx->xts.block1 = (block128_f)aes_t4_encrypt;
-+#if 0 /* not yet */
-+            switch (bits) {
-+            case 128:
-+                xctx->stream = aes128_t4_xts_encrypt;
-+                break;
-+            case 192:
-+                xctx->stream = aes192_t4_xts_encrypt;
-+                break;
-+            case 256:
-+                xctx->stream = aes256_t4_xts_encrypt;
-+                break;
-+            default:
-+                return 0;
-+            }
-+#endif
-+        } else {
-+            aes_t4_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
-+            xctx->xts.block1 = (block128_f)aes_t4_decrypt;
-+#if 0 /* not yet */
-+            switch (bits) {
-+            case 128:
-+                xctx->stream = aes128_t4_xts_decrypt;
-+                break;
-+            case 192:
-+                xctx->stream = aes192_t4_xts_decrypt;
-+                break;
-+            case 256:
-+                xctx->stream = aes256_t4_xts_decrypt;
-+                break;
-+            default:
-+                return 0;
-+                }
-+#endif
-+            }
-+
-+        aes_t4_set_encrypt_key(key + ctx->key_len/2,
-+                        ctx->key_len * 4, &xctx->ks2.ks);
-+        xctx->xts.block2 = (block128_f)aes_t4_encrypt;
-+
-+        xctx->xts.key1 = &xctx->ks1;
-+    }
-+
-+    if (iv) {
-+        xctx->xts.key2 = &xctx->ks2;
-+        memcpy(ctx->iv, iv, 16);
-+    }
-+
-+    return 1;
-+}
-+
-+#define aes_t4_xts_cipher aes_xts_cipher
-+static int aes_t4_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+        const unsigned char *in, size_t len);
-+
-+static int aes_t4_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) {
-+        int bits = ctx->key_len * 8;
-+        aes_t4_set_encrypt_key(key, bits, &cctx->ks.ks);
-+        CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
-+                    &cctx->ks, (block128_f)aes_t4_encrypt);
-+#if 0 /* not yet */
-+       switch (bits) {
-+        case 128:
-+            cctx->str = enc?(ccm128_f)aes128_t4_ccm64_encrypt :
-+                (ccm128_f)ae128_t4_ccm64_decrypt;
-+            break;
-+        case 192:
-+            cctx->str = enc?(ccm128_f)aes192_t4_ccm64_encrypt :
-+                (ccm128_f)ae192_t4_ccm64_decrypt;
-+            break;
-+        case 256:
-+            cctx->str = enc?(ccm128_f)aes256_t4_ccm64_encrypt :
-+                (ccm128_f)ae256_t4_ccm64_decrypt;
-+            break;
-+        default:
-+            return 0;
-+        }
-+#endif
-+        cctx->key_set = 1;
-+    }
-+    if (iv) {
-+        memcpy(ctx->iv, iv, 15 - cctx->L);
-+        cctx->iv_set = 1;
-+    }
-+    return 1;
-+}
-+
-+#define aes_t4_ccm_cipher aes_ccm_cipher
-+static int aes_t4_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
-+        const unsigned char *in, size_t len);
-+
-+#define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
-+static const EVP_CIPHER aes_t4_##keylen##_##mode = { \
-+    nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \
-+    flags|EVP_CIPH_##MODE##_MODE,    \
-+    aes_t4_init_key,        \
-+    aes_t4_##mode##_cipher,        \
-+    NULL,                \
-+    sizeof(EVP_AES_KEY),        \
-+    NULL,NULL,NULL,NULL }; \
-+static const EVP_CIPHER aes_##keylen##_##mode = { \
-+    nid##_##keylen##_##nmode,blocksize,    \
-+    keylen/8,ivlen, \
-+    flags|EVP_CIPH_##MODE##_MODE,    \
-+    aes_init_key,            \
-+    aes_##mode##_cipher,        \
-+    NULL,                \
-+    sizeof(EVP_AES_KEY),        \
-+    NULL,NULL,NULL,NULL }; \
-+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
-+{ return SPARC_AES_CAPABLE?&aes_t4_##keylen##_##mode:&aes_##keylen##_##mode; }
-+
-+#define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \
-+static const EVP_CIPHER aes_t4_##keylen##_##mode = { \
-+    nid##_##keylen##_##mode,blocksize, \
-+    (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
-+    flags|EVP_CIPH_##MODE##_MODE,    \
-+    aes_t4_##mode##_init_key,    \
-+    aes_t4_##mode##_cipher,        \
-+    aes_##mode##_cleanup,        \
-+    sizeof(EVP_AES_##MODE##_CTX),    \
-+    NULL,NULL,aes_##mode##_ctrl,NULL }; \
-+static const EVP_CIPHER aes_##keylen##_##mode = { \
-+    nid##_##keylen##_##mode,blocksize, \
-+    (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \
-+    flags|EVP_CIPH_##MODE##_MODE,    \
-+    aes_##mode##_init_key,        \
-+    aes_##mode##_cipher,        \
-+    aes_##mode##_cleanup,        \
-+    sizeof(EVP_AES_##MODE##_CTX),    \
-+    NULL,NULL,aes_##mode##_ctrl,NULL }; \
-+const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \
-+{ return SPARC_AES_CAPABLE?&aes_t4_##keylen##_##mode:&aes_##keylen##_##mode; }
-+
- #  else
-
- #   define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
-@@ -480,7 +837,7 @@
-         && !enc)
- #  ifdef BSAES_CAPABLE
-         if (BSAES_CAPABLE && mode == EVP_CIPH_CBC_MODE) {
--            ret = AES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks);
-+            ret = AES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
-             dat->block = (block128_f) AES_decrypt;
-             dat->stream.cbc = (cbc128_f) bsaes_cbc_encrypt;
-         } else
-@@ -487,7 +844,7 @@
- #  endif
- #  ifdef VPAES_CAPABLE
-         if (VPAES_CAPABLE) {
--            ret = vpaes_set_decrypt_key(key, ctx->key_len * 8, &dat->ks);
-+            ret = vpaes_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
-             dat->block = (block128_f) vpaes_decrypt;
-             dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
-                 (cbc128_f) vpaes_cbc_encrypt : NULL;
-@@ -494,7 +851,7 @@
-         } else
- #  endif
-         {
--            ret = AES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks);
-+            ret = AES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
-             dat->block = (block128_f) AES_decrypt;
-             dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
-                 (cbc128_f) AES_cbc_encrypt : NULL;
-@@ -502,7 +859,7 @@
-     } else
- #  ifdef BSAES_CAPABLE
-     if (BSAES_CAPABLE && mode == EVP_CIPH_CTR_MODE) {
--        ret = AES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks);
-+        ret = AES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
-         dat->block = (block128_f) AES_encrypt;
-         dat->stream.ctr = (ctr128_f) bsaes_ctr32_encrypt_blocks;
-     } else
-@@ -508,7 +865,7 @@
- #  endif
- #  ifdef VPAES_CAPABLE
-     if (VPAES_CAPABLE) {
--        ret = vpaes_set_encrypt_key(key, ctx->key_len * 8, &dat->ks);
-+        ret = vpaes_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
-         dat->block = (block128_f) vpaes_encrypt;
-         dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
-             (cbc128_f) vpaes_cbc_encrypt : NULL;
-@@ -515,7 +872,7 @@
-     } else
- #  endif
-     {
--        ret = AES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks);
-+        ret = AES_set_encrypt_key(key, ctx->key_len*8, &dat->ks.ks);
-         dat->block = (block128_f) AES_encrypt;
-         dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ?
-             (cbc128_f) AES_cbc_encrypt : NULL;
-@@ -810,7 +1167,7 @@
-         do {
- #  ifdef BSAES_CAPABLE
-             if (BSAES_CAPABLE) {
--                AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks);
-+                AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks);
-                 CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
-                                    (block128_f) AES_encrypt);
-                 gctx->ctr = (ctr128_f) bsaes_ctr32_encrypt_blocks;
-@@ -819,7 +1176,7 @@
- #  endif
- #  ifdef VPAES_CAPABLE
-             if (VPAES_CAPABLE) {
--                vpaes_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks);
-+                vpaes_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks);
-                 CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
-                                    (block128_f) vpaes_encrypt);
-                 gctx->ctr = NULL;
-@@ -828,7 +1185,7 @@
- #  endif
-                 (void)0;        /* terminate potentially open 'else' */
-
--            AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks);
-+            AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks);
-             CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks,
-                                (block128_f) AES_encrypt);
- #  ifdef AES_CTR_ASM
-@@ -1049,15 +1406,15 @@
- #  ifdef VPAES_CAPABLE
-             if (VPAES_CAPABLE) {
-                 if (enc) {
--                    vpaes_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1);
-+                    vpaes_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
-                     xctx->xts.block1 = (block128_f) vpaes_encrypt;
-                 } else {
--                    vpaes_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1);
-+                    vpaes_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
-                     xctx->xts.block1 = (block128_f) vpaes_decrypt;
-                 }
-
-                 vpaes_set_encrypt_key(key + ctx->key_len / 2,
--                                      ctx->key_len * 4, &xctx->ks2);
-+                                      ctx->key_len * 4, &xctx->ks2.ks);
-                 xctx->xts.block2 = (block128_f) vpaes_encrypt;
-
-                 xctx->xts.key1 = &xctx->ks1;
-@@ -1067,15 +1424,15 @@
-                 (void)0;        /* terminate potentially open 'else' */
-
-             if (enc) {
--                AES_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1);
-+                AES_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
-                 xctx->xts.block1 = (block128_f) AES_encrypt;
-             } else {
--                AES_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1);
-+                AES_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
-                 xctx->xts.block1 = (block128_f) AES_decrypt;
-             }
-
-             AES_set_encrypt_key(key + ctx->key_len / 2,
--                                ctx->key_len * 4, &xctx->ks2);
-+                                ctx->key_len * 4, &xctx->ks2.ks);
-             xctx->xts.block2 = (block128_f) AES_encrypt;
-
-             xctx->xts.key1 = &xctx->ks1;
-@@ -1196,7 +1553,7 @@
-         do {
- #  ifdef VPAES_CAPABLE
-             if (VPAES_CAPABLE) {
--                vpaes_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks);
-+                vpaes_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks.ks);
-                 CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
-                                    &cctx->ks, (block128_f) vpaes_encrypt);
-                 cctx->str = NULL;
-@@ -1204,7 +1561,7 @@
-                 break;
-             }
- #  endif
--            AES_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks);
-+            AES_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks.ks);
-             CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L,
-                                &cctx->ks, (block128_f) AES_encrypt);
-             cctx->str = NULL;
-@@ -1285,5 +1642,4 @@
-                     EVP_CIPH_FLAG_FIPS | CUSTOM_FLAGS)
-     BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, ccm, CCM,
-                     EVP_CIPH_FLAG_FIPS | CUSTOM_FLAGS)
--# endif
- #endif
-Index: openssl/crypto/evp/evp.h
-===================================================================
---- evp.h    Mon Feb 11 07:26:04 2013
-+++ evp.h.new    Thu May  2 14:31:55 2013
-@@ -1325,6 +1325,7 @@
- # 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_T4_INIT_KEY                            178
- # define EVP_F_AES_XTS                                    172
- # define EVP_F_AES_XTS_CIPHER                             175
- # define EVP_F_ALG_MODULE_INIT                            177
-Index: openssl/crypto/evp/evp_err.c
-===================================================================
---- evp_err.c	Mon Feb 11 07:26:04 2013
-+++ evp_err.c.new	Thu May  2 14:33:24 2013
-@@ -73,6 +73,7 @@
-     {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_T4_INIT_KEY), "AES_T4_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"},
--- a/components/openssl/openssl-1.0.1/patches/38_remove_illegal_instruction_calls.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,219 +0,0 @@
-#
-# This patch was developed in house.
-# This is Solaris-specific: not suitable for upstream.
-#
---- openssl-1.0.1g/crypto/sparcv9cap.c.~1~	Thu May  1 13:07:00 2014
-+++ openssl-1.0.1g/crypto/sparcv9cap.c	Thu May  1 13:11:33 2014
-@@ -2,10 +2,10 @@
- #include <stdlib.h>
- #include <string.h>
- #include <setjmp.h>
--#include <signal.h>
- #include <sys/time.h>
- #include <unistd.h>
- #include <openssl/bn.h>
-+#include <sys/auxv.h>
- 
- #include "sparc_arch.h"
- 
-@@ -59,13 +59,8 @@
- }
- 
- unsigned long _sparcv9_rdtick(void);
--void _sparcv9_vis1_probe(void);
- unsigned long _sparcv9_vis1_instrument(void);
--void _sparcv9_vis2_probe(void);
--void _sparcv9_fmadd_probe(void);
- unsigned long _sparcv9_rdcfr(void);
--void _sparcv9_vis3_probe(void);
--unsigned long _sparcv9_random(void);
- #ifndef _BOOT
- size_t _sparcv9_vis1_instrument_bus(unsigned int *,size_t);
- size_t _sparcv9_vis1_instrument_bus2(unsigned int *,size_t,size_t);
-@@ -235,18 +235,11 @@
-
- #else
-
--static sigjmp_buf common_jmp;
--static void common_handler(int sig)
--{
--    siglongjmp(common_jmp, sig);
--}
--
- void OPENSSL_cpuid_setup(void)
- {
-     char *e;
--    struct sigaction common_act, ill_oact, bus_oact;
--    sigset_t all_masked, oset;
-     static int trigger = 0;
-+    uint_t ui = 0;
-
-     if (trigger)
-         return;
-@@ -259,80 +247,40 @@
-         return;
-     }
- 
-+    (void) getisax(&ui, 1);
-+
-     /* Initial value, fits UltraSPARC-I&II... */
--    OPENSSL_sparcv9cap_P[0] = SPARCV9_PREFER_FPU | SPARCV9_TICK_PRIVILEGED;
-+    OPENSSL_sparcv9cap_P[0] = SPARCV9_BLK;
- 
--    sigfillset(&all_masked);
--    sigdelset(&all_masked, SIGILL);
--    sigdelset(&all_masked, SIGTRAP);
--# ifdef SIGEMT
--    sigdelset(&all_masked, SIGEMT);
--# endif
--    sigdelset(&all_masked, SIGFPE);
--    sigdelset(&all_masked, SIGBUS);
--    sigdelset(&all_masked, SIGSEGV);
--    sigprocmask(SIG_SETMASK, &all_masked, &oset);
--
--    memset(&common_act, 0, sizeof(common_act));
--    common_act.sa_handler = common_handler;
--    common_act.sa_mask = all_masked;
--
--    sigaction(SIGILL, &common_act, &ill_oact);
--    sigaction(SIGBUS, &common_act, &bus_oact); /* T1 fails 16-bit ldda [on
--                                                * Linux] */
--
--    if (sigsetjmp(common_jmp, 1) == 0) {
--        _sparcv9_rdtick();
--        OPENSSL_sparcv9cap_P[0] &= ~SPARCV9_TICK_PRIVILEGED;
--    }
--
--    if (sigsetjmp(common_jmp, 1) == 0) {
--        _sparcv9_vis1_probe();
--        OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS1 | SPARCV9_BLK;
-+    if (ui & AV_SPARC_VIS) {
-         /* detect UltraSPARC-Tx, see sparccpud.S for details... */
--        if (_sparcv9_vis1_instrument() >= 12)
--            OPENSSL_sparcv9cap_P[0] &= ~(SPARCV9_VIS1 | SPARCV9_PREFER_FPU);
--        else {
--            _sparcv9_vis2_probe();
--            OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS2;
--        }
-+        if (_sparcv9_vis1_instrument() < 7)
-+            OPENSSL_sparcv9cap_P[0] |= SPARCV9_TICK_PRIVILEGED;
-+        if (_sparcv9_vis1_instrument() < 12) {
-+            OPENSSL_sparcv9cap_P[0] |= (SPARCV9_VIS1 | SPARCV9_PREFER_FPU);
-+            if (ui & AV_SPARC_VIS2)
-+                OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS2;
-+         }
-     }
- 
--    if (sigsetjmp(common_jmp, 1) == 0) {
--        _sparcv9_fmadd_probe();
-+    if (ui & AV_SPARC_FMAF)
-         OPENSSL_sparcv9cap_P[0] |= SPARCV9_FMADD;
--    }
- 
-     /*
-      * VIS3 flag is tested independently from VIS1, unlike VIS2 that is,
-      * because VIS3 defines even integer instructions.
-      */
--    if (sigsetjmp(common_jmp,1) == 0) {
--        _sparcv9_vis3_probe();
--        OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS3;
--    }
-+    if (ui & AV_SPARC_VIS3)
-+            OPENSSL_sparcv9cap_P[0] |= SPARCV9_VIS3;
- 
--    if (sigsetjmp(common_jmp,1) == 0) {
--        (void)_sparcv9_random();
--        OPENSSL_sparcv9cap_P[0] |= SPARCV9_RANDOM;
--    }
-+#define AV_T4_MECHS     (AV_SPARC_AES | AV_SPARC_DES | AV_SPARC_KASUMI | \
-+                         AV_SPARC_CAMELLIA | AV_SPARC_MD5 | AV_SPARC_SHA1 | \
-+                         AV_SPARC_SHA256 | AV_SPARC_SHA512 | AV_SPARC_MPMUL | \
-+                         AV_SPARC_CRC32C)
- 
--    /*
--     * In wait for better solution _sparcv9_rdcfr is masked by
--     * VIS3 flag, because it goes to uninterruptable endless
--     * loop on UltraSPARC II running Solaris. Things might be
--     * different on Linux...
--     */
--    if ((OPENSSL_sparcv9cap_P[0]&SPARCV9_VIS3) &&
--        sigsetjmp(common_jmp, 1) == 0) {
-+    if ((OPENSSL_sparcv9cap_P[0]&SPARCV9_VIS3) && (ui & AV_T4_MECHS))
-         OPENSSL_sparcv9cap_P[1] = (unsigned int)_sparcv9_rdcfr();
--    }
- 
--    sigaction(SIGBUS, &bus_oact, NULL);
--    sigaction(SIGILL, &ill_oact, NULL);
--
--    sigprocmask(SIG_SETMASK, &oset, NULL);
--
-     if (sizeof(size_t) == 8)
-         OPENSSL_sparcv9cap_P[0] |= SPARCV9_64BIT_STACK;
- #ifdef __linux
---- openssl-1.0.1g/crypto/sparccpuid.S.~1~      Thu May  1 13:07:00 2014
-+++ openssl-1.0.1g/crypto/sparccpuid.S  Thu May  1 13:11:33 2014
-@@ -236,16 +236,6 @@
- .type	_sparcv9_rdtick,#function
- .size	_sparcv9_rdtick,.-_sparcv9_rdtick
- 
--.global	_sparcv9_vis1_probe
--.align	8
--_sparcv9_vis1_probe:
--	.word	0x81b00d80	!fxor	%f0,%f0,%f0
--	add	%sp,BIAS+2,%o1
--	retl
--	.word	0xc19a5a40	!ldda	[%o1]ASI_FP16_P,%f0
--.type	_sparcv9_vis1_probe,#function
--.size	_sparcv9_vis1_probe,.-_sparcv9_vis1_probe
--
- ! Probe and instrument VIS1 instruction. Output is number of cycles it
- ! takes to execute rdtick and pair of VIS1 instructions. US-Tx VIS unit
- ! is slow (documented to be 6 cycles on T2) and the core is in-order
-@@ -307,24 +297,6 @@
- .type	_sparcv9_vis1_instrument,#function
- .size	_sparcv9_vis1_instrument,.-_sparcv9_vis1_instrument
- 
--.global	_sparcv9_vis2_probe
--.align	8
--_sparcv9_vis2_probe:
--	retl
--	.word	0x81b00980	!bshuffle	%f0,%f0,%f0
--.type	_sparcv9_vis2_probe,#function
--.size	_sparcv9_vis2_probe,.-_sparcv9_vis2_probe
--
--.global	_sparcv9_fmadd_probe
--.align	8
--_sparcv9_fmadd_probe:
--	.word	0x81b00d80	!fxor	%f0,%f0,%f0
--	.word	0x85b08d82	!fxor	%f2,%f2,%f2
--	retl
--	.word	0x81b80440	!fmaddd	%f0,%f0,%f2,%f0
--.type	_sparcv9_fmadd_probe,#function
--.size	_sparcv9_fmadd_probe,.-_sparcv9_fmadd_probe
--
- .global	_sparcv9_rdcfr
- .align	8
- _sparcv9_rdcfr:
-@@ -333,22 +305,6 @@
- .type	_sparcv9_rdcfr,#function
- .size	_sparcv9_rdcfr,.-_sparcv9_rdcfr
- 
--.global	_sparcv9_vis3_probe
--.align	8
--_sparcv9_vis3_probe:
--	retl
--	.word	0x81b022a0	!xmulx	%g0,%g0,%g0
--.type	_sparcv9_vis3_probe,#function
--.size	_sparcv9_vis3_probe,.-_sparcv9_vis3_probe
--
--.global	_sparcv9_random
--.align	8
--_sparcv9_random:
--	retl
--	.word	0x91b002a0	!random	%o0
--.type	_sparcv9_random,#function
--.size	_sparcv9_random,.-_sparcv9_vis3_probe
--
- .global	OPENSSL_cleanse
- .align	32
- OPENSSL_cleanse:
--- a/components/openssl/openssl-1.0.1/patches/39_internal_tests.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-#
-# Patch developed in-house. Solaris-specific; not suitable for upstream.
-#
-# Remove test 'test_ca' because it depends on directories
-# not present in the build directory. The rest of tests are ok.
-#
---- a/test/Makefile.orig	Thu Apr  2 12:11:12 2015
-+++ b/test/Makefile	Thu Apr  2 12:11:21 2015
-@@ -142,7 +142,7 @@
- 	test_rand test_bn test_ec test_ecdsa test_ecdh \
- 	test_enc test_x509 test_rsa test_crl test_sid \
- 	test_gen test_req test_pkcs7 test_verify test_dh test_dsa \
--	test_ss test_ca test_engine test_evp test_evp_extra test_ssl test_tsa test_ige \
-+	test_ss test_engine test_evp test_evp_extra test_ssl test_tsa test_ige \
- 	test_jpake test_srp test_cms test_heartbeat test_constant_time test_verify_extra \
- 	test_clienthello
- 
- test_evp:
--- a/components/openssl/openssl-1.0.1/patches/40_suppress_v8plus_abi_warnings.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-#
-# Patch developed in-house. Solaris-specific; not suitable for upstream.
-#
-# Suppress warnings about sparcv8+ ABI violation
-# when building T4-specific modules as 32-bit:
-#    v8+ ABI violation: illegal use of %i or %l register as rs1 in "brnz,a" instruction
-# This has been confirmed as a valid usecase and is thus intentional.
-#
---- a/crypto/aes/Makefile.orig	čt dub 30 03:15:03 2015
-+++ b/crypto/aes/Makefile	čt dub 30 03:19:32 2015
-@@ -72,6 +72,9 @@
- aest4-sparcv9.s: asm/aest4-sparcv9.pl
- 	$(PERL) asm/aest4-sparcv9.pl $(CFLAGS) > $@
- 
-+aest4-sparcv9.o: aest4-sparcv9.s
-+	$(AS) $(ASFLAGS) -Wa,-n -o $@ $^
-+
- aes-ppc.s:	asm/aes-ppc.pl
- 	$(PERL) asm/aes-ppc.pl $(PERLASM_SCHEME) $@
- 
---- a/crypto/sha/Makefile.orig	čt dub 30 14:37:32 2015
-+++ b/crypto/sha/Makefile	čt dub 30 14:40:49 2015
-@@ -71,6 +71,8 @@
- sha1-sparcv9.S:	asm/sha1-sparcv9.pl;	$(PERL) asm/sha1-sparcv9.pl $@ $(CFLAGS)
- sha256-sparcv9.S:asm/sha512-sparcv9.pl;	$(PERL) asm/sha512-sparcv9.pl $@ $(CFLAGS)
- sha512-sparcv9.S:asm/sha512-sparcv9.pl;	$(PERL) asm/sha512-sparcv9.pl $@ $(CFLAGS)
-+sha512-sparcv9.o: sha512-sparcv9.S
-+	$(CC) $(CFLAGS) -Wa,-n -c -o $@ $^
- 
- sha1-ppc.s:	asm/sha1-ppc.pl;	$(PERL) asm/sha1-ppc.pl $(PERLASM_SCHEME) $@
- sha256-ppc.s:	asm/sha512-ppc.pl;	$(PERL) asm/sha512-ppc.pl $(PERLASM_SCHEME) $@
---- a/crypto/bn/Makefile.orig	čt dub 30 14:43:20 2015
-+++ b/crypto/bn/Makefile	čt dub 30 14:45:11 2015
-@@ -79,8 +79,12 @@
- 	$(PERL) asm/sparcv9-mont.pl $(CFLAGS) > $@
- vis3-mont.s:		asm/vis3-mont.pl
- 	$(PERL) asm/vis3-mont.pl $(CFLAGS) > $@
-+vis3-mont.o:	vis3-mont.s
-+	$(AS) $(ASFLAGS) -Wa,-n -o $@ $^
- sparct4-mont.S:	asm/sparct4-mont.pl
- 	$(PERL) asm/sparct4-mont.pl $(CFLAGS) > $@
-+sparct4-mont.o:	sparct4-mont.S
-+	$(CC) $(CFLAGS) -Wa,-n -c -o $@ $^
- sparcv9-gf2m.S:	asm/sparcv9-gf2m.pl
- 	$(PERL) asm/sparcv9-gf2m.pl $(CFLAGS) > $@
- 
--- a/components/openssl/openssl-1.0.1/patches/41_uninitialized_ctx.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-#
-# This was developed in house. Upstream notified.
-#
---- openssl-1.0.1m/crypto/evp/evp_enc.c.orig	Tue Jun  2 13:18:15 2015
-+++ openssl-1.0.1m/crypto/evp/evp_enc.c	Tue Jun  2 13:19:19 2015
-@@ -179,6 +179,7 @@
-                 EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE);
-                 return 0;
-             }
-+	    (void) memset(ctx->cipher_data, 0, ctx->cipher->ctx_size);
-         } else {
-             ctx->cipher_data = NULL;
-         }
--- a/components/openssl/openssl-1.0.1/patches/42_rm_sslv2.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,526 +0,0 @@
-#
-# This was developed in house.  Not applicable to the upstream.
-#
---- openssl-1.0.1/ssl/ssl.h	Tue May 26 11:13:15 2015
-+++ openssl-1.0.1/ssl/ssl.h.new	Tue May 26 11:32:09 2015
-@@ -2016,12 +2016,28 @@
- /* This sets the 'default' SSL version that SSL_new() will create */
- int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth);
- 
--# ifndef OPENSSL_NO_SSL2_METHOD
--const SSL_METHOD *SSLv2_method(void); /* SSLv2 */
--const SSL_METHOD *SSLv2_server_method(void); /* SSLv2 */
--const SSL_METHOD *SSLv2_client_method(void); /* SSLv2 */
--# endif
-
-+#ifndef __has_attribute
-+# define __has_attribute(x) 0
-+#endif
-+
-+/* Mark SSLv2_* functions deprecated */
-+#if __has_attribute(deprecated) \
-+    || (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 301)) \
-+    || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5130))
-+# define DEPRECATED __attribute__((deprecated))
-+#else
-+# define DEPRECATED
-+#endif
-+
-+# ifndef OPENSSL_NO_SSL2
-+# ifndef OPENSSL_NO_SSL2_METHOD
-+DEPRECATED const SSL_METHOD *SSLv2_method(void); /* SSLv2 */
-+DEPRECATED const SSL_METHOD *SSLv2_server_method(void); /* SSLv2 */
-+DEPRECATED const SSL_METHOD *SSLv2_client_method(void); /* SSLv2 */
-+# endif
-+# endif
-+
- # ifndef OPENSSL_NO_SSL3_METHOD
- const SSL_METHOD *SSLv3_method(void); /* SSLv3 */
- const SSL_METHOD *SSLv3_server_method(void); /* SSLv3 */
---- openssl-1.0.1/doc/ssl/SSL_CIPHER_get_name.pod	Tue May 26 11:13:15 2015
-+++ openssl-1.0.1/doc/ssl/SSL_CIPHER_get_name.pod.new	Tue May 26 11:32:09 2015
-@@ -25,7 +25,7 @@
- 
- SSL_CIPHER_get_version() returns string which indicates the SSL/TLS protocol
- version that first defined the cipher.
--This is currently B<SSLv2> or B<TLSv1/SSLv3>.
-+This is currently B<TLSv1/SSLv3>.
- In some cases it should possibly return "TLSv1.2" but does not;
- use SSL_CIPHER_description() instead.
- If B<cipher> is NULL, "(NONE)" is returned.
-@@ -56,7 +56,7 @@
- 
- =item <protocol version>
- 
--Protocol version: B<SSLv2>, B<SSLv3>, B<TLSv1.2>. The TLSv1.0 ciphers are
-+Protocol version: B<SSLv3>, B<TLSv1.2>. The TLSv1.0 ciphers are
- flagged with SSLv3. No new ciphers were added by TLSv1.1.
- 
- =item Kx=<key exchange>
---- openssl-1.0.1/doc/ssl/SSL_CTX_new.pod	Tue Mar  1 14:02:53 2016
-+++ openssl-1.0.1/doc/ssl/SSL_CTX_new.pod.new	Tue Mar  1 14:35:59 2016
-@@ -62,12 +62,12 @@
- These are the general-purpose I<version-flexible> SSL/TLS methods.
- The actual protocol version used will be negotiated to the highest version
- mutually supported by the client and the server.
--The supported protocols are SSLv2, SSLv3, TLSv1, TLSv1.1 and TLSv1.2.
-+The supported protocols are SSLv3, TLSv1, TLSv1.1 and TLSv1.2.
- Most applications should use these method, and avoid the version specific
- methods described below.
- 
- The list of protocols available can be further limited using the
--B<SSL_OP_NO_SSLv2>, B<SSL_OP_NO_SSLv3>, B<SSL_OP_NO_TLSv1>,
-+B<SSL_OP_NO_SSLv3>, B<SSL_OP_NO_TLSv1>,
- B<SSL_OP_NO_TLSv1_1> and B<SSL_OP_NO_TLSv1_2> options of the
- L<SSL_CTX_set_options(3)> or L<SSL_set_options(3)> functions.
- Clients should avoid creating "holes" in the set of protocols they support,
-@@ -81,8 +81,6 @@
- Applications should typically use L<SSL_CTX_set_options(3)> in combination with
- the B<SSL_OP_NO_SSLv3> flag to disable negotiation of SSLv3 via the above
- I<version-flexible> SSL/TLS methods.
--The B<SSL_OP_NO_SSLv2> option is set by default, and would need to be cleared
--via L<SSL_CTX_clear_options(3)> in order to enable negotiation of SSLv2.
- 
- =item TLSv1_2_method(), TLSv1_2_server_method(), TLSv1_2_client_method()
- 
-@@ -115,13 +113,7 @@
- 
- =item SSLv2_method(), SSLv2_server_method(), SSLv2_client_method()
- 
--A TLS/SSL connection established with these methods will only understand the
--SSLv2 protocol.  A client will send out SSLv2 client hello messages and will
--also indicate that it only understand SSLv2.  A server will only understand
--SSLv2 client hello messages.  The SSLv2 protocol offers little to no security
--and should not be used.
--As of OpenSSL 1.0.1s, EXPORT ciphers and 56-bit DES are no longer available
--with SSLv2.
-+The SSLv2 protocol offers little to no security and has been deprecated.
- 
- =item DTLSv1_method(), DTLSv1_server_method(), DTLSv1_client_method()
- 
---- openssl-1.0.1/doc/ssl/SSL_CTX_set_cipher_list.pod	Thu Mar 19 06:37:10 2015
-+++ openssl-1.0.1/doc/ssl/SSL_CTX_set_cipher_list.pod.new	Tue May 26 11:38:09 2015
-@@ -54,10 +54,6 @@
- keys), the "no shared cipher" (SSL_R_NO_SHARED_CIPHER) error is generated
- and the handshake will fail.
- 
--If the cipher list does not contain any SSLv2 cipher suites (this is the
--default) then SSLv2 is effectively disabled and neither clients nor servers
--will attempt to use SSLv2.
--
- =head1 RETURN VALUES
- 
- SSL_CTX_set_cipher_list() and SSL_set_cipher_list() return 1 if any cipher
---- openssl-1.0.1/doc/ssl/SSL_CTX_set_generate_session_id.pod	Thu Jan 15 06:43:49 2015
-+++ openssl-1.0.1/doc/ssl/SSL_CTX_set_generate_session_id.pod.new	Tue May 26 11:40:47 2015
-@@ -32,9 +32,8 @@
- 
- When a new session is established between client and server, the server
- generates a session id. The session id is an arbitrary sequence of bytes.
--The length of the session id is 16 bytes for SSLv2 sessions and between
--1 and 32 bytes for SSLv3/TLSv1. The session id is not security critical
--but must be unique for the server. Additionally, the session id is
-+The length of the session id is between 1 and 32 bytes. The session id is not
-+security critical but must be unique for the server. Additionally, the session id is
- transmitted in the clear when reusing the session so it must not contain
- sensitive information.
- 
-@@ -51,12 +50,6 @@
- the callback B<must never> increase B<id_len> or write to the location
- B<id> exceeding the given limit.
- 
--If a SSLv2 session id is generated and B<id_len> is reduced, it will be
--restored after the callback has finished and the session id will be padded
--with 0x00. It is not recommended to change the B<id_len> for SSLv2 sessions.
--The callback can use the L<SSL_get_version(3)|SSL_get_version(3)> function
--to check, whether the session is of type SSLv2.
--
- The location B<id> is filled with 0x00 before the callback is called, so the
- callback may only fill part of the possible length and leave B<id_len>
- untouched while maintaining reproducibility.
-@@ -63,9 +56,8 @@
- 
- Since the sessions must be distinguished, session ids must be unique.
- Without the callback a random number is used, so that the probability
--of generating the same session id is extremely small (2^128 possible ids
--for an SSLv2 session, 2^256 for SSLv3/TLSv1). In order to assure the
--uniqueness of the generated session id, the callback must call
-+of generating the same session id is extremely small (2^256 for SSLv3/TLSv1).
-+In order to assure the uniqueness of the generated session id, the callback must call
- SSL_has_matching_session_id() and generate another id if a conflict occurs.
- If an id conflict is not resolved, the handshake will fail.
- If the application codes e.g. a unique host id, a unique process number, and
-@@ -85,10 +77,6 @@
- the external cache is not tested with SSL_has_matching_session_id()
- and the same race condition applies.
- 
--When calling SSL_has_matching_session_id() for an SSLv2 session with
--reduced B<id_len>, the match operation will be performed using the
--fixed length required and with a 0x00 padded id.
--
- The callback must return 0 if it cannot generate a session id for whatever
- reason and return 1 on success.
- 
-@@ -104,12 +92,7 @@
-                               unsigned int *id_len)
-       {
-       unsigned int count = 0;
--      const char *version;
- 
--      version = SSL_get_version(ssl);
--      if (!strcmp(version, "SSLv2"))
--	  /* we must not change id_len */;
--
-       do      {
-               RAND_pseudo_bytes(id, *id_len);
-               /* Prefix the session_id with the required prefix. NB: If our
---- openssl-1.0.1/doc/ssl/SSL_CTX_set_options.pod	Tue Jan 20 04:33:36 2015
-+++ openssl-1.0.1/doc/ssl/SSL_CTX_set_options.pod.new	Tue May 26 11:41:47 2015
-@@ -63,18 +63,11 @@
- 
- =item SSL_OP_MICROSOFT_SESS_ID_BUG
- 
--www.microsoft.com - when talking SSLv2, if session-id reuse is
--performed, the session-id passed back in the server-finished message
--is different from the one decided upon.
-+As of OpenSSL 1.0.0 this option has no effect.
- 
- =item SSL_OP_NETSCAPE_CHALLENGE_BUG
- 
--Netscape-Commerce/1.12, when talking SSLv2, accepts a 32 byte
--challenge but then appears to only use 16 bytes when generating the
--encryption keys.  Using 16 bytes is ok but it should be ok to use 32.
--According to the SSLv3 spec, one should use 32 bytes for the challenge
--when operating in SSLv2/v3 compatibility mode, but as mentioned above,
--this breaks this server so 16 bytes is the way to go.
-+As of OpenSSL 1.0.0 this option has no effect.
- 
- =item SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
- 
---- openssl-1.0.1/doc/ssl/SSL_get_default_timeout.pod	Thu Jan 15 06:43:49 2015
-+++ openssl-1.0.1/doc/ssl/SSL_get_default_timeout.pod.new	Tue May 26 11:42:15 2015
-@@ -24,7 +24,7 @@
- timeout for the protocol will be used.
- 
- SSL_get_default_timeout() return this hardcoded value, which is 300 seconds
--for all currently supported protocols (SSLv2, SSLv3, and TLSv1).
-+for all currently supported protocols.
- 
- =head1 RETURN VALUES
- 
---- openssl-1.0.1/doc/ssl/SSL_get_version.pod	Thu Jan 15 06:43:49 2015
-+++ openssl-1.0.1/doc/ssl/SSL_get_version.pod.new	Tue May 26 11:42:45 2015
-@@ -21,9 +21,6 @@
- 
- =over 4
- 
--=item SSLv2
--
--The connection uses the SSLv2 protocol.
- 
- =item SSLv3
- 
---- openssl-1.0.1/doc/ssl/SSL_new.pod	Thu Jan 15 06:43:49 2015
-+++ openssl-1.0.1/doc/ssl/SSL_new.pod.new	Tue May 26 11:43:12 2015
-@@ -14,7 +14,7 @@
- 
- SSL_new() creates a new B<SSL> structure which is needed to hold the
- data for a TLS/SSL connection. The new structure inherits the settings
--of the underlying context B<ctx>: connection method (SSLv2/v3/TLSv1),
-+of the underlying context B<ctx>: connection method,
- options, verification settings, timeout settings.
- 
- =head1 RETURN VALUES
---- openssl-1.0.1/doc/ssl/SSL_shutdown.pod	Thu Mar 19 06:37:10 2015
-+++ openssl-1.0.1/doc/ssl/SSL_shutdown.pod.new	Tue May 26 11:43:56 2015
-@@ -60,9 +60,7 @@
- 
- It is therefore recommended, to check the return value of SSL_shutdown()
- and call SSL_shutdown() again, if the bidirectional shutdown is not yet
--complete (return value of the first call is 0). As the shutdown is not
--specially handled in the SSLv2 protocol, SSL_shutdown() will succeed on
--the first call.
-+complete (return value of the first call is 0).
- 
- The behaviour of SSL_shutdown() additionally depends on the underlying BIO. 
- 
---- openssl-1.0.1/doc/ssl/ssl.pod	Tue Mar  1 05:40:03 2016
-+++ openssl-1.0.1/doc/ssl/ssl.pod.new	Tue Mar  1 15:42:46 2016
-@@ -9,7 +9,7 @@
- 
- =head1 DESCRIPTION
- 
--The OpenSSL B<ssl> library implements the Secure Sockets Layer (SSL v2/v3) and
-+The OpenSSL B<ssl> library implements the Secure Sockets Layer (SSL v3) and
- Transport Layer Security (TLS v1) protocols. It provides a rich API which is
- documented here.
- 
-@@ -45,8 +45,8 @@
- =item B<SSL_METHOD> (SSL Method)
- 
- That's a dispatch structure describing the internal B<ssl> library
--methods/functions which implement the various protocol versions (SSLv1, SSLv2
--and TLSv1). It's needed to create an B<SSL_CTX>.
-+methods/functions which implement the various protocol versions (SSLv3,
-+TLSv1, ...). It's needed to create an B<SSL_CTX>.
- 
- =item B<SSL_CIPHER> (SSL Cipher)
- 
-@@ -93,7 +93,7 @@
- 
- =item B<ssl2.h>
- 
--That's the sub header file dealing with the SSLv2 protocol only.
-+That's the sub header file dealing with the deprecated SSLv2 protocol only.
- I<Usually you don't have to include it explicitly because
- it's already included by ssl.h>.
- 
-@@ -105,8 +105,8 @@
- 
- =item B<ssl23.h>
- 
--That's the sub header file dealing with the combined use of the SSLv2 and
--SSLv3 protocols.
-+That's the sub header file dealing with the combined use of the different
-+protocol versions.
- I<Usually you don't have to include it explicitly because
- it's already included by ssl.h>.
- 
-@@ -201,15 +201,15 @@
- =item const SSL_METHOD *B<SSLv2_method>(void);
- 
- Constructor for the SSLv2 SSL_METHOD structure for clients, servers
--or both.
-+or both. (deprecated)
- 
- =item const SSL_METHOD *B<SSLv2_client_method>(void);
- 
--Constructor for the SSLv2 SSL_METHOD structure for clients.
-+Constructor for the SSLv2 SSL_METHOD structure for clients. (deprecated)
- 
- =item const SSL_METHOD *B<SSLv2_server_method>(void);
- 
--Constructor for the SSLv2 SSL_METHOD structure for servers.
-+Constructor for the SSLv2 SSL_METHOD structure for servers. (deprecated)
- 
- =back
- 
-@@ -234,12 +234,12 @@
- =item const char *B<SSL_CIPHER_get_name>(SSL_CIPHER *cipher);
- 
- Return the internal name of I<cipher> as a string. These are the various
--strings defined by the I<SSL2_TXT_xxx>, I<SSL3_TXT_xxx> and I<TLS1_TXT_xxx>
-+strings defined by the I<SSL3_TXT_xxx> and I<TLS1_TXT_xxx>
- definitions in the header files.
- 
- =item char *B<SSL_CIPHER_get_version>(SSL_CIPHER *cipher);
- 
--Returns a string like "C<TLSv1/SSLv3>" or "C<SSLv2>" which indicates the
-+Returns a string like "C<TLSv1/SSLv3>" which indicates the
- SSL/TLS protocol version to which I<cipher> belongs (i.e. where it was defined
- in the specification the first time).
- 
---- openssl-1.0.1/doc/apps/ciphers.pod	Tue Mar  1 05:40:03 2016
-+++ openssl-1.0.1/doc/apps/ciphers.pod.new	Tue Mar  1 15:28:28 2016
-@@ -9,7 +9,6 @@
- B<openssl> B<ciphers>
- [B<-v>]
- [B<-V>]
--[B<-ssl2>]
- [B<-ssl3>]
- [B<-tls1>]
- [B<cipherlist>]
-@@ -27,12 +26,9 @@
- =item B<-v>
- 
- Verbose option. List ciphers with a complete description of
--protocol version (SSLv2 or SSLv3; the latter includes TLS), key exchange,
-+protocol version, key exchange,
- authentication, encryption and mac algorithms used along with any key size
- restrictions and whether the algorithm is classed as an "export" cipher.
--Note that without the B<-v> option, ciphers may seem to appear twice
--in a cipher list; this is when similar ciphers are available for
--SSL v2 and for SSL v3/TLS v1.
- 
- =item B<-V>
- 
-@@ -42,10 +38,6 @@
- 
- This lists ciphers compatible with any of SSLv3, TLSv1, TLSv1.1 or TLSv1.2.
- 
--=item B<-ssl2>
--
--Only include SSLv2 ciphers.
--
- =item B<-h>, B<-?>
- 
- Print a brief usage message.
-@@ -255,9 +247,9 @@
- ciphers suites using FORTEZZA key exchange, authentication, encryption or all
- FORTEZZA algorithms. Not implemented.
- 
--=item B<TLSv1.2>, B<TLSv1>, B<SSLv3>, B<SSLv2>
-+=item B<TLSv1.2>, B<TLSv1>, B<SSLv3>
- 
--TLS v1.2, TLS v1.0, SSL v3.0 or SSL v2.0 cipher suites respectively. Note:
-+TLS v1.2, TLS v1.0, or SSL v3.0 cipher suites respectively. Note:
- there are no ciphersuites specific to TLS v1.1.
- 
- =item B<AES128>, B<AES256>, B<AES>
-@@ -578,16 +570,6 @@
-  TLS_PSK_WITH_AES_128_CBC_SHA              PSK-AES128-CBC-SHA
-  TLS_PSK_WITH_AES_256_CBC_SHA              PSK-AES256-CBC-SHA
- 
--=head2 Deprecated SSL v2.0 cipher suites.
--
-- SSL_CK_RC4_128_WITH_MD5                 RC4-MD5
-- SSL_CK_RC4_128_EXPORT40_WITH_MD5        Not implemented.
-- SSL_CK_RC2_128_CBC_WITH_MD5             RC2-CBC-MD5
-- SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5    Not implemented.
-- SSL_CK_IDEA_128_CBC_WITH_MD5            IDEA-CBC-MD5
-- SSL_CK_DES_64_CBC_WITH_MD5              Not implemented.
-- SSL_CK_DES_192_EDE3_CBC_WITH_MD5        DES-CBC3-MD5
--
- =head1 NOTES
- 
- The non-ephemeral DH modes are currently unimplemented in OpenSSL
---- openssl-1.0.1/doc/apps/s_client.pod	Tue Mar  1 05:40:03 2016
-+++ openssl-1.0.1/doc/apps/s_client.pod.new	Tue Mar  1 15:37:40 2016
-@@ -32,10 +32,8 @@
- [B<-ign_eof>]
- [B<-no_ign_eof>]
- [B<-quiet>]
--[B<-ssl2>]
- [B<-ssl3>]
- [B<-tls1>]
--[B<-no_ssl2>]
- [B<-no_ssl3>]
- [B<-no_tls1>]
- [B<-bugs>]
-@@ -197,7 +195,7 @@
- given as a hexadecimal number without leading 0x, for example -psk
- 1a2b3c4d.
- 
--=item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2>
-+=item B<-ssl3>, B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2>
- 
- These options require or disable the use of the specified SSL or TLS protocols.
- By default the initial handshake uses a I<version-flexible> method which will
-@@ -215,10 +213,6 @@
- supported cipher in the list sent by the client. See the B<ciphers>
- command for more information.
- 
--=item B<-serverpref>
--
--use the server's cipher preferences; only used for SSLV2.
--
- =item B<-starttls protocol>
- 
- send the protocol-specific message(s) to switch to TLS for communication.
-@@ -295,8 +289,8 @@
- then an HTTP command can be given such as "GET /" to retrieve a web page.
- 
- If the handshake fails then there are several possible causes, if it is
--nothing obvious like no client certificate then the B<-bugs>, B<-ssl2>,
--B<-ssl3>, B<-tls1>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1> options can be tried
-+nothing obvious like no client certificate then the B<-bugs>,
-+B<-ssl3>, B<-tls1>, B<-no_ssl3>, B<-no_tls1> options can be tried
- in case it is a buggy server. In particular you should play with these
- options B<before> submitting a bug report to an OpenSSL mailing list.
- 
-@@ -318,10 +312,6 @@
- If there are problems verifying a server certificate then the
- B<-showcerts> option can be used to show the whole chain.
- 
--Since the SSLv23 client hello cannot include compression methods or extensions
--these will only be supported if its use is disabled, for example by using the
--B<-no_sslv2> option.
--
- The B<s_client> utility is a test tool and is designed to continue the
- handshake after any certificate verification errors. As a result it will
- accept any certificate chain (trusted or not) sent by the peer. None test
---- openssl-1.0.1/doc/apps/s_server.pod	Tue Mar  1 05:40:03 2016
-+++ openssl-1.0.1/doc/apps/s_server.pod.new	Tue Mar  1 15:38:50 2016
-@@ -39,10 +39,8 @@
- [B<-serverpref>]
- [B<-quiet>]
- [B<-no_tmp_rsa>]
--[B<-ssl2>]
- [B<-ssl3>]
- [B<-tls1>]
--[B<-no_ssl2>]
- [B<-no_ssl3>]
- [B<-no_tls1>]
- [B<-no_dhe>]
-@@ -221,7 +219,7 @@
- given as a hexadecimal number without leading 0x, for example -psk
- 1a2b3c4d.
- 
--=item B<-ssl2>, B<-ssl3>, B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-no_ssl2>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2>
-+=item B<-ssl3>, B<-tls1>, B<-tls1_1>, B<-tls1_2>, B<-no_ssl3>, B<-no_tls1>, B<-no_tls1_1>, B<-no_tls1_2>
- 
- These options require or disable the use of the specified SSL or TLS protocols.
- By default the initial handshake uses a I<version-flexible> method which will
---- openssl-1.0.1/doc/apps/s_time.pod	Thu Jan 15 06:43:49 2015
-+++ openssl-1.0.1/doc/apps/s_time.pod.new	Tue May 26 12:20:09 2015
-@@ -19,7 +19,6 @@
- [B<-verify depth>]
- [B<-nbio>]
- [B<-time seconds>]
--[B<-ssl2>]
- [B<-ssl3>]
- [B<-bugs>]
- [B<-cipher cipherlist>]
-@@ -92,18 +90,17 @@
- 
- turns on non-blocking I/O.
- 
--=item B<-ssl2>, B<-ssl3>
-+=item B<-ssl3>
- 
- these options disable the use of certain SSL or TLS protocols. By default
- the initial handshake uses a method which should be compatible with all
--servers and permit them to use SSL v3, SSL v2 or TLS as appropriate.
-+servers and permit them to use SSL v3 or TLS as appropriate.
- The timing program is not as rich in options to turn protocols on and off as
- the L<s_client(1)|s_client(1)> program and may not connect to all servers.
- 
- Unfortunately there are a lot of ancient and broken servers in use which
- cannot handle this technique and will fail to connect. Some servers only
--work if TLS is turned off with the B<-ssl3> option; others
--will only support SSL v2 and may need the B<-ssl2> option.
-+work if TLS is turned off with the B<-ssl3> option.
- 
- =item B<-bugs>
- 
-@@ -137,7 +122,7 @@
- for details.
- 
- If the handshake fails then there are several possible causes, if it is
--nothing obvious like no client certificate then the B<-bugs>, B<-ssl2>,
-+nothing obvious like no client certificate then the B<-bugs>,
- B<-ssl3> options can be tried
- in case it is a buggy server. In particular you should play with these
- options B<before> submitting a bug report to an OpenSSL mailing list.
---- openssl-1.0.1/doc/apps/sess_id.pod	Thu Jan 15 06:43:49 2015
-+++ openssl-1.0.1/doc/apps/sess_id.pod.new	Tue May 26 12:21:07 2015
-@@ -91,7 +91,7 @@
- 
- =item B<Protocol>
- 
--this is the protocol in use TLSv1, SSLv3 or SSLv2.
-+this is the protocol in use TLSv1.2, TLSv1.1, TLSv1 or SSLv3.
- 
- =item B<Cipher>
- 
-@@ -110,10 +110,6 @@
- 
- this is the SSL session master key.
- 
--=item B<Key-Arg>
--
--the key argument, this is only used in SSL v2.
--
- =item B<Start Time>
- 
- this is the session start time represented as an integer in standard Unix format.
--- a/components/openssl/openssl-1.0.1/patches/45-use-srln.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-# This patch fixes the invalid use of 64-bit instruction (srlx) by 32-bit
-# applications.  This patch is from the following commit in the upstream:
-#    https://github.com/openssl/openssl/commit/f198cc43a0eca4bf1a8e7f60c51af560f4346dc8
---- a/crypto/des/asm/dest4-sparcv9.pl	2016-08-04 14:20:26.610683970 -0700
-+++ b/crypto/des/asm/dest4-sparcv9.pl	2016-08-04 14:22:33.339076315 -0700
-@@ -96,7 +96,7 @@
- des_t4_cbc_encrypt:
- 	cmp		$len, 0
- 	be,pn		$::size_t_cc, .Lcbc_abort
--	nop
-+	srln		$len, 0, $len		! needed on v8+, "nop" on v9
- 	ld		[$ivec + 0], %f0	! load ivec
- 	ld		[$ivec + 4], %f1
- 
-@@ -197,7 +197,7 @@
- des_t4_cbc_decrypt:
- 	cmp		$len, 0
- 	be,pn		$::size_t_cc, .Lcbc_abort
--	nop
-+	srln		$len, 0, $len		! needed on v8+, "nop" on v9
- 	ld		[$ivec + 0], %f2	! load ivec
- 	ld		[$ivec + 4], %f3
- 
-@@ -305,7 +305,7 @@
- des_t4_ede3_cbc_encrypt:
- 	cmp		$len, 0
- 	be,pn		$::size_t_cc, .Lcbc_abort
--	nop
-+	srln		$len, 0, $len		! needed on v8+, "nop" on v9
- 	ld		[$ivec + 0], %f0	! load ivec
- 	ld		[$ivec + 4], %f1
- 
-@@ -457,7 +457,7 @@
- des_t4_ede3_cbc_decrypt:
- 	cmp		$len, 0
- 	be,pn		$::size_t_cc, .Lcbc_abort
--	nop
-+	srln		$len, 0, $len		! needed on v8+, "nop" on v9
- 	ld		[$ivec + 0], %f2	! load ivec
- 	ld		[$ivec + 4], %f3
- 
---- a/crypto/perlasm/sparcv9_modes.pl	2016-08-04 14:24:29.877624460 -0700
-+++ b/crypto/perlasm/sparcv9_modes.pl	2016-08-04 14:27:18.552931245 -0700
-@@ -37,6 +37,7 @@
- 	save		%sp, -$::frame, %sp
- 	cmp		$len, 0
- 	be,pn		$::size_t_cc, .L${bits}_cbc_enc_abort
-+	srln		$len, 0, $len		! needed on v8+, "nop" on v9
- 	sub		$inp, $out, $blk_init	! $inp!=$out
- ___
- $::code.=<<___ if (!$::evp);
-@@ -254,6 +255,7 @@
- 	save		%sp, -$::frame, %sp
- 	cmp		$len, 0
- 	be,pn		$::size_t_cc, .L${bits}_cbc_dec_abort
-+	srln		$len, 0, $len		! needed on v8+, "nop" on v9
- 	sub		$inp, $out, $blk_init	! $inp!=$out
- ___
- $::code.=<<___ if (!$::evp);
-@@ -613,6 +615,7 @@
- .align	32
- ${alg}${bits}_t4_ctr32_encrypt:
- 	save		%sp, -$::frame, %sp
-+	srln		$len, 0, $len		! needed on v8+, "nop" on v9
- 
- 	prefetch	[$inp], 20
- 	prefetch	[$inp + 63], 20
-@@ -916,6 +919,7 @@
- .align	32
- ${alg}${bits}_t4_xts_${dir}crypt:
- 	save		%sp, -$::frame-16, %sp
-+	srln		$len, 0, $len		! needed on v8+, "nop" on v9
- 
- 	mov		$ivec, %o0
- 	add		%fp, $::bias-16, %o1
--- a/components/openssl/openssl-1.0.1/patches/47_xmpp_detection.patch	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-# The patch is based on the following commit from the upstream:
-# https://github.com/openssl/openssl/commit/4e48c77572a9a96a301e362a3646cd3cc7eca0f9 
-# The fix is patched until the new version becomes available
-# from the upstream.
---- a/apps/s_client.c
-+++ b/apps/s_client.c
-@@ -1640,8 +1640,8 @@
-                    "xmlns='jabber:client' to='%s' version='1.0'>", host);
-         seen = BIO_read(sbio, mbuf, BUFSIZZ);
-         mbuf[seen] = 0;
--        while (!strstr
--               (mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'")) {
-+        while (!strstr(mbuf, "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'") &&
-+               !strstr(mbuf, "<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"")) {
-             if (strstr(mbuf, "/stream:features>"))
-                 goto shut;
-             seen = BIO_read(sbio, mbuf, BUFSIZZ);
--- a/components/openssl/openssl-1.0.1/wanboot-openssl/wanboot-stubs.c	Wed Oct 12 06:26:22 2016 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
- */
-
-/* Content of this file is only needed for wanboot. */
-#ifdef	_BOOT
-
-#include <sys/types.h>
-#include <dirent.h>
-#include <errno.h>
-#include <stddef.h>
-
-/*
- * In OpenSSL 0.9.7 the EVP_read_pw_string now calls into the new "ui"
- * routines of 0.9.7, which is not compiled in the standalone, so it is
- * stubbed out here to avoid having to add a bunch of #ifndef's elsewhere.
- */
-/* ARGSUSED */
-int
-EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt, int
-    verify)
-{
-	return (-1); /* failure */
-}
-
-/*
- * In standalone issetugid() is always false.
- */
-int
-OPENSSL_issetugid(void)
-{
-	return (1);
-}
-
-/*
- * Directory routines -- currently, the only consumer of these interfaces
- * is $SRC/common/openssl/ssl/ssl_cert.c, and it has fallback code in the
- * case of failure, so we just fail opendir() and stub out the rest.  At
- * some point, we may need to provide a real implementation.
- */
-/* ARGSUSED */
-DIR *
-opendir(const char *dirname)
-{
-	errno = EACCES;
-	return (NULL);
-}
-
-/* ARGSUSED */
-struct dirent *
-readdir(DIR *dirp)
-{
-	return (NULL);
-}
-
-/* ARGSUSED */
-int
-closedir(DIR *dirp)
-{
-	return (0);
-}
-
-/*
- * Atoi is used on multiple places in libcrypto.
- * This implementation is taken from stand-alone libsock library:
- * usr/src/stand/lib/sock/sock_test.c
- * Alternative solution: just extern it here, wanboot has -lsock anyway.
- */
-#ifndef	isdigit
-#define	isdigit(c) ((c) >= '0' && (c) <= '9')
-#endif
-
-#ifndef	isspace
-#define	isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || \
-		    (c) == '\r' || (c) == '\f' || (c) == '\013')
-#endif
-int
-atoi(const char *p)
-{
-	int n;
-	int c = *p++, neg = 0;
-
-	while (isspace(c)) {
-		c = *p++;
-	}
-	if (!isdigit(c)) {
-		switch (c) {
-		case '-':
-			neg++;
-			/* FALLTHROUGH */
-		case '+':
-			c = *p++;
-		}
-	}
-	for (n = 0; isdigit(c); c = *p++) {
-		n *= 10; /* two steps to avoid unnecessary overflow */
-		n += '0' - c; /* accum neg to avoid surprises at MAX */
-	}
-	return (neg ? n : -n);
-}
-
-#endif	/* _BOOT */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/openssl-default/Makefile	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,427 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+#
+include ../../../make-rules/shared-macros.mk
+
+COMPONENT_NAME =	openssl
+# When new version of OpenSSL comes in, you must update both COMPONENT_VERSION
+# and IPS_COMPONENT_VERSION.
+# When upgrading OpenSSL, please, DON'T FORGET TO TEST WANBOOT too. 
+# For more information about wanboot-openssl testing, please refer to
+# ../README.
+COMPONENT_VERSION =	1.0.2j
+# Version for IPS. It is easier to do it manually than convert the letter to a
+# number while taking into account that there might be no letter at all.
+IPS_COMPONENT_VERSION = 1.0.2.10
+COMPONENT_PROJECT_URL=	http://www.openssl.org/
+COMPONENT_SRC =		$(COMPONENT_NAME)-$(COMPONENT_VERSION)
+COMPONENT_ARCHIVE =	$(COMPONENT_SRC).tar.gz
+COMPONENT_ARCHIVE_HASH=	\
+    sha256:e7aff292be21c259c6af26469c7a9b3ba26e9abaaffd325e3dccc9785256c431
+COMPONENT_ARCHIVE_URL =	$(COMPONENT_PROJECT_URL)source/$(COMPONENT_ARCHIVE)
+COMPONENT_BUGDB=	library/openssl
+
+TPNO=			31866
+
+# Clone the patch files to the patches-all dir.
+# COPY_COMMON_FILES is there so that rsync is called as soon as
+# the Makefile is parsed.
+PATCH_DIR=patches-all
+CLEAN_PATHS += $(PATCH_DIR)
+COPY_COMMON_FILES:= $(shell rsync -ac ../common/patches/ patches/ $(PATCH_DIR))
+
+include $(WS_MAKE_RULES)/prep.mk
+include $(WS_MAKE_RULES)/configure.mk
+include $(WS_MAKE_RULES)/ips.mk
+include $(WS_MAKE_RULES)/lint-libraries.mk
+
+PATH=$(SPRO_VROOT)/bin:/usr/bin:/usr/gnu/bin:/usr/perl5/bin
+ifeq   ($(strip $(PARFAIT_BUILD)),yes)
+PATH=$(PARFAIT_TOOLS):$(SPRO_VROOT)/bin:/usr/bin:/usr/perl5/bin
+endif
+
+# Variant of OpenSSL for wanboot is built in build/sparcv9-wanboot.
+BUILD_DIR_WANBOOT = $(BUILD_DIR)/$(MACH64)-wanboot
+
+# OpenSSL does not use autoconf but its own configure system.
+CONFIGURE_SCRIPT = $(SOURCE_DIR)/Configure
+
+# Ignore default CC_FOR_BUILD, CC, and CXX in CONFIGURE_ENV.
+CONFIGURE_ENV += CC_FOR_BUILD=
+CONFIGURE_ENV += CC=
+CONFIGURE_ENV += CXX=
+
+# This is to force OpenSSL's Configure script to use gmake for 'make links'. 
+# Otherwise it fails with:
+#     mksh: Fatal error in reader: Unmatched `(' on line
+CONFIGURE_ENV += MAKE="$(GMAKE)"
+
+# Used in the configure options below.
+PKCS11_LIB32 = /usr/lib/libpkcs11.so.1
+PKCS11_LIB64 = /usr/lib/64/libpkcs11.so.1
+ENGINESDIR_32 = /lib/openssl/engines
+ENGINESDIR_64 = /lib/openssl/engines/64
+
+# Configure options common to both regular OpenSSL and OpenSSL for wanboot.
+CONFIGURE_OPTIONS =  -DSOLARIS_OPENSSL -DNO_WINDOWS_BRAINDEATH
+CONFIGURE_OPTIONS += --openssldir=/etc/openssl
+CONFIGURE_OPTIONS += --prefix=/usr
+# We use OpenSSL install code for installing only manual pages and we do that
+# for 32-bit version only.
+CONFIGURE_OPTIONS += --install_prefix=$(PROTO_DIR)
+CONFIGURE_OPTIONS += no-ec
+CONFIGURE_OPTIONS += no-ecdh
+CONFIGURE_OPTIONS += no-ecdsa
+CONFIGURE_OPTIONS += no-rc3
+CONFIGURE_OPTIONS += no-rc5
+CONFIGURE_OPTIONS += no-mdc2
+CONFIGURE_OPTIONS += no-idea
+CONFIGURE_OPTIONS += no-hw_4758_cca
+CONFIGURE_OPTIONS += no-hw_aep
+CONFIGURE_OPTIONS += no-hw_atalla
+CONFIGURE_OPTIONS += no-hw_chil
+CONFIGURE_OPTIONS += no-hw_gmp
+CONFIGURE_OPTIONS += no-hw_ncipher
+CONFIGURE_OPTIONS += no-hw_nuron
+CONFIGURE_OPTIONS += no-hw_padlock
+CONFIGURE_OPTIONS += no-hw_sureware
+CONFIGURE_OPTIONS += no-hw_ubsec
+CONFIGURE_OPTIONS += no-hw_cswift
+
+# MD2 is not enabled by default in OpensSSL but some software we have in
+# Userland needs it. One example is nmap.
+CONFIGURE_OPTIONS += enable-md2
+CONFIGURE_OPTIONS += no-seed
+
+# We don't ship GOST engine.
+CONFIGURE_OPTIONS += no-gost
+
+# Disable SSLv2 protocol
+CONFIGURE_OPTIONS += no-ssl2
+
+# We use both no-whirlpool and no-whrlpool since there is an inconsistency in
+# the OpenSSL code and one needs both to build OpenSSL successfully with
+# Whirlpool implementation removed.
+CONFIGURE_OPTIONS += no-whirlpool
+CONFIGURE_OPTIONS += no-whrlpool
+
+# Some additional options needed for our engines.
+CONFIGURE_OPTIONS += --pk11-libname=$(PKCS11_LIB$(BITS))
+CONFIGURE_OPTIONS += --enginesdir=$(ENGINESDIR_$(BITS))
+
+# We define our own compiler and linker option sets for Solaris. See Configure
+# for more information.
+CONFIGURE_OPTIONS32_i386 =	solaris-x86-cc-sunw
+CONFIGURE_OPTIONS32_sparc =	solaris-sparcv9-cc-sunw
+CONFIGURE_OPTIONS64_i386 =	solaris64-x86_64-cc-sunw
+CONFIGURE_OPTIONS64_sparc =	solaris64-sparcv9-cc-sunw
+
+# Options specific to regular build.
+# They must not be specified as common, as they cannot be overridden.
+$(BUILD_DIR)/$(MACH32)/.configured:	CONFIGURE_OPTIONS += threads
+$(BUILD_DIR)/$(MACH64)/.configured:	CONFIGURE_OPTIONS += threads
+$(BUILD_DIR)/$(MACH32)/.configured:	CONFIGURE_OPTIONS += shared
+$(BUILD_DIR)/$(MACH64)/.configured:	CONFIGURE_OPTIONS += shared
+$(BUILD_DIR)/$(MACH32)/.configured:	CONFIGURE_OPTIONS += shared
+$(BUILD_DIR)/$(MACH64)/.configured:	CONFIGURE_OPTIONS += shared
+$(BUILD_DIR)/$(MACH32)/.configured:	CONFIGURE_OPTIONS += \
+	$(CONFIGURE_OPTIONS32_$(MACH))
+$(BUILD_DIR)/$(MACH64)/.configured:	CONFIGURE_OPTIONS += \
+	$(CONFIGURE_OPTIONS64_$(MACH))
+
+# OpenSSL for wanboot specific options
+$(BUILD_DIR_WANBOOT)/.configured:	BITS=64
+$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += -DNO_CHMOD
+$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += -D_BOOT
+$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += -DOPENSSL_NO_DTLS1
+$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += -DOPENSSL_NO_HEARTBEATS
+$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += -DOPENSSL_NO_SRP
+$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += no-cast
+$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += no-dso
+$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += no-rc4
+$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += no-ripemd
+$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += no-hw
+$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += no-threads
+$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += no-shared
+$(BUILD_DIR_WANBOOT)/.configured:	CONFIGURE_OPTIONS += \
+	solaris64-sparcv9-cc-sunw-wanboot
+
+# OpenSSL has its own configure system which must be run from the fully
+# populated source code directory. However, the Userland configuration phase is
+# run from the build directory. So, we must get the full source code into the
+# build directory.
+COMPONENT_PRE_CONFIGURE_ACTION = \
+    ( $(CLONEY) $(SOURCE_DIR) $(BUILD_DIR)/$(MACH$(BITS)); )
+
+$(BUILD_DIR_WANBOOT)/.configured:	COMPONENT_PRE_CONFIGURE_ACTION = \
+	    ( $(CLONEY) $(SOURCE_DIR) $(BUILD_DIR_WANBOOT); )
+
+# We deliver only one opensslconf.h file which must be suitable for both 32 and
+# 64 bits. Depending on the configuration option, OpenSSL's Configure script
+# creates opensslconf.h for either 32 or 64 bits. A patch makes the resulting
+# header file usable on both architectures. The patch was generated against the
+# opensslconf.h version from the 32 bit build.
+COMPONENT_POST_CONFIGURE_ACTION = \
+    ( [ $(BITS) -eq 32 ] && $(GPATCH) -p1 $(@D)/crypto/opensslconf.h \
+      patches-post-config/opensslconf.patch; cd $(@D); $(MAKE) depend; )
+
+# We do not ship our engines as patches since it would be more difficult to
+# update the files which have been under continuous development. We rather copy
+# the files to the right directories.
+# Same holds for wanboot-stubs.c, which stubs out several functions, that are
+# not available in the stand-alone environment of wanboot.
+COMPONENT_PRE_BUILD_ACTION = \
+    ( echo "Cloning engines..."; \
+      $(LN) -fs $(COMPONENT_DIR)/../common/engines/pkcs11/*.[ch]	$(@D)/engines; \
+      $(LN) -fs $(COMPONENT_DIR)/wanboot-openssl/wanboot-stubs.c	$(@D)/crypto; )
+
+# Enable ASLR for this component
+ASLR_MODE =	$(ASLR_ENABLE)
+
+# OpenSSL for wanboot is built on sparc only.
+ifeq ($(MACH), sparc)
+BUILD_64 +=	$(BUILD_DIR_WANBOOT)/.built
+endif
+
+configure:	$(CONFIGURE_32_and_64)
+
+build:		$(BUILD_32_and_64)
+
+# Object files for wanboot-openssl.o have to be listed explicitly.
+WANBOOT_OBJS =  \
+    crypto/aes/aes-sparcv9.o crypto/aes/aes_cbc.o crypto/aes/aes_core.o \
+    crypto/aes/aes_misc.o crypto/aes/aes_wrap.o crypto/aes/aest4-sparcv9.o \
+    crypto/asn1/a_bitstr.o \
+    crypto/asn1/a_bool.o crypto/asn1/a_bytes.o crypto/asn1/a_d2i_fp.o \
+    crypto/asn1/a_digest.o crypto/asn1/a_dup.o crypto/asn1/a_enum.o \
+    crypto/asn1/a_gentm.o crypto/asn1/a_i2d_fp.o crypto/asn1/a_int.o \
+    crypto/asn1/a_mbstr.o crypto/asn1/a_object.o crypto/asn1/a_octet.o \
+    crypto/asn1/a_print.o crypto/asn1/a_set.o crypto/asn1/a_sign.o \
+    crypto/asn1/a_strex.o crypto/asn1/a_strnid.o crypto/asn1/a_time.o \
+    crypto/asn1/a_type.o crypto/asn1/a_utctm.o crypto/asn1/a_utf8.o \
+    crypto/asn1/a_verify.o crypto/asn1/ameth_lib.o crypto/asn1/asn1_err.o \
+    crypto/asn1/asn1_gen.o crypto/asn1/asn1_lib.o crypto/asn1/asn1_par.o \
+    crypto/asn1/asn_mime.o crypto/asn1/asn_pack.o crypto/asn1/bio_asn1.o \
+    crypto/asn1/bio_ndef.o crypto/asn1/d2i_pr.o crypto/asn1/evp_asn1.o \
+    crypto/asn1/f_int.o crypto/asn1/f_string.o crypto/asn1/i2d_pr.o \
+    crypto/asn1/nsseq.o crypto/asn1/p5_pbe.o crypto/asn1/p5_pbev2.o \
+    crypto/asn1/p8_pkey.o crypto/asn1/t_pkey.o crypto/asn1/t_x509.o \
+    crypto/asn1/t_x509a.o crypto/asn1/tasn_dec.o crypto/asn1/tasn_enc.o \
+    crypto/asn1/tasn_fre.o crypto/asn1/tasn_new.o crypto/asn1/tasn_prn.o \
+    crypto/asn1/tasn_typ.o crypto/asn1/tasn_utl.o crypto/asn1/x_algor.o \
+    crypto/asn1/x_attrib.o crypto/asn1/x_bignum.o crypto/asn1/x_crl.o \
+    crypto/asn1/x_exten.o crypto/asn1/x_info.o crypto/asn1/x_long.o \
+    crypto/asn1/x_name.o crypto/asn1/x_pkey.o crypto/asn1/x_pubkey.o \
+    crypto/asn1/x_req.o crypto/asn1/x_sig.o crypto/asn1/x_spki.o \
+    crypto/asn1/x_val.o crypto/asn1/x_x509.o crypto/asn1/x_x509a.o \
+    crypto/bf/bf_cfb64.o crypto/bf/bf_ecb.o crypto/bf/bf_enc.o \
+    crypto/bf/bf_ofb64.o crypto/bf/bf_skey.o crypto/bio/b_dump.o \
+    crypto/bio/b_print.o crypto/bio/bf_buff.o crypto/bio/bio_err.o \
+    crypto/bio/bio_lib.o crypto/bio/bss_file.o crypto/bio/bss_mem.o \
+    crypto/bio/bss_null.o crypto/bio/bss_sock.o crypto/bn/bn-sparcv9.o \
+    crypto/bn/bn_add.o crypto/bn/bn_blind.o crypto/bn/bn_ctx.o \
+    crypto/bn/bn_div.o crypto/bn/bn_err.o crypto/bn/bn_exp.o \
+    crypto/bn/bn_exp2.o crypto/bn/bn_gcd.o crypto/bn/bn_lib.o \
+    crypto/bn/bn_mod.o crypto/bn/bn_mont.o crypto/bn/bn_mul.o \
+    crypto/bn/bn_prime.o crypto/bn/bn_print.o crypto/bn/bn_rand.o \
+    crypto/bn/bn_recp.o crypto/bn/bn_shift.o crypto/bn/bn_sqr.o \
+    crypto/bn/bn_word.o crypto/bn/sparcv9-mont.o crypto/bn/sparcv9a-mont.o \
+    crypto/bn/sparct4-mont.o crypto/bn/vis3-mont.o \
+    crypto/buffer/buf_err.o crypto/buffer/buf_str.o crypto/buffer/buffer.o \
+    crypto/camellia/camellia.o crypto/camellia/cmll_cbc.o \
+    crypto/camellia/cmll_cfb.o crypto/camellia/cmll_ecb.o \
+    crypto/camellia/cmll_misc.o crypto/camellia/cmll_ofb.o \
+    crypto/camellia/cmll_utl.o crypto/camellia/cmllt4-sparcv9.o \
+    crypto/cmac/cm_ameth.o crypto/cmac/cm_pmeth.o \
+    crypto/cmac/cmac.o crypto/cms/cms_asn1.o crypto/cms/cms_att.o \
+    crypto/cms/cms_dd.o crypto/cms/cms_enc.o crypto/cms/cms_env.o \
+    crypto/cms/cms_err.o crypto/cms/cms_io.o crypto/cms/cms_lib.o \
+    crypto/cms/cms_pwri.o crypto/cms/cms_sd.o crypto/comp/c_zlib.o \
+    crypto/comp/comp_err.o crypto/comp/comp_lib.o crypto/conf/conf_api.o \
+    crypto/conf/conf_def.o crypto/conf/conf_err.o crypto/conf/conf_lib.o \
+    crypto/conf/conf_mod.o crypto/cpt_err.o crypto/cryptlib.o \
+    crypto/des/cfb64ede.o crypto/des/cfb64enc.o crypto/des/cfb_enc.o \
+    crypto/des/des_enc-sparc.o crypto/des/ecb3_enc.o crypto/des/ecb_enc.o \
+    crypto/des/ofb64ede.o crypto/des/ofb64enc.o crypto/des/dest4-sparcv9.o \
+    crypto/des/set_key.o \
+    crypto/des/xcbc_enc.o crypto/dh/dh_ameth.o crypto/dh/dh_asn1.o \
+    crypto/dh/dh_check.o crypto/dh/dh_err.o crypto/dh/dh_gen.o \
+    crypto/dh/dh_key.o crypto/dh/dh_lib.o crypto/dh/dh_pmeth.o \
+    crypto/dsa/dsa_ameth.o crypto/dsa/dsa_asn1.o crypto/dsa/dsa_err.o \
+    crypto/dsa/dsa_gen.o crypto/dsa/dsa_key.o crypto/dsa/dsa_lib.o \
+    crypto/dsa/dsa_ossl.o crypto/dsa/dsa_pmeth.o crypto/dsa/dsa_sign.o \
+    crypto/dsa/dsa_vrf.o crypto/dso/dso_lib.o crypto/dso/dso_null.o \
+    crypto/dso/dso_openssl.o crypto/engine/eng_ctrl.o crypto/engine/eng_err.o \
+    crypto/engine/eng_init.o crypto/engine/eng_lib.o crypto/engine/eng_list.o \
+    crypto/engine/eng_pkey.o crypto/engine/eng_table.o \
+    crypto/engine/tb_asnmth.o crypto/engine/tb_cipher.o crypto/engine/tb_dh.o \
+    crypto/engine/tb_digest.o crypto/engine/tb_dsa.o \
+    crypto/engine/tb_pkmeth.o crypto/engine/tb_rand.o crypto/engine/tb_rsa.o \
+    crypto/err/err.o crypto/err/err_all.o crypto/err/err_prn.o \
+    crypto/evp/bio_b64.o crypto/evp/bio_enc.o crypto/evp/bio_md.o \
+    crypto/evp/c_all.o crypto/evp/c_allc.o crypto/evp/c_alld.o \
+    crypto/evp/digest.o crypto/evp/e_aes.o crypto/evp/e_aes_cbc_hmac_sha1.o \
+    crypto/evp/e_bf.o crypto/evp/e_camellia.o crypto/evp/e_des.o \
+    crypto/evp/e_des3.o crypto/evp/e_null.o crypto/evp/e_rc2.o \
+    crypto/evp/e_xcbc_d.o crypto/evp/encode.o crypto/evp/evp_enc.o \
+    crypto/evp/evp_err.o crypto/evp/evp_key.o crypto/evp/evp_lib.o \
+    crypto/evp/evp_pbe.o crypto/evp/evp_pkey.o crypto/evp/m_dss.o \
+    crypto/evp/m_dss1.o crypto/evp/m_md4.o crypto/evp/m_md5.o \
+    crypto/evp/m_sha.o crypto/evp/m_sha1.o crypto/evp/m_sigver.o \
+    crypto/evp/names.o crypto/evp/p5_crpt.o crypto/evp/p5_crpt2.o \
+    crypto/evp/p_lib.o crypto/evp/p_sign.o crypto/evp/p_verify.o \
+    crypto/evp/pmeth_fn.o crypto/evp/pmeth_gn.o crypto/evp/pmeth_lib.o \
+    crypto/ex_data.o crypto/hmac/hm_ameth.o crypto/hmac/hm_pmeth.o \
+    crypto/hmac/hmac.o crypto/lhash/lhash.o crypto/md4/md4_dgst.o \
+    crypto/md5/md5-sparcv9.o \
+    crypto/md5/md5_dgst.o crypto/mem.o crypto/mem_dbg.o crypto/modes/cbc128.o \
+    crypto/modes/ccm128.o crypto/modes/cfb128.o crypto/modes/ctr128.o \
+    crypto/modes/gcm128.o crypto/modes/ghash-sparcv9.o crypto/modes/ofb128.o \
+    crypto/modes/wrap128.o crypto/modes/xts128.o crypto/o_dir.o \
+    crypto/o_init.o crypto/o_time.o \
+    crypto/objects/o_names.o crypto/objects/obj_dat.o \
+    crypto/objects/obj_err.o crypto/objects/obj_lib.o \
+    crypto/objects/obj_xref.o crypto/ocsp/ocsp_asn.o crypto/ocsp/ocsp_err.o \
+    crypto/pem/pem_all.o crypto/pem/pem_err.o crypto/pem/pem_info.o \
+    crypto/pem/pem_lib.o crypto/pem/pem_oth.o crypto/pem/pem_pk8.o \
+    crypto/pem/pem_pkey.o crypto/pem/pem_x509.o crypto/pem/pem_xaux.o \
+    crypto/pkcs12/p12_add.o crypto/pkcs12/p12_asn.o crypto/pkcs12/p12_attr.o \
+    crypto/pkcs12/p12_crpt.o crypto/pkcs12/p12_decr.o crypto/pkcs12/p12_key.o \
+    crypto/pkcs12/p12_mutl.o crypto/pkcs12/p12_p8d.o crypto/pkcs12/p12_p8e.o \
+    crypto/pkcs12/p12_utl.o crypto/pkcs12/pk12err.o crypto/pkcs7/pk7_asn1.o \
+    crypto/pkcs7/pk7_attr.o crypto/pkcs7/pk7_doit.o crypto/pkcs7/pk7_lib.o \
+    crypto/pkcs7/pkcs7err.o crypto/pqueue/pqueue.o crypto/rand/md_rand.o \
+    crypto/rand/rand_err.o crypto/rand/rand_lib.o crypto/rand/rand_unix.o \
+    crypto/rand/randfile.o crypto/rc2/rc2_cbc.o crypto/rc2/rc2_ecb.o \
+    crypto/rc2/rc2_skey.o crypto/rc2/rc2cfb64.o crypto/rc2/rc2ofb64.o \
+    crypto/rsa/rsa_ameth.o crypto/rsa/rsa_asn1.o crypto/rsa/rsa_crpt.o \
+    crypto/rsa/rsa_eay.o crypto/rsa/rsa_err.o crypto/rsa/rsa_gen.o \
+    crypto/rsa/rsa_lib.o crypto/rsa/rsa_none.o crypto/rsa/rsa_oaep.o \
+    crypto/rsa/rsa_pk1.o crypto/rsa/rsa_pmeth.o crypto/rsa/rsa_pss.o \
+    crypto/rsa/rsa_saos.o crypto/rsa/rsa_sign.o crypto/rsa/rsa_ssl.o \
+    crypto/rsa/rsa_x931.o crypto/sha/sha1-sparcv9.o crypto/sha/sha1dgst.o \
+    crypto/sha/sha256-sparcv9.o crypto/sha/sha256.o \
+    crypto/sha/sha512-sparcv9.o crypto/sha/sha512.o crypto/sha/sha_dgst.o \
+    crypto/sparccpuid.o crypto/sparcv9cap.o crypto/srp/srp_lib.o \
+    crypto/srp/srp_vfy.o crypto/stack/stack.o crypto/ts/ts_err.o \
+    crypto/txt_db/txt_db.o crypto/ui/ui_err.o crypto/wanboot-stubs.o \
+    crypto/x509/by_dir.o crypto/x509/by_file.o crypto/x509/x509_att.o \
+    crypto/x509/x509_cmp.o crypto/x509/x509_d2.o crypto/x509/x509_def.o \
+    crypto/x509/x509_err.o crypto/x509/x509_ext.o crypto/x509/x509_lu.o \
+    crypto/x509/x509_obj.o crypto/x509/x509_req.o crypto/x509/x509_trs.o \
+    crypto/x509/x509_txt.o crypto/x509/x509_v3.o crypto/x509/x509_vfy.o \
+    crypto/x509/x509_vpm.o crypto/x509/x509cset.o \
+    crypto/x509/x509name.o crypto/x509/x509rset.o \
+    crypto/x509/x509type.o crypto/x509/x_all.o crypto/x509v3/pcy_cache.o \
+    crypto/x509v3/pcy_data.o crypto/x509v3/pcy_lib.o crypto/x509v3/pcy_map.o \
+    crypto/x509v3/pcy_node.o crypto/x509v3/pcy_tree.o crypto/x509v3/v3_akey.o \
+    crypto/x509v3/v3_akeya.o crypto/x509v3/v3_alt.o crypto/x509v3/v3_bcons.o \
+    crypto/x509v3/v3_bitst.o crypto/x509v3/v3_conf.o crypto/x509v3/v3_cpols.o \
+    crypto/x509v3/v3_crld.o crypto/x509v3/v3_enum.o crypto/x509v3/v3_extku.o \
+    crypto/x509v3/v3_genn.o crypto/x509v3/v3_ia5.o crypto/x509v3/v3_info.o \
+    crypto/x509v3/v3_int.o crypto/x509v3/v3_lib.o crypto/x509v3/v3_ncons.o \
+    crypto/x509v3/v3_ocsp.o crypto/x509v3/v3_pci.o crypto/x509v3/v3_pcia.o \
+    crypto/x509v3/v3_pcons.o crypto/x509v3/v3_pku.o crypto/x509v3/v3_pmaps.o \
+    crypto/x509v3/v3_prn.o crypto/x509v3/v3_purp.o \
+    crypto/x509v3/v3_scts.o crypto/x509v3/v3_skey.o \
+    crypto/x509v3/v3_sxnet.o crypto/x509v3/v3_utl.o crypto/x509v3/v3err.o \
+    ssl/s3_both.o ssl/s3_clnt.o ssl/s3_enc.o ssl/s3_lib.o ssl/s3_pkt.o \
+    ssl/ssl_algs.o ssl/ssl_asn1.o ssl/ssl_cert.o ssl/ssl_ciph.o ssl/ssl_err.o \
+    ssl/ssl_err2.o ssl/ssl_lib.o ssl/ssl_rsa.o ssl/ssl_sess.o ssl/t1_enc.o \
+    ssl/t1_lib.o ssl/t1_reneg.o ssl/d1_srtp.o ssl/s3_cbc.o ssl/t1_clnt.o
+
+# Linking of openssl bits for wanboot.
+# Interface for wanboot is specified in mapfile.wanboot. Object files are
+# compiled to have functions in separate sections, unused sections get
+# discarded.
+CREATE_BIG_OBJECT_FILE = ( \
+    cd $(BUILD_DIR_WANBOOT); \
+    $(LD) -o wanboot-openssl.o -r -M../../mapfile.wanboot -Breduce \
+        -zdiscard-unused=sections,files -zguidance \
+        $(WANBOOT_OBJS); \
+    )
+
+$(BUILD_DIR_WANBOOT)/.built:	COMPONENT_POST_BUILD_ACTION = \
+    ($(CREATE_BIG_OBJECT_FILE); )
+
+# OpenSSL uses sections man[1357] by default so we must create the man
+# directories we use for OpenSSL man pages in Solaris. Note that we patch the
+# OpenSSL man page install script to use the correct directories.
+MANDIR_SECTIONS =  $(PROTO_DIR)/usr/share/man/man1openssl
+MANDIR_SECTIONS += $(PROTO_DIR)/usr/share/man/man3openssl
+MANDIR_SECTIONS += $(PROTO_DIR)/usr/share/man/man5openssl
+MANDIR_SECTIONS += $(PROTO_DIR)/usr/share/man/man7openssl
+
+# We must create man page directories manually since we patched OpenSSL install
+# code to install into manXopenssl instead of manX. Also, OpenSSL does not
+# install into <dir>/$(MACH64) for 64-bit install so no such directory is
+# created and Userland install code would fail when installing lint libraries.
+COMPONENT_PRE_INSTALL_ACTION = ( $(MKDIR) $(MANDIR_SECTIONS); \
+    $(MKDIR) $(PROTO_DIR)/usr/lib/$(MACH64); )
+
+# The install_docs target will install man pages into $(PROTO_DIR)/$(MANDIR). We
+# also add /usr/perl5/bin to PATH so that OpenSSL install code can locate the
+# system pod2man. If not set, OpenSSL make would use an internal implementation
+# from the tarball which would corrupt some man pages.
+COMPONENT_INSTALL_ARGS += PATH=$(PATH) MANDIR=/usr/share/man
+
+WANBOOT_TO      = $(PROTO_DIR)/lib/openssl/wanboot/$(MACH64)
+
+# We could run OpenSSL install code for 32 bits only to process header files and
+# manual pages. However, lint libraries depend on install stamps so we run
+# install for 64 bit as well. Note that we must take built binary files from
+# build directories, not from the proto area which contains whatever was
+# installed first.
+# OpenSSL for wanboot is built on sparc only.
+ifeq ($(MACH), sparc)
+install:	$(INSTALL_32_and_64) $(BUILD_DIR_WANBOOT)/.built
+	$(MKDIR) -p $(WANBOOT_TO);
+	$(CP) $(BUILD_DIR_WANBOOT)/wanboot-openssl.o $(WANBOOT_TO);
+else
+install:	$(INSTALL_32_and_64)
+endif
+
+# We need to modify the default lint flags to include patched opensslconf.h from
+# the build directory. If we do not do that, lint will complain about md2.h
+# which is not enabled by default but it is in our opensslconf.h.
+LFLAGS_32 := -I$(BUILD_DIR_32)/include $(LINT_FLAGS) -lsoftcrypto
+LFLAGS_64 := -I$(BUILD_DIR_64)/include $(LINT_FLAGS) -lsoftcrypto
+
+# Set modified lint flags for our lint library targets.
+$(BUILD_DIR_32)/llib-lcrypto.ln: LINT_FLAGS=$(LFLAGS_32) -I$(PROTOUSRINCDIR)
+$(BUILD_DIR_32)/llib-lssl.ln: LINT_FLAGS=$(LFLAGS_32) -I$(PROTOUSRINCDIR)
+$(BUILD_DIR_64)/llib-lcrypto.ln: LINT_FLAGS=$(LFLAGS_64) -I$(PROTOUSRINCDIR)
+$(BUILD_DIR_64)/llib-lssl.ln: LINT_FLAGS=$(LFLAGS_64) -I$(PROTOUSRINCDIR)
+
+# There are also separate STC test suites 'openssl' and 'openssl-engine'
+# for regression testing. These internal tests are unit tests only.
+COMPONENT_TEST_TARGETS = test
+test:		$(TEST_32_and_64)
+
+system-test:    $(SYSTEM_TESTS_NOT_IMPLEMENTED)
+
+
+REQUIRED_PACKAGES += developer/build/makedepend
+REQUIRED_PACKAGES += network/rsync
+REQUIRED_PACKAGES += system/library
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/openssl-default/llib-lcrypto	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,83 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* LINTLIBRARY */
+/* PROTOLIB1 */
+
+#include <openssl/aes.h>
+#include <openssl/asn1.h>
+#include <openssl/asn1_mac.h>
+#include <openssl/asn1t.h>
+#include <openssl/bio.h>
+#include <openssl/blowfish.h>
+#include <openssl/bn.h>
+#include <openssl/buffer.h>
+#include <openssl/camellia.h>
+#include <openssl/cms.h>
+#include <openssl/comp.h>
+#include <openssl/conf.h>
+#include <openssl/conf_api.h>
+#include <openssl/crypto.h>
+#include <openssl/des.h>
+#include <openssl/dh.h>
+#include <openssl/dsa.h>
+#include <openssl/dso.h>
+#include <openssl/e_os2.h>
+#include <openssl/ebcdic.h>
+#include <openssl/engine.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/krb5_asn.h>
+#include <openssl/kssl.h>
+#include <openssl/lhash.h>
+#include <openssl/md2.h>
+#include <openssl/md4.h>
+#include <openssl/md5.h>
+#include <openssl/modes.h>
+#include <openssl/obj_mac.h>
+#include <openssl/objects.h>
+#include <openssl/opensslconf.h>
+#include <openssl/opensslv.h>
+#include <openssl/pem.h>
+#include <openssl/pem2.h>
+#include <openssl/pkcs12.h>
+#include <openssl/pkcs7.h>
+#include <openssl/pqueue.h>
+#include <openssl/rand.h>
+#include <openssl/ripemd.h>
+#include <openssl/rsa.h>
+#include <openssl/safestack.h>
+#include <openssl/sha.h>
+#include <openssl/stack.h>
+#include <openssl/symhacks.h>
+#include <openssl/ts.h>
+#include <openssl/txt_db.h>
+#include <openssl/ui.h>
+#include <openssl/ui_compat.h>
+#include <openssl/x509.h>
+#include <openssl/x509_vfy.h>
+#include <openssl/x509v3.h>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/openssl-default/llib-lssl	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,33 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* LINTLIBRARY */
+/* PROTOLIB1 */
+
+#include <openssl/ssl.h>
+#include <openssl/ssl2.h>
+#include <openssl/ssl23.h>
+#include <openssl/ssl3.h>
+#include <openssl/tls1.h>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/openssl-default/mapfile.wanboot	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,127 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+#
+
+#
+# This file defines interface requirements of wanboot on OpenSSL.
+#
+
+$mapfile_version 2
+SYMBOL_SCOPE {
+		ERR_clear_error;
+		SSL_CTX_set_default_passwd_cb;
+		SSL_load_error_strings;
+		EVP_PKEY_free;
+		SSL_get_peer_certificate;
+		SSL_CIPHER_get_name;
+		sk_value;
+		RAND_load_file;
+		X509_NAME_oneline;
+		SSL_write;
+		X509_NAME_get_text_by_NID;
+		OPENSSL_uni2asc;
+		SSL_CTX_set_default_passwd_cb_userdata;
+		SSL_CTX_use_PrivateKey_file;
+		OPENSSL_asc2uni;
+		SSL_get_error;
+		ASN1_UTF8STRING_free;
+		ASN1_mbstring_copy;
+		ERR_error_string;
+		PKCS12_unpack_p7data;
+		X509_free;
+		ERR_get_error;
+		ERR_put_error;
+		PKCS12_free;
+		ASN1_UTF8STRING_new;
+		OPENSSL_add_all_algorithms_noconf;
+		OBJ_nid2obj;
+		PKCS12_SAFEBAG_free;
+		ASN1_STRING_free;
+		sk_delete;
+		OBJ_obj2nid;
+		SSL_CTX_set_verify_depth;
+		PKCS8_PRIV_KEY_INFO_free;
+		SSL_set_connect_state;
+		sk_pop_free;
+		BIO_s_file;
+		SSL_set_fd;
+		SSL_CTX_use_PrivateKey;
+		ASN1_STRING_to_UTF8;
+		PKCS12_certbag2x509;
+		PKCS7_free;
+		PKCS12_decrypt_skey;
+		BIO_new;
+		RAND_status;
+		sk_num;
+		SSL_get_verify_result;
+		SSL_free;
+		SSL_read;
+		SSL_new;
+		SSLv3_client_method;
+		TLSv1_2_client_method;
+		X509_check_private_key;
+		SSL_CTX_new;
+		ASN1_TYPE_set;
+		ASN1_TYPE_new;
+		ERR_peek_error;
+		CRYPTO_free;
+		SSL_CTX_load_verify_locations;
+		PKCS12_unpack_authsafes;
+		X509_ATTRIBUTE_new;
+		PKCS12_unpack_p7encdata;
+		sk_push;
+		SSL_connect;
+		SSL_shutdown;
+		SSL_CTX_use_certificate_file;
+		PKCS12_get_attr_gen;
+		X509_verify_cert_error_string;
+		X509_ATTRIBUTE_free;
+		X509_alias_set1;
+		PKCS12_verify_mac;
+		ASN1_TIME_print;
+		SSL_CTX_use_certificate;
+		SSL_get_ciphers;
+		SSL_CTX_ctrl;
+		SSL_CTX_free;
+		X509_keyid_set1;
+		ERR_load_strings;
+		EVP_EncodeBlock;
+		ASN1_TYPE_free;
+		sk_new_null;
+		SSL_get_current_cipher;
+		ASN1_STRING_cmp;
+		ASN1_STRING_set;
+		ERR_get_next_error_library;
+		EVP_PKCS82PKEY;
+		X509_get_issuer_name;
+		CRYPTO_malloc;
+		BIO_ctrl;
+		BIO_free;
+		X509_STORE_add_cert;
+		ASN1_STRING_type_new;
+		SSL_CTX_set_cipher_list;
+		X509_get_subject_name;
+		SSL_library_init;
+		d2i_PKCS12_fp;
+	local:
+		*;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/openssl-default/openssl-default.license	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,127 @@
+
+  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. Actually both licenses are BSD-style
+  Open Source licenses. In case of any license issues related to OpenSSL
+  please contact [email protected].
+
+  OpenSSL License
+  ---------------
+
+/* ====================================================================
+ * Copyright (c) 1998-2016 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    [email protected].
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+ Original SSLeay License
+ -----------------------
+
+/* Copyright (C) 1995-1998 Eric Young ([email protected])
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young ([email protected]).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson ([email protected]).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young ([email protected])"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson ([email protected])"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/openssl-default/openssl-default.p5m	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,2222 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+#
+
+<transform file path=usr.*/man/.+ -> default mangler.man.stability uncommitted>
+set name=pkg.fmri \
+    value=pkg:/library/security/openssl@$(IPS_COMPONENT_VERSION),$(BUILD_VERSION)
+set name=pkg.summary \
+    value="OpenSSL - a Toolkit for Secure Sockets Layer (SSL v2/v3) and Transport Layer (TLS v1) protocols and general purpose cryptographic library"
+set name=pkg.description \
+    value="OpenSSL is a full-featured toolkit implementing the Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1) protocols as well as a full-strength general purpose cryptography library."
+set name=pkg.human-version value=$(COMPONENT_VERSION)
+set name=com.oracle.info.description value=OpenSSL
+set name=com.oracle.info.tpno value=$(TPNO)
+set name=info.classification value=org.opensolaris.category.2008:System/Security
+set name=info.source-url value=$(COMPONENT_ARCHIVE_URL)
+set name=info.upstream-url value=$(COMPONENT_PROJECT_URL)
+set name=org.opensolaris.arc-caseid value=PSARC/2011/025
+set name=org.opensolaris.consolidation value=$(CONSOLIDATION)
+dir  path=etc/openssl/certs group=sys
+
+# Basic directories, links, and a configuration file.
+file etc/openssl/openssl.cnf path=etc/openssl/default/openssl.cnf group=sys \
+    mode=0644 preserve=true
+file path=etc/openssl/openssl.cnf group=sys mode=0644 \
+    original_name=SUNWopenssl:etc/sfw/openssl/openssl.cnf preserve=true
+dir  path=etc/openssl/private group=sys mode=0700
+link path=etc/sfw/openssl target=../openssl
+link path=lib/$(MACH64)/libcrypto.so target=libcrypto.so.1.0.0
+
+# Mediator links for 64-bit libraries
+link path=lib/$(MACH64)/libcrypto.so.1.0.0 \
+    target=../openssl/default/$(MACH64)/libcrypto.so.1.0.0 mediator=openssl \
+    mediator-implementation=default mediator-priority=vendor
+link path=lib/$(MACH64)/libssl.so target=libssl.so.1.0.0
+link path=lib/$(MACH64)/libssl.so.1.0.0 \
+    target=../openssl/default/$(MACH64)/libssl.so.1.0.0 mediator=openssl \
+    mediator-implementation=default mediator-priority=vendor
+link path=lib/$(MACH64)/llib-lcrypto \
+    target=../openssl/default/$(MACH64)/llib-lcrypto mediator=openssl \
+    mediator-implementation=default mediator-priority=vendor
+link path=lib/$(MACH64)/llib-lcrypto.ln \
+    target=../openssl/default/$(MACH64)/llib-lcrypto.ln mediator=openssl \
+    mediator-implementation=default mediator-priority=vendor
+link path=lib/$(MACH64)/llib-lssl \
+    target=../openssl/default/$(MACH64)/llib-lssl mediator=openssl \
+    mediator-implementation=default mediator-priority=vendor
+link path=lib/$(MACH64)/llib-lssl.ln \
+    target=../openssl/default/$(MACH64)/llib-lssl.ln mediator=openssl \
+    mediator-implementation=default mediator-priority=vendor
+link path=lib/libcrypto.so target=libcrypto.so.1.0.0
+
+# Mediator links for 32-bit libraries
+link path=lib/libcrypto.so.1.0.0 target=openssl/default/libcrypto.so.1.0.0 \
+    mediator=openssl mediator-implementation=default mediator-priority=vendor
+link path=lib/libssl.so target=libssl.so.1.0.0
+link path=lib/libssl.so.1.0.0 target=openssl/default/libssl.so.1.0.0 \
+    mediator=openssl mediator-implementation=default mediator-priority=vendor
+link path=lib/llib-lcrypto target=openssl/default/llib-lcrypto \
+    mediator=openssl mediator-implementation=default mediator-priority=vendor
+link path=lib/llib-lcrypto.ln target=openssl/default/llib-lcrypto.ln \
+    mediator=openssl mediator-implementation=default mediator-priority=vendor
+link path=lib/llib-lssl target=openssl/default/llib-lssl mediator=openssl \
+    mediator-implementation=default mediator-priority=vendor
+link path=lib/llib-lssl.ln target=openssl/default/llib-lssl.ln \
+    mediator=openssl mediator-implementation=default mediator-priority=vendor
+
+# Commands.
+file $(MACH32)/apps/openssl path=lib/openssl/default/$(MACH32)/openssl \
+    owner=root group=bin mode=0555
+link path=lib/openssl/default/$(MACH64)/libcrypto.so target=libcrypto.so.1.0.0
+file $(MACH64)/libcrypto.so.1.0.0 \
+    path=lib/openssl/default/$(MACH64)/libcrypto.so.1.0.0
+link path=lib/openssl/default/$(MACH64)/libssl.so target=libssl.so.1.0.0
+file $(MACH64)/libssl.so.1.0.0 \
+    path=lib/openssl/default/$(MACH64)/libssl.so.1.0.0 owner=root group=bin \
+    mode=0555
+file llib-lcrypto path=lib/openssl/default/$(MACH64)/llib-lcrypto
+file $(MACH64)/llib-lcrypto.ln \
+    path=lib/openssl/default/$(MACH64)/llib-lcrypto.ln
+file llib-lssl path=lib/openssl/default/$(MACH64)/llib-lssl
+file $(MACH64)/llib-lssl.ln path=lib/openssl/default/$(MACH64)/llib-lssl.ln
+link path=lib/openssl/default/64 target=$(MACH64)
+file etc/openssl/misc/CA.pl path=lib/openssl/default/CA.pl
+link path=lib/openssl/default/engines/$(MACH64)/libpk11.so target=libpk11.so.1
+
+# 64 bit libraries, lint libraries, and engines.
+file $(MACH64)/engines/libpk11.so \
+    path=lib/openssl/default/engines/$(MACH64)/libpk11.so.1 owner=root \
+    group=bin mode=0555
+link path=lib/openssl/default/engines/libpk11.so target=libpk11.so.1
+
+# 32 bit libraries, lint libraries, and engines.
+file $(MACH32)/engines/libpk11.so \
+    path=lib/openssl/default/engines/libpk11.so.1 owner=root group=bin
+link path=lib/openssl/default/libcrypto.so target=libcrypto.so.1.0.0
+file $(MACH32)/libcrypto.so.1.0.0 path=lib/openssl/default/libcrypto.so.1.0.0
+link path=lib/openssl/default/libssl.so target=libssl.so.1.0.0
+file $(MACH32)/libssl.so.1.0.0 path=lib/openssl/default/libssl.so.1.0.0 \
+    owner=root group=bin mode=0555
+file llib-lcrypto path=lib/openssl/default/llib-lcrypto
+file $(MACH32)/llib-lcrypto.ln path=lib/openssl/default/llib-lcrypto.ln
+file llib-lssl path=lib/openssl/default/llib-lssl
+file $(MACH32)/llib-lssl.ln path=lib/openssl/default/llib-lssl.ln
+file $(MACH64)/apps/openssl path=lib/openssl/default/openssl owner=root \
+    group=bin mode=0555
+dir  path=lib/openssl/engines group=sys mode=0755
+dir  path=lib/openssl/engines/$(MACH64) group=sys mode=0755
+link path=lib/openssl/engines/$(MACH64)/libpk11.so target=libpk11.so.1
+link path=lib/openssl/engines/$(MACH64)/libpk11.so.1 \
+    target=../../default/engines/$(MACH64)/libpk11.so.1 mediator=openssl \
+    mediator-implementation=default mediator-priority=vendor
+link path=lib/openssl/engines/64 target=$(MACH64)
+link path=lib/openssl/engines/libpk11.so target=libpk11.so.1
+link path=lib/openssl/engines/libpk11.so.1 \
+    target=../default/engines/libpk11.so.1 mediator=openssl \
+    mediator-implementation=default mediator-priority=vendor
+
+# Wanboot static standalone openssl binaries
+file path=lib/openssl/wanboot/$(MACH64)/wanboot-openssl.o \
+    pkg.depend.bypass-generate=.* pkg.linted.userland.action001=true \
+    variant.arch=sparc
+link path=usr/bin/$(MACH32)/openssl \
+    target=../../../lib/openssl/default/$(MACH32)/openssl mediator=openssl \
+    mediator-implementation=default mediator-priority=vendor
+link path=usr/bin/CA.pl target=../../lib/openssl/default/CA.pl \
+    mediator=openssl mediator-implementation=default mediator-priority=vendor
+
+# Mediator links for the commands
+link path=usr/bin/openssl target=../../lib/openssl/default/openssl \
+    mediator=openssl mediator-implementation=default mediator-priority=vendor
+
+# Header and pkg files.
+file path=usr/include/openssl/aes.h
+file path=usr/include/openssl/asn1.h
+file path=usr/include/openssl/asn1_mac.h
+file path=usr/include/openssl/asn1t.h
+file path=usr/include/openssl/bio.h
+file path=usr/include/openssl/blowfish.h
+file path=usr/include/openssl/bn.h
+file path=usr/include/openssl/buffer.h
+file path=usr/include/openssl/camellia.h
+file path=usr/include/openssl/cast.h
+file path=usr/include/openssl/cmac.h
+file path=usr/include/openssl/cms.h
+file path=usr/include/openssl/comp.h
+file path=usr/include/openssl/conf.h
+file path=usr/include/openssl/conf_api.h
+file path=usr/include/openssl/crypto.h
+file path=usr/include/openssl/des.h
+file path=usr/include/openssl/des_old.h
+file path=usr/include/openssl/dh.h
+file path=usr/include/openssl/dsa.h
+file path=usr/include/openssl/dso.h
+file path=usr/include/openssl/dtls1.h
+file path=usr/include/openssl/e_os2.h
+file path=usr/include/openssl/ebcdic.h
+file path=usr/include/openssl/engine.h
+file path=usr/include/openssl/err.h
+file path=usr/include/openssl/evp.h
+file path=usr/include/openssl/hmac.h
+file path=usr/include/openssl/krb5_asn.h
+file path=usr/include/openssl/kssl.h
+file path=usr/include/openssl/lhash.h
+file path=usr/include/openssl/md2.h
+file path=usr/include/openssl/md4.h
+file path=usr/include/openssl/md5.h
+file path=usr/include/openssl/modes.h
+file path=usr/include/openssl/obj_mac.h
+file path=usr/include/openssl/objects.h
+file path=usr/include/openssl/ocsp.h
+# A special case. This header file is patched but possibly overwritten in the
+# proto are with the 64 bit install. We must use the one from the 32 bit build
+# which is the one we have a patch for.
+file $(MACH32)/include/openssl/opensslconf.h \
+    path=usr/include/openssl/opensslconf.h
+file path=usr/include/openssl/opensslv.h
+file path=usr/include/openssl/ossl_typ.h
+file path=usr/include/openssl/pem.h
+file path=usr/include/openssl/pem2.h
+file path=usr/include/openssl/pkcs12.h
+file path=usr/include/openssl/pkcs7.h
+file path=usr/include/openssl/pqueue.h
+file path=usr/include/openssl/rand.h
+file path=usr/include/openssl/rc2.h
+file path=usr/include/openssl/rc4.h
+file path=usr/include/openssl/ripemd.h
+file path=usr/include/openssl/rsa.h
+file path=usr/include/openssl/safestack.h
+file path=usr/include/openssl/sha.h
+file path=usr/include/openssl/srp.h
+file path=usr/include/openssl/srtp.h
+file path=usr/include/openssl/ssl.h
+file path=usr/include/openssl/ssl2.h
+file path=usr/include/openssl/ssl23.h
+file path=usr/include/openssl/ssl3.h
+file path=usr/include/openssl/stack.h
+file path=usr/include/openssl/symhacks.h
+file path=usr/include/openssl/tls1.h
+file path=usr/include/openssl/ts.h
+file path=usr/include/openssl/txt_db.h
+file path=usr/include/openssl/ui.h
+file path=usr/include/openssl/ui_compat.h
+file path=usr/include/openssl/x509.h
+file path=usr/include/openssl/x509_vfy.h
+file path=usr/include/openssl/x509v3.h
+link path=usr/lib/$(MACH64)/libcrypto.so \
+    target=../../../lib/$(MACH64)/libcrypto.so
+link path=usr/lib/$(MACH64)/libcrypto.so.1.0.0 \
+    target=../../../lib/$(MACH64)/libcrypto.so.1.0.0
+link path=usr/lib/$(MACH64)/libssl.so target=../../../lib/$(MACH64)/libssl.so
+link path=usr/lib/$(MACH64)/libssl.so.1.0.0 \
+    target=../../../lib/$(MACH64)/libssl.so.1.0.0
+file $(MACH64)/libcrypto.pc path=usr/lib/$(MACH64)/pkgconfig/libcrypto.pc
+file $(MACH64)/libssl.pc path=usr/lib/$(MACH64)/pkgconfig/libssl.pc
+file $(MACH64)/openssl.pc path=usr/lib/$(MACH64)/pkgconfig/openssl.pc
+link path=usr/lib/libcrypto.so target=../../lib/libcrypto.so
+link path=usr/lib/libcrypto.so.1.0.0 target=../../lib/libcrypto.so.1.0.0
+link path=usr/lib/libssl.so target=../../lib/libssl.so
+link path=usr/lib/libssl.so.1.0.0 target=../../lib/libssl.so.1.0.0
+file $(MACH32)/libcrypto.pc path=usr/lib/pkgconfig/libcrypto.pc
+file $(MACH32)/libssl.pc path=usr/lib/pkgconfig/libssl.pc
+file $(MACH32)/openssl.pc path=usr/lib/pkgconfig/openssl.pc
+
+# Manual pages.
+link path=usr/sfw/bin/$(MACH64)/openssl target=../../../bin/openssl
+link path=usr/sfw/bin/openssl target=../../bin/openssl
+file path=usr/share/man/man1openssl/CA.pl.1openssl
+file path=usr/share/man/man1openssl/asn1parse.1openssl
+file path=usr/share/man/man1openssl/ca.1openssl
+file path=usr/share/man/man1openssl/ciphers.1openssl
+file path=usr/share/man/man1openssl/cms.1openssl
+file path=usr/share/man/man1openssl/crl.1openssl
+file path=usr/share/man/man1openssl/crl2pkcs7.1openssl
+file path=usr/share/man/man1openssl/dgst.1openssl
+file path=usr/share/man/man1openssl/dhparam.1openssl
+file path=usr/share/man/man1openssl/dsa.1openssl
+file path=usr/share/man/man1openssl/dsaparam.1openssl
+file path=usr/share/man/man1openssl/ec.1openssl
+file path=usr/share/man/man1openssl/ecparam.1openssl
+file path=usr/share/man/man1openssl/enc.1openssl
+file path=usr/share/man/man1openssl/errstr.1openssl
+file path=usr/share/man/man1openssl/gendsa.1openssl
+file path=usr/share/man/man1openssl/genpkey.1openssl
+file path=usr/share/man/man1openssl/genrsa.1openssl
+link path=usr/share/man/man1openssl/md2.1openssl target=dgst.1openssl
+link path=usr/share/man/man1openssl/md4.1openssl target=dgst.1openssl
+link path=usr/share/man/man1openssl/md5.1openssl target=dgst.1openssl
+link path=usr/share/man/man1openssl/mdc2.1openssl target=dgst.1openssl
+file path=usr/share/man/man1openssl/nseq.1openssl
+file path=usr/share/man/man1openssl/ocsp.1openssl
+file path=usr/share/man/man1openssl/openssl.1openssl
+file path=usr/share/man/man1openssl/passwd.1openssl
+file path=usr/share/man/man1openssl/pkcs12.1openssl
+file path=usr/share/man/man1openssl/pkcs7.1openssl
+file path=usr/share/man/man1openssl/pkcs8.1openssl
+file path=usr/share/man/man1openssl/pkey.1openssl
+file path=usr/share/man/man1openssl/pkeyparam.1openssl
+file path=usr/share/man/man1openssl/pkeyutl.1openssl
+file path=usr/share/man/man1openssl/rand.1openssl
+file path=usr/share/man/man1openssl/req.1openssl
+link path=usr/share/man/man1openssl/ripemd160.1openssl target=dgst.1openssl
+file path=usr/share/man/man1openssl/rsa.1openssl
+file path=usr/share/man/man1openssl/rsautl.1openssl
+file path=usr/share/man/man1openssl/s_client.1openssl
+file path=usr/share/man/man1openssl/s_server.1openssl
+file path=usr/share/man/man1openssl/s_time.1openssl
+file path=usr/share/man/man1openssl/sess_id.1openssl
+link path=usr/share/man/man1openssl/sha.1openssl target=dgst.1openssl
+link path=usr/share/man/man1openssl/sha1.1openssl target=dgst.1openssl
+file path=usr/share/man/man1openssl/smime.1openssl
+file path=usr/share/man/man1openssl/speed.1openssl
+file path=usr/share/man/man1openssl/spkac.1openssl
+file path=usr/share/man/man1openssl/ts.1openssl
+file path=usr/share/man/man1openssl/tsget.1openssl
+file path=usr/share/man/man1openssl/verify.1openssl
+file path=usr/share/man/man1openssl/version.1openssl
+file path=usr/share/man/man1openssl/x509.1openssl
+link path=usr/share/man/man3openssl/ASN1_OBJECT_free.3openssl \
+    target=ASN1_OBJECT_new.3openssl
+file path=usr/share/man/man3openssl/ASN1_OBJECT_new.3openssl
+link path=usr/share/man/man3openssl/ASN1_STRING_cmp.3openssl \
+    target=ASN1_STRING_length.3openssl
+link path=usr/share/man/man3openssl/ASN1_STRING_data.3openssl \
+    target=ASN1_STRING_length.3openssl
+link path=usr/share/man/man3openssl/ASN1_STRING_dup.3openssl \
+    target=ASN1_STRING_length.3openssl
+link path=usr/share/man/man3openssl/ASN1_STRING_free.3openssl \
+    target=ASN1_STRING_new.3openssl
+file path=usr/share/man/man3openssl/ASN1_STRING_length.3openssl
+link path=usr/share/man/man3openssl/ASN1_STRING_length_set.3openssl \
+    target=ASN1_STRING_length.3openssl
+file path=usr/share/man/man3openssl/ASN1_STRING_new.3openssl
+file path=usr/share/man/man3openssl/ASN1_STRING_print_ex.3openssl
+link path=usr/share/man/man3openssl/ASN1_STRING_print_ex_fp.3openssl \
+    target=ASN1_STRING_print_ex.3openssl
+link path=usr/share/man/man3openssl/ASN1_STRING_set.3openssl \
+    target=ASN1_STRING_length.3openssl
+link path=usr/share/man/man3openssl/ASN1_STRING_type.3openssl \
+    target=ASN1_STRING_length.3openssl
+link path=usr/share/man/man3openssl/ASN1_STRING_type_new.3openssl \
+    target=ASN1_STRING_new.3openssl
+file path=usr/share/man/man3openssl/ASN1_generate_nconf.3openssl
+link path=usr/share/man/man3openssl/ASN1_generate_v3.3openssl \
+    target=ASN1_generate_nconf.3openssl
+link path=usr/share/man/man3openssl/BF_cbc_encrypt.3openssl \
+    target=blowfish.3openssl
+link path=usr/share/man/man3openssl/BF_cfb64_encrypt.3openssl \
+    target=blowfish.3openssl
+link path=usr/share/man/man3openssl/BF_decrypt.3openssl target=blowfish.3openssl
+link path=usr/share/man/man3openssl/BF_ecb_encrypt.3openssl \
+    target=blowfish.3openssl
+link path=usr/share/man/man3openssl/BF_encrypt.3openssl target=blowfish.3openssl
+link path=usr/share/man/man3openssl/BF_ofb64_encrypt.3openssl \
+    target=blowfish.3openssl
+link path=usr/share/man/man3openssl/BF_options.3openssl target=blowfish.3openssl
+link path=usr/share/man/man3openssl/BF_set_key.3openssl target=blowfish.3openssl
+link path=usr/share/man/man3openssl/BIO_append_filename.3openssl \
+    target=BIO_s_file.3openssl
+link path=usr/share/man/man3openssl/BIO_callback_ctrl.3openssl \
+    target=BIO_ctrl.3openssl
+file path=usr/share/man/man3openssl/BIO_ctrl.3openssl
+link path=usr/share/man/man3openssl/BIO_ctrl_get_read_request.3openssl \
+    target=BIO_s_bio.3openssl
+link path=usr/share/man/man3openssl/BIO_ctrl_get_write_guarantee.3openssl \
+    target=BIO_s_bio.3openssl
+link path=usr/share/man/man3openssl/BIO_ctrl_pending.3openssl \
+    target=BIO_ctrl.3openssl
+link path=usr/share/man/man3openssl/BIO_ctrl_reset_read_request.3openssl \
+    target=BIO_s_bio.3openssl
+link path=usr/share/man/man3openssl/BIO_ctrl_wpending.3openssl \
+    target=BIO_ctrl.3openssl
+link path=usr/share/man/man3openssl/BIO_debug_callback.3openssl \
+    target=BIO_set_callback.3openssl
+link path=usr/share/man/man3openssl/BIO_destroy_bio_pair.3openssl \
+    target=BIO_s_bio.3openssl
+link path=usr/share/man/man3openssl/BIO_do_accept.3openssl \
+    target=BIO_s_accept.3openssl
+link path=usr/share/man/man3openssl/BIO_do_connect.3openssl \
+    target=BIO_s_connect.3openssl
+link path=usr/share/man/man3openssl/BIO_eof.3openssl target=BIO_ctrl.3openssl
+file path=usr/share/man/man3openssl/BIO_f_base64.3openssl
+file path=usr/share/man/man3openssl/BIO_f_buffer.3openssl
+file path=usr/share/man/man3openssl/BIO_f_cipher.3openssl
+file path=usr/share/man/man3openssl/BIO_f_md.3openssl
+file path=usr/share/man/man3openssl/BIO_f_null.3openssl
+file path=usr/share/man/man3openssl/BIO_f_ssl.3openssl
+file path=usr/share/man/man3openssl/BIO_find_type.3openssl
+link path=usr/share/man/man3openssl/BIO_flush.3openssl target=BIO_ctrl.3openssl
+link path=usr/share/man/man3openssl/BIO_free.3openssl target=BIO_new.3openssl
+link path=usr/share/man/man3openssl/BIO_free_all.3openssl \
+    target=BIO_new.3openssl
+link path=usr/share/man/man3openssl/BIO_get_accept_port.3openssl \
+    target=BIO_s_accept.3openssl
+link path=usr/share/man/man3openssl/BIO_get_bind_mode.3openssl \
+    target=BIO_s_accept.3openssl
+link path=usr/share/man/man3openssl/BIO_get_callback.3openssl \
+    target=BIO_set_callback.3openssl
+link path=usr/share/man/man3openssl/BIO_get_callback_arg.3openssl \
+    target=BIO_set_callback.3openssl
+link path=usr/share/man/man3openssl/BIO_get_cipher_ctx.3openssl \
+    target=BIO_f_cipher.3openssl
+link path=usr/share/man/man3openssl/BIO_get_cipher_status.3openssl \
+    target=BIO_f_cipher.3openssl
+link path=usr/share/man/man3openssl/BIO_get_close.3openssl \
+    target=BIO_ctrl.3openssl
+link path=usr/share/man/man3openssl/BIO_get_conn_hostname.3openssl \
+    target=BIO_s_connect.3openssl
+link path=usr/share/man/man3openssl/BIO_get_conn_int_port.3openssl \
+    target=BIO_s_connect.3openssl
+link path=usr/share/man/man3openssl/BIO_get_conn_ip.3openssl \
+    target=BIO_s_connect.3openssl
+link path=usr/share/man/man3openssl/BIO_get_conn_port.3openssl \
+    target=BIO_s_connect.3openssl
+link path=usr/share/man/man3openssl/BIO_get_fd.3openssl target=BIO_s_fd.3openssl
+link path=usr/share/man/man3openssl/BIO_get_fp.3openssl \
+    target=BIO_s_file.3openssl
+link path=usr/share/man/man3openssl/BIO_get_info_callback.3openssl \
+    target=BIO_ctrl.3openssl
+link path=usr/share/man/man3openssl/BIO_get_md.3openssl target=BIO_f_md.3openssl
+link path=usr/share/man/man3openssl/BIO_get_md_ctx.3openssl \
+    target=BIO_f_md.3openssl
+link path=usr/share/man/man3openssl/BIO_get_mem_data.3openssl \
+    target=BIO_s_mem.3openssl
+link path=usr/share/man/man3openssl/BIO_get_mem_ptr.3openssl \
+    target=BIO_s_mem.3openssl
+link path=usr/share/man/man3openssl/BIO_get_num_renegotiates.3openssl \
+    target=BIO_f_ssl.3openssl
+link path=usr/share/man/man3openssl/BIO_get_read_request.3openssl \
+    target=BIO_s_bio.3openssl
+link path=usr/share/man/man3openssl/BIO_get_retry_BIO.3openssl \
+    target=BIO_should_retry.3openssl
+link path=usr/share/man/man3openssl/BIO_get_retry_reason.3openssl \
+    target=BIO_should_retry.3openssl
+link path=usr/share/man/man3openssl/BIO_get_ssl.3openssl \
+    target=BIO_f_ssl.3openssl
+link path=usr/share/man/man3openssl/BIO_get_write_buf_size.3openssl \
+    target=BIO_s_bio.3openssl
+link path=usr/share/man/man3openssl/BIO_get_write_guarantee.3openssl \
+    target=BIO_s_bio.3openssl
+link path=usr/share/man/man3openssl/BIO_gets.3openssl target=BIO_read.3openssl
+link path=usr/share/man/man3openssl/BIO_int_ctrl.3openssl \
+    target=BIO_ctrl.3openssl
+link path=usr/share/man/man3openssl/BIO_make_bio_pair.3openssl \
+    target=BIO_s_bio.3openssl
+file path=usr/share/man/man3openssl/BIO_new.3openssl
+file path=usr/share/man/man3openssl/BIO_new_CMS.3openssl
+link path=usr/share/man/man3openssl/BIO_new_bio_pair.3openssl \
+    target=BIO_s_bio.3openssl
+link path=usr/share/man/man3openssl/BIO_new_buffer_ssl_connect.3openssl \
+    target=BIO_f_ssl.3openssl
+link path=usr/share/man/man3openssl/BIO_new_fd.3openssl target=BIO_s_fd.3openssl
+link path=usr/share/man/man3openssl/BIO_new_file.3openssl \
+    target=BIO_s_file.3openssl
+link path=usr/share/man/man3openssl/BIO_new_fp.3openssl \
+    target=BIO_s_file.3openssl
+link path=usr/share/man/man3openssl/BIO_new_mem_buf.3openssl \
+    target=BIO_s_mem.3openssl
+link path=usr/share/man/man3openssl/BIO_new_socket.3openssl \
+    target=BIO_s_socket.3openssl
+link path=usr/share/man/man3openssl/BIO_new_ssl.3openssl \
+    target=BIO_f_ssl.3openssl
+link path=usr/share/man/man3openssl/BIO_new_ssl_connect.3openssl \
+    target=BIO_f_ssl.3openssl
+link path=usr/share/man/man3openssl/BIO_next.3openssl \
+    target=BIO_find_type.3openssl
+link path=usr/share/man/man3openssl/BIO_pending.3openssl \
+    target=BIO_ctrl.3openssl
+link path=usr/share/man/man3openssl/BIO_pop.3openssl target=BIO_push.3openssl
+link path=usr/share/man/man3openssl/BIO_ptr_ctrl.3openssl \
+    target=BIO_ctrl.3openssl
+file path=usr/share/man/man3openssl/BIO_push.3openssl
+link path=usr/share/man/man3openssl/BIO_puts.3openssl target=BIO_read.3openssl
+file path=usr/share/man/man3openssl/BIO_read.3openssl
+link path=usr/share/man/man3openssl/BIO_read_filename.3openssl \
+    target=BIO_s_file.3openssl
+link path=usr/share/man/man3openssl/BIO_reset.3openssl target=BIO_ctrl.3openssl
+link path=usr/share/man/man3openssl/BIO_retry_type.3openssl \
+    target=BIO_should_retry.3openssl
+link path=usr/share/man/man3openssl/BIO_rw_filename.3openssl \
+    target=BIO_s_file.3openssl
+file path=usr/share/man/man3openssl/BIO_s_accept.3openssl
+file path=usr/share/man/man3openssl/BIO_s_bio.3openssl
+file path=usr/share/man/man3openssl/BIO_s_connect.3openssl
+file path=usr/share/man/man3openssl/BIO_s_fd.3openssl
+file path=usr/share/man/man3openssl/BIO_s_file.3openssl
+file path=usr/share/man/man3openssl/BIO_s_mem.3openssl
+file path=usr/share/man/man3openssl/BIO_s_null.3openssl
+file path=usr/share/man/man3openssl/BIO_s_socket.3openssl
+link path=usr/share/man/man3openssl/BIO_seek.3openssl target=BIO_ctrl.3openssl
+link path=usr/share/man/man3openssl/BIO_set.3openssl target=BIO_new.3openssl
+link path=usr/share/man/man3openssl/BIO_set_accept_bios.3openssl \
+    target=BIO_s_accept.3openssl
+link path=usr/share/man/man3openssl/BIO_set_accept_port.3openssl \
+    target=BIO_s_accept.3openssl
+link path=usr/share/man/man3openssl/BIO_set_bind_mode.3openssl \
+    target=BIO_s_accept.3openssl
+file path=usr/share/man/man3openssl/BIO_set_callback.3openssl
+link path=usr/share/man/man3openssl/BIO_set_callback_arg.3openssl \
+    target=BIO_set_callback.3openssl
+link path=usr/share/man/man3openssl/BIO_set_cipher.3openssl \
+    target=BIO_f_cipher.3openssl
+link path=usr/share/man/man3openssl/BIO_set_close.3openssl \
+    target=BIO_ctrl.3openssl
+link path=usr/share/man/man3openssl/BIO_set_conn_hostname.3openssl \
+    target=BIO_s_connect.3openssl
+link path=usr/share/man/man3openssl/BIO_set_conn_int_port.3openssl \
+    target=BIO_s_connect.3openssl
+link path=usr/share/man/man3openssl/BIO_set_conn_ip.3openssl \
+    target=BIO_s_connect.3openssl
+link path=usr/share/man/man3openssl/BIO_set_conn_port.3openssl \
+    target=BIO_s_connect.3openssl
+link path=usr/share/man/man3openssl/BIO_set_fd.3openssl target=BIO_s_fd.3openssl
+link path=usr/share/man/man3openssl/BIO_set_fp.3openssl \
+    target=BIO_s_file.3openssl
+link path=usr/share/man/man3openssl/BIO_set_info_callback.3openssl \
+    target=BIO_ctrl.3openssl
+link path=usr/share/man/man3openssl/BIO_set_md.3openssl target=BIO_f_md.3openssl
+link path=usr/share/man/man3openssl/BIO_set_mem_buf.3openssl \
+    target=BIO_s_mem.3openssl
+link path=usr/share/man/man3openssl/BIO_set_mem_eof_return.3openssl \
+    target=BIO_s_mem.3openssl
+link path=usr/share/man/man3openssl/BIO_set_nbio.3openssl \
+    target=BIO_s_connect.3openssl
+link path=usr/share/man/man3openssl/BIO_set_nbio_accept.3openssl \
+    target=BIO_s_accept.3openssl
+link path=usr/share/man/man3openssl/BIO_set_ssl.3openssl \
+    target=BIO_f_ssl.3openssl
+link path=usr/share/man/man3openssl/BIO_set_ssl_mode.3openssl \
+    target=BIO_f_ssl.3openssl
+link path=usr/share/man/man3openssl/BIO_set_ssl_renegotiate_bytes.3openssl \
+    target=BIO_f_ssl.3openssl
+link path=usr/share/man/man3openssl/BIO_set_ssl_renegotiate_timeout.3openssl \
+    target=BIO_f_ssl.3openssl
+link path=usr/share/man/man3openssl/BIO_set_write_buf_size.3openssl \
+    target=BIO_s_bio.3openssl
+link path=usr/share/man/man3openssl/BIO_should_io_special.3openssl \
+    target=BIO_should_retry.3openssl
+link path=usr/share/man/man3openssl/BIO_should_read.3openssl \
+    target=BIO_should_retry.3openssl
+file path=usr/share/man/man3openssl/BIO_should_retry.3openssl
+link path=usr/share/man/man3openssl/BIO_should_write.3openssl \
+    target=BIO_should_retry.3openssl
+link path=usr/share/man/man3openssl/BIO_shutdown_wr.3openssl \
+    target=BIO_s_bio.3openssl
+link path=usr/share/man/man3openssl/BIO_ssl_copy_session_id.3openssl \
+    target=BIO_f_ssl.3openssl
+link path=usr/share/man/man3openssl/BIO_ssl_shutdown.3openssl \
+    target=BIO_f_ssl.3openssl
+link path=usr/share/man/man3openssl/BIO_tell.3openssl target=BIO_ctrl.3openssl
+link path=usr/share/man/man3openssl/BIO_vfree.3openssl target=BIO_new.3openssl
+link path=usr/share/man/man3openssl/BIO_wpending.3openssl \
+    target=BIO_ctrl.3openssl
+link path=usr/share/man/man3openssl/BIO_write.3openssl target=BIO_read.3openssl
+link path=usr/share/man/man3openssl/BIO_write_filename.3openssl \
+    target=BIO_s_file.3openssl
+link path=usr/share/man/man3openssl/BN_BLINDING_convert.3openssl \
+    target=BN_BLINDING_new.3openssl
+link path=usr/share/man/man3openssl/BN_BLINDING_convert_ex.3openssl \
+    target=BN_BLINDING_new.3openssl
+link path=usr/share/man/man3openssl/BN_BLINDING_create_param.3openssl \
+    target=BN_BLINDING_new.3openssl
+link path=usr/share/man/man3openssl/BN_BLINDING_free.3openssl \
+    target=BN_BLINDING_new.3openssl
+link path=usr/share/man/man3openssl/BN_BLINDING_get_flags.3openssl \
+    target=BN_BLINDING_new.3openssl
+link path=usr/share/man/man3openssl/BN_BLINDING_get_thread_id.3openssl \
+    target=BN_BLINDING_new.3openssl
+link path=usr/share/man/man3openssl/BN_BLINDING_invert.3openssl \
+    target=BN_BLINDING_new.3openssl
+link path=usr/share/man/man3openssl/BN_BLINDING_invert_ex.3openssl \
+    target=BN_BLINDING_new.3openssl
+file path=usr/share/man/man3openssl/BN_BLINDING_new.3openssl
+link path=usr/share/man/man3openssl/BN_BLINDING_set_flags.3openssl \
+    target=BN_BLINDING_new.3openssl
+link path=usr/share/man/man3openssl/BN_BLINDING_set_thread_id.3openssl \
+    target=BN_BLINDING_new.3openssl
+link path=usr/share/man/man3openssl/BN_BLINDING_update.3openssl \
+    target=BN_BLINDING_new.3openssl
+link path=usr/share/man/man3openssl/BN_CTX_end.3openssl \
+    target=BN_CTX_start.3openssl
+link path=usr/share/man/man3openssl/BN_CTX_free.3openssl \
+    target=BN_CTX_new.3openssl
+link path=usr/share/man/man3openssl/BN_CTX_get.3openssl \
+    target=BN_CTX_start.3openssl
+link path=usr/share/man/man3openssl/BN_CTX_init.3openssl \
+    target=BN_CTX_new.3openssl
+file path=usr/share/man/man3openssl/BN_CTX_new.3openssl
+file path=usr/share/man/man3openssl/BN_CTX_start.3openssl
+link path=usr/share/man/man3openssl/BN_MONT_CTX_copy.3openssl \
+    target=BN_mod_mul_montgomery.3openssl
+link path=usr/share/man/man3openssl/BN_MONT_CTX_free.3openssl \
+    target=BN_mod_mul_montgomery.3openssl
+link path=usr/share/man/man3openssl/BN_MONT_CTX_init.3openssl \
+    target=BN_mod_mul_montgomery.3openssl
+link path=usr/share/man/man3openssl/BN_MONT_CTX_new.3openssl \
+    target=BN_mod_mul_montgomery.3openssl
+link path=usr/share/man/man3openssl/BN_MONT_CTX_set.3openssl \
+    target=BN_mod_mul_montgomery.3openssl
+link path=usr/share/man/man3openssl/BN_RECP_CTX_free.3openssl \
+    target=BN_mod_mul_reciprocal.3openssl
+link path=usr/share/man/man3openssl/BN_RECP_CTX_init.3openssl \
+    target=BN_mod_mul_reciprocal.3openssl
+link path=usr/share/man/man3openssl/BN_RECP_CTX_new.3openssl \
+    target=BN_mod_mul_reciprocal.3openssl
+link path=usr/share/man/man3openssl/BN_RECP_CTX_set.3openssl \
+    target=BN_mod_mul_reciprocal.3openssl
+file path=usr/share/man/man3openssl/BN_add.3openssl
+file path=usr/share/man/man3openssl/BN_add_word.3openssl
+link path=usr/share/man/man3openssl/BN_bin2bn.3openssl target=BN_bn2bin.3openssl
+file path=usr/share/man/man3openssl/BN_bn2bin.3openssl
+link path=usr/share/man/man3openssl/BN_bn2dec.3openssl target=BN_bn2bin.3openssl
+link path=usr/share/man/man3openssl/BN_bn2hex.3openssl target=BN_bn2bin.3openssl
+link path=usr/share/man/man3openssl/BN_bn2mpi.3openssl target=BN_bn2bin.3openssl
+link path=usr/share/man/man3openssl/BN_clear.3openssl target=BN_new.3openssl
+link path=usr/share/man/man3openssl/BN_clear_bit.3openssl \
+    target=BN_set_bit.3openssl
+link path=usr/share/man/man3openssl/BN_clear_free.3openssl \
+    target=BN_new.3openssl
+file path=usr/share/man/man3openssl/BN_cmp.3openssl
+file path=usr/share/man/man3openssl/BN_copy.3openssl
+link path=usr/share/man/man3openssl/BN_dec2bn.3openssl target=BN_bn2bin.3openssl
+link path=usr/share/man/man3openssl/BN_div.3openssl target=BN_add.3openssl
+link path=usr/share/man/man3openssl/BN_div_recp.3openssl \
+    target=BN_mod_mul_reciprocal.3openssl
+link path=usr/share/man/man3openssl/BN_div_word.3openssl \
+    target=BN_add_word.3openssl
+link path=usr/share/man/man3openssl/BN_dup.3openssl target=BN_copy.3openssl
+link path=usr/share/man/man3openssl/BN_exp.3openssl target=BN_add.3openssl
+link path=usr/share/man/man3openssl/BN_free.3openssl target=BN_new.3openssl
+link path=usr/share/man/man3openssl/BN_from_montgomery.3openssl \
+    target=BN_mod_mul_montgomery.3openssl
+link path=usr/share/man/man3openssl/BN_gcd.3openssl target=BN_add.3openssl
+file path=usr/share/man/man3openssl/BN_generate_prime.3openssl
+link path=usr/share/man/man3openssl/BN_get_word.3openssl target=BN_zero.3openssl
+link path=usr/share/man/man3openssl/BN_hex2bn.3openssl target=BN_bn2bin.3openssl
+link path=usr/share/man/man3openssl/BN_init.3openssl target=BN_new.3openssl
+link path=usr/share/man/man3openssl/BN_is_bit_set.3openssl \
+    target=BN_set_bit.3openssl
+link path=usr/share/man/man3openssl/BN_is_odd.3openssl target=BN_cmp.3openssl
+link path=usr/share/man/man3openssl/BN_is_one.3openssl target=BN_cmp.3openssl
+link path=usr/share/man/man3openssl/BN_is_prime.3openssl \
+    target=BN_generate_prime.3openssl
+link path=usr/share/man/man3openssl/BN_is_prime_fasttest.3openssl \
+    target=BN_generate_prime.3openssl
+link path=usr/share/man/man3openssl/BN_is_word.3openssl target=BN_cmp.3openssl
+link path=usr/share/man/man3openssl/BN_is_zero.3openssl target=BN_cmp.3openssl
+link path=usr/share/man/man3openssl/BN_lshift.3openssl \
+    target=BN_set_bit.3openssl
+link path=usr/share/man/man3openssl/BN_lshift1.3openssl \
+    target=BN_set_bit.3openssl
+link path=usr/share/man/man3openssl/BN_mask_bits.3openssl \
+    target=BN_set_bit.3openssl
+link path=usr/share/man/man3openssl/BN_mod.3openssl target=BN_add.3openssl
+link path=usr/share/man/man3openssl/BN_mod_add.3openssl target=BN_add.3openssl
+link path=usr/share/man/man3openssl/BN_mod_exp.3openssl target=BN_add.3openssl
+file path=usr/share/man/man3openssl/BN_mod_inverse.3openssl
+link path=usr/share/man/man3openssl/BN_mod_mul.3openssl target=BN_add.3openssl
+file path=usr/share/man/man3openssl/BN_mod_mul_montgomery.3openssl
+file path=usr/share/man/man3openssl/BN_mod_mul_reciprocal.3openssl
+link path=usr/share/man/man3openssl/BN_mod_sqr.3openssl target=BN_add.3openssl
+link path=usr/share/man/man3openssl/BN_mod_sub.3openssl target=BN_add.3openssl
+link path=usr/share/man/man3openssl/BN_mod_word.3openssl \
+    target=BN_add_word.3openssl
+link path=usr/share/man/man3openssl/BN_mpi2bn.3openssl target=BN_bn2bin.3openssl
+link path=usr/share/man/man3openssl/BN_mul.3openssl target=BN_add.3openssl
+link path=usr/share/man/man3openssl/BN_mul_word.3openssl \
+    target=BN_add_word.3openssl
+file path=usr/share/man/man3openssl/BN_new.3openssl
+link path=usr/share/man/man3openssl/BN_nnmod.3openssl target=BN_add.3openssl
+link path=usr/share/man/man3openssl/BN_num_bits.3openssl \
+    target=BN_num_bytes.3openssl
+link path=usr/share/man/man3openssl/BN_num_bits_word.3openssl \
+    target=BN_num_bytes.3openssl
+file path=usr/share/man/man3openssl/BN_num_bytes.3openssl
+link path=usr/share/man/man3openssl/BN_one.3openssl target=BN_zero.3openssl
+link path=usr/share/man/man3openssl/BN_print.3openssl target=BN_bn2bin.3openssl
+link path=usr/share/man/man3openssl/BN_print_fp.3openssl \
+    target=BN_bn2bin.3openssl
+link path=usr/share/man/man3openssl/BN_pseudo_rand.3openssl \
+    target=BN_rand.3openssl
+file path=usr/share/man/man3openssl/BN_rand.3openssl
+link path=usr/share/man/man3openssl/BN_rshift.3openssl \
+    target=BN_set_bit.3openssl
+link path=usr/share/man/man3openssl/BN_rshift1.3openssl \
+    target=BN_set_bit.3openssl
+file path=usr/share/man/man3openssl/BN_set_bit.3openssl
+link path=usr/share/man/man3openssl/BN_set_word.3openssl target=BN_zero.3openssl
+link path=usr/share/man/man3openssl/BN_sqr.3openssl target=BN_add.3openssl
+link path=usr/share/man/man3openssl/BN_sub.3openssl target=BN_add.3openssl
+link path=usr/share/man/man3openssl/BN_sub_word.3openssl \
+    target=BN_add_word.3openssl
+file path=usr/share/man/man3openssl/BN_swap.3openssl
+link path=usr/share/man/man3openssl/BN_to_montgomery.3openssl \
+    target=BN_mod_mul_montgomery.3openssl
+link path=usr/share/man/man3openssl/BN_ucmp.3openssl target=BN_cmp.3openssl
+link path=usr/share/man/man3openssl/BN_value_one.3openssl \
+    target=BN_zero.3openssl
+file path=usr/share/man/man3openssl/BN_zero.3openssl
+link path=usr/share/man/man3openssl/BUF_MEM_free.3openssl target=buffer.3openssl
+link path=usr/share/man/man3openssl/BUF_MEM_grow.3openssl target=buffer.3openssl
+link path=usr/share/man/man3openssl/BUF_MEM_new.3openssl target=buffer.3openssl
+link path=usr/share/man/man3openssl/BUF_strdup.3openssl target=buffer.3openssl
+link path=usr/share/man/man3openssl/CMS_ReceiptRequest_create0.3openssl \
+    target=CMS_get1_ReceiptRequest.3openssl
+link path=usr/share/man/man3openssl/CMS_ReceiptRequest_get0_values.3openssl \
+    target=CMS_get1_ReceiptRequest.3openssl
+link path=usr/share/man/man3openssl/CMS_RecipientInfo_decrypt.3openssl \
+    target=CMS_get0_RecipientInfos.3openssl
+link path=usr/share/man/man3openssl/CMS_RecipientInfo_kekri_get0_id.3openssl \
+    target=CMS_get0_RecipientInfos.3openssl
+link path=usr/share/man/man3openssl/CMS_RecipientInfo_kekri_id_cmp.3openssl \
+    target=CMS_get0_RecipientInfos.3openssl
+link path=usr/share/man/man3openssl/CMS_RecipientInfo_ktri_cert_cmp.3openssl \
+    target=CMS_get0_RecipientInfos.3openssl
+link \
+    path=usr/share/man/man3openssl/CMS_RecipientInfo_ktri_get0_signer_id.3openssl \
+    target=CMS_get0_RecipientInfos.3openssl
+link path=usr/share/man/man3openssl/CMS_RecipientInfo_set0_key.3openssl \
+    target=CMS_get0_RecipientInfos.3openssl
+link path=usr/share/man/man3openssl/CMS_RecipientInfo_set0_pkey.3openssl \
+    target=CMS_get0_RecipientInfos.3openssl
+link path=usr/share/man/man3openssl/CMS_RecipientInfo_type.3openssl \
+    target=CMS_get0_RecipientInfos.3openssl
+link path=usr/share/man/man3openssl/CMS_SignerInfo_cert_cmp.3openssl \
+    target=CMS_get0_SignerInfos.3openssl
+link path=usr/share/man/man3openssl/CMS_SignerInfo_get0_signer_id.3openssl \
+    target=CMS_get0_SignerInfos.3openssl
+link path=usr/share/man/man3openssl/CMS_SignerInfo_sign.3openssl \
+    target=CMS_add1_signer.3openssl
+file path=usr/share/man/man3openssl/CMS_add0_cert.3openssl
+link path=usr/share/man/man3openssl/CMS_add0_crl.3openssl \
+    target=CMS_add0_cert.3openssl
+link path=usr/share/man/man3openssl/CMS_add0_recipient_key.3openssl \
+    target=CMS_add1_recipient_cert.3openssl
+link path=usr/share/man/man3openssl/CMS_add1_ReceiptRequest.3openssl \
+    target=CMS_get1_ReceiptRequest.3openssl
+link path=usr/share/man/man3openssl/CMS_add1_cert.3openssl \
+    target=CMS_add0_cert.3openssl
+file path=usr/share/man/man3openssl/CMS_add1_recipient_cert.3openssl
+file path=usr/share/man/man3openssl/CMS_add1_signer.3openssl
+file path=usr/share/man/man3openssl/CMS_compress.3openssl
+file path=usr/share/man/man3openssl/CMS_decrypt.3openssl
+file path=usr/share/man/man3openssl/CMS_encrypt.3openssl
+file path=usr/share/man/man3openssl/CMS_final.3openssl
+file path=usr/share/man/man3openssl/CMS_get0_RecipientInfos.3openssl
+file path=usr/share/man/man3openssl/CMS_get0_SignerInfos.3openssl
+link path=usr/share/man/man3openssl/CMS_get0_eContentType.3openssl \
+    target=CMS_get0_type.3openssl
+file path=usr/share/man/man3openssl/CMS_get0_type.3openssl
+file path=usr/share/man/man3openssl/CMS_get1_ReceiptRequest.3openssl
+link path=usr/share/man/man3openssl/CMS_get1_certs.3openssl \
+    target=CMS_add0_cert.3openssl
+link path=usr/share/man/man3openssl/CMS_get1_crls.3openssl \
+    target=CMS_add0_cert.3openssl
+link path=usr/share/man/man3openssl/CMS_set1_eContentType.3openssl \
+    target=CMS_get0_type.3openssl
+link path=usr/share/man/man3openssl/CMS_set1_signer_certs.3openssl \
+    target=CMS_get0_SignerInfos.3openssl
+file path=usr/share/man/man3openssl/CMS_sign.3openssl
+file path=usr/share/man/man3openssl/CMS_sign_receipt.3openssl
+file path=usr/share/man/man3openssl/CMS_uncompress.3openssl
+file path=usr/share/man/man3openssl/CMS_verify.3openssl
+file path=usr/share/man/man3openssl/CMS_verify_receipt.3openssl
+link path=usr/share/man/man3openssl/CONF_modules_finish.3openssl \
+    target=CONF_modules_free.3openssl
+file path=usr/share/man/man3openssl/CONF_modules_free.3openssl
+link path=usr/share/man/man3openssl/CONF_modules_load.3openssl \
+    target=CONF_modules_load_file.3openssl
+file path=usr/share/man/man3openssl/CONF_modules_load_file.3openssl
+link path=usr/share/man/man3openssl/CONF_modules_unload.3openssl \
+    target=CONF_modules_free.3openssl
+link path=usr/share/man/man3openssl/CRYPTO_THREADID_cmp.3openssl \
+    target=threads.3openssl
+link path=usr/share/man/man3openssl/CRYPTO_THREADID_cpy.3openssl \
+    target=threads.3openssl
+link path=usr/share/man/man3openssl/CRYPTO_THREADID_current.3openssl \
+    target=threads.3openssl
+link path=usr/share/man/man3openssl/CRYPTO_THREADID_get_callback.3openssl \
+    target=threads.3openssl
+link path=usr/share/man/man3openssl/CRYPTO_THREADID_hash.3openssl \
+    target=threads.3openssl
+link path=usr/share/man/man3openssl/CRYPTO_THREADID_set_callback.3openssl \
+    target=threads.3openssl
+link path=usr/share/man/man3openssl/CRYPTO_destroy_dynlockid.3openssl \
+    target=threads.3openssl
+link path=usr/share/man/man3openssl/CRYPTO_get_ex_data.3openssl \
+    target=CRYPTO_set_ex_data.3openssl
+link path=usr/share/man/man3openssl/CRYPTO_get_new_dynlockid.3openssl \
+    target=threads.3openssl
+link path=usr/share/man/man3openssl/CRYPTO_lock.3openssl target=threads.3openssl
+link path=usr/share/man/man3openssl/CRYPTO_num_locks.3openssl \
+    target=threads.3openssl
+link \
+    path=usr/share/man/man3openssl/CRYPTO_set_dynlock_create_callback.3openssl \
+    target=threads.3openssl
+link \
+    path=usr/share/man/man3openssl/CRYPTO_set_dynlock_destroy_callback.3openssl \
+    target=threads.3openssl
+link path=usr/share/man/man3openssl/CRYPTO_set_dynlock_lock_callback.3openssl \
+    target=threads.3openssl
+file path=usr/share/man/man3openssl/CRYPTO_set_ex_data.3openssl
+link path=usr/share/man/man3openssl/CRYPTO_set_locking_callback.3openssl \
+    target=threads.3openssl
+link path=usr/share/man/man3openssl/DES_cbc_cksum.3openssl target=des.3openssl
+link path=usr/share/man/man3openssl/DES_cfb64_encrypt.3openssl \
+    target=des.3openssl
+link path=usr/share/man/man3openssl/DES_cfb_encrypt.3openssl target=des.3openssl
+link path=usr/share/man/man3openssl/DES_crypt.3openssl target=des.3openssl
+link path=usr/share/man/man3openssl/DES_ecb2_encrypt.3openssl \
+    target=des.3openssl
+link path=usr/share/man/man3openssl/DES_ecb3_encrypt.3openssl \
+    target=des.3openssl
+link path=usr/share/man/man3openssl/DES_ecb_encrypt.3openssl target=des.3openssl
+link path=usr/share/man/man3openssl/DES_ede2_cbc_encrypt.3openssl \
+    target=des.3openssl
+link path=usr/share/man/man3openssl/DES_ede2_cfb64_encrypt.3openssl \
+    target=des.3openssl
+link path=usr/share/man/man3openssl/DES_ede2_ofb64_encrypt.3openssl \
+    target=des.3openssl
+link path=usr/share/man/man3openssl/DES_ede3_cbc_encrypt.3openssl \
+    target=des.3openssl
+link path=usr/share/man/man3openssl/DES_ede3_cbcm_encrypt.3openssl \
+    target=des.3openssl
+link path=usr/share/man/man3openssl/DES_ede3_cfb64_encrypt.3openssl \
+    target=des.3openssl
+link path=usr/share/man/man3openssl/DES_ede3_ofb64_encrypt.3openssl \
+    target=des.3openssl
+link path=usr/share/man/man3openssl/DES_enc_read.3openssl target=des.3openssl
+link path=usr/share/man/man3openssl/DES_enc_write.3openssl target=des.3openssl
+link path=usr/share/man/man3openssl/DES_fcrypt.3openssl target=des.3openssl
+link path=usr/share/man/man3openssl/DES_is_weak_key.3openssl target=des.3openssl
+link path=usr/share/man/man3openssl/DES_key_sched.3openssl target=des.3openssl
+link path=usr/share/man/man3openssl/DES_ncbc_encrypt.3openssl \
+    target=des.3openssl
+link path=usr/share/man/man3openssl/DES_ofb64_encrypt.3openssl \
+    target=des.3openssl
+link path=usr/share/man/man3openssl/DES_ofb_encrypt.3openssl target=des.3openssl
+link path=usr/share/man/man3openssl/DES_pcbc_encrypt.3openssl \
+    target=des.3openssl
+link path=usr/share/man/man3openssl/DES_quad_cksum.3openssl target=des.3openssl
+link path=usr/share/man/man3openssl/DES_random_key.3openssl target=des.3openssl
+link path=usr/share/man/man3openssl/DES_set_key.3openssl target=des.3openssl
+link path=usr/share/man/man3openssl/DES_set_key_checked.3openssl \
+    target=des.3openssl
+link path=usr/share/man/man3openssl/DES_set_key_unchecked.3openssl \
+    target=des.3openssl
+link path=usr/share/man/man3openssl/DES_set_odd_parity.3openssl \
+    target=des.3openssl
+link path=usr/share/man/man3openssl/DES_string_to_2keys.3openssl \
+    target=des.3openssl
+link path=usr/share/man/man3openssl/DES_string_to_key.3openssl \
+    target=des.3openssl
+link path=usr/share/man/man3openssl/DES_xcbc_encrypt.3openssl \
+    target=des.3openssl
+link path=usr/share/man/man3openssl/DH_OpenSSL.3openssl \
+    target=DH_set_method.3openssl
+link path=usr/share/man/man3openssl/DH_check.3openssl \
+    target=DH_generate_parameters.3openssl
+link path=usr/share/man/man3openssl/DH_compute_key.3openssl \
+    target=DH_generate_key.3openssl
+link path=usr/share/man/man3openssl/DH_free.3openssl target=DH_new.3openssl
+file path=usr/share/man/man3openssl/DH_generate_key.3openssl
+file path=usr/share/man/man3openssl/DH_generate_parameters.3openssl
+link path=usr/share/man/man3openssl/DH_get_default_method.3openssl \
+    target=DH_set_method.3openssl
+link path=usr/share/man/man3openssl/DH_get_ex_data.3openssl \
+    target=DH_get_ex_new_index.3openssl
+file path=usr/share/man/man3openssl/DH_get_ex_new_index.3openssl
+file path=usr/share/man/man3openssl/DH_new.3openssl
+link path=usr/share/man/man3openssl/DH_new_method.3openssl \
+    target=DH_set_method.3openssl
+link path=usr/share/man/man3openssl/DH_set_default_method.3openssl \
+    target=DH_set_method.3openssl
+link path=usr/share/man/man3openssl/DH_set_ex_data.3openssl \
+    target=DH_get_ex_new_index.3openssl
+file path=usr/share/man/man3openssl/DH_set_method.3openssl
+file path=usr/share/man/man3openssl/DH_size.3openssl
+link path=usr/share/man/man3openssl/DHparams_print.3openssl \
+    target=RSA_print.3openssl
+link path=usr/share/man/man3openssl/DHparams_print_fp.3openssl \
+    target=RSA_print.3openssl
+link path=usr/share/man/man3openssl/DSA_OpenSSL.3openssl \
+    target=DSA_set_method.3openssl
+link path=usr/share/man/man3openssl/DSA_SIG_free.3openssl \
+    target=DSA_SIG_new.3openssl
+file path=usr/share/man/man3openssl/DSA_SIG_new.3openssl
+file path=usr/share/man/man3openssl/DSA_do_sign.3openssl
+link path=usr/share/man/man3openssl/DSA_do_verify.3openssl \
+    target=DSA_do_sign.3openssl
+file path=usr/share/man/man3openssl/DSA_dup_DH.3openssl
+link path=usr/share/man/man3openssl/DSA_free.3openssl target=DSA_new.3openssl
+file path=usr/share/man/man3openssl/DSA_generate_key.3openssl
+file path=usr/share/man/man3openssl/DSA_generate_parameters.3openssl
+link path=usr/share/man/man3openssl/DSA_get_default_method.3openssl \
+    target=DSA_set_method.3openssl
+link path=usr/share/man/man3openssl/DSA_get_ex_data.3openssl \
+    target=DSA_get_ex_new_index.3openssl
+file path=usr/share/man/man3openssl/DSA_get_ex_new_index.3openssl
+file path=usr/share/man/man3openssl/DSA_new.3openssl
+link path=usr/share/man/man3openssl/DSA_new_method.3openssl \
+    target=DSA_set_method.3openssl
+link path=usr/share/man/man3openssl/DSA_print.3openssl target=RSA_print.3openssl
+link path=usr/share/man/man3openssl/DSA_print_fp.3openssl \
+    target=RSA_print.3openssl
+link path=usr/share/man/man3openssl/DSA_set_default_method.3openssl \
+    target=DSA_set_method.3openssl
+link path=usr/share/man/man3openssl/DSA_set_ex_data.3openssl \
+    target=DSA_get_ex_new_index.3openssl
+file path=usr/share/man/man3openssl/DSA_set_method.3openssl
+file path=usr/share/man/man3openssl/DSA_sign.3openssl
+link path=usr/share/man/man3openssl/DSA_sign_setup.3openssl \
+    target=DSA_sign.3openssl
+file path=usr/share/man/man3openssl/DSA_size.3openssl
+link path=usr/share/man/man3openssl/DSA_verify.3openssl target=DSA_sign.3openssl
+link path=usr/share/man/man3openssl/DSAparams_print.3openssl \
+    target=RSA_print.3openssl
+link path=usr/share/man/man3openssl/DSAparams_print_fp.3openssl \
+    target=RSA_print.3openssl
+link path=usr/share/man/man3openssl/ERR_GET_FUNC.3openssl \
+    target=ERR_GET_LIB.3openssl
+file path=usr/share/man/man3openssl/ERR_GET_LIB.3openssl
+link path=usr/share/man/man3openssl/ERR_GET_REASON.3openssl \
+    target=ERR_GET_LIB.3openssl
+link path=usr/share/man/man3openssl/ERR_PACK.3openssl \
+    target=ERR_load_strings.3openssl
+link path=usr/share/man/man3openssl/ERR_add_error_data.3openssl \
+    target=ERR_put_error.3openssl
+file path=usr/share/man/man3openssl/ERR_clear_error.3openssl
+file path=usr/share/man/man3openssl/ERR_error_string.3openssl
+link path=usr/share/man/man3openssl/ERR_error_string_n.3openssl \
+    target=ERR_error_string.3openssl
+link path=usr/share/man/man3openssl/ERR_free_strings.3openssl \
+    target=ERR_load_crypto_strings.3openssl
+link path=usr/share/man/man3openssl/ERR_func_error_string.3openssl \
+    target=ERR_error_string.3openssl
+file path=usr/share/man/man3openssl/ERR_get_error.3openssl
+link path=usr/share/man/man3openssl/ERR_get_error_line.3openssl \
+    target=ERR_get_error.3openssl
+link path=usr/share/man/man3openssl/ERR_get_error_line_data.3openssl \
+    target=ERR_get_error.3openssl
+link path=usr/share/man/man3openssl/ERR_get_next_error_library.3openssl \
+    target=ERR_load_strings.3openssl
+link path=usr/share/man/man3openssl/ERR_lib_error_string.3openssl \
+    target=ERR_error_string.3openssl
+link path=usr/share/man/man3openssl/ERR_load_UI_strings.3openssl \
+    target=ui.3openssl
+file path=usr/share/man/man3openssl/ERR_load_crypto_strings.3openssl
+file path=usr/share/man/man3openssl/ERR_load_strings.3openssl
+link path=usr/share/man/man3openssl/ERR_peek_error.3openssl \
+    target=ERR_get_error.3openssl
+link path=usr/share/man/man3openssl/ERR_peek_error_line.3openssl \
+    target=ERR_get_error.3openssl
+link path=usr/share/man/man3openssl/ERR_peek_error_line_data.3openssl \
+    target=ERR_get_error.3openssl
+link path=usr/share/man/man3openssl/ERR_peek_last_error.3openssl \
+    target=ERR_get_error.3openssl
+link path=usr/share/man/man3openssl/ERR_peek_last_error_line.3openssl \
+    target=ERR_get_error.3openssl
+link path=usr/share/man/man3openssl/ERR_peek_last_error_line_data.3openssl \
+    target=ERR_get_error.3openssl
+link path=usr/share/man/man3openssl/ERR_pop_to_mark.3openssl \
+    target=ERR_set_mark.3openssl
+file path=usr/share/man/man3openssl/ERR_print_errors.3openssl
+link path=usr/share/man/man3openssl/ERR_print_errors_fp.3openssl \
+    target=ERR_print_errors.3openssl
+file path=usr/share/man/man3openssl/ERR_put_error.3openssl
+link path=usr/share/man/man3openssl/ERR_reason_error_string.3openssl \
+    target=ERR_error_string.3openssl
+file path=usr/share/man/man3openssl/ERR_remove_state.3openssl
+file path=usr/share/man/man3openssl/ERR_set_mark.3openssl
+file path=usr/share/man/man3openssl/EVP_BytesToKey.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_block_size.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_cipher.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_cleanup.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_ctrl.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_flags.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_get_app_data.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_init.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_iv_length.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_key_length.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_mode.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_nid.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_set_app_data.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_set_key_length.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_set_padding.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_CTX_type.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_asn1_to_param.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_block_size.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_flags.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_iv_length.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_key_length.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_mode.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_nid.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_param_to_asn1.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CIPHER_type.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CipherFinal.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CipherFinal_ex.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CipherInit.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CipherInit_ex.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_CipherUpdate.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_DecryptFinal.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_DecryptFinal_ex.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_DecryptInit.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_DecryptInit_ex.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_DecryptUpdate.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_DigestFinal_ex.3openssl \
+    target=EVP_DigestInit.3openssl
+file path=usr/share/man/man3openssl/EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_DigestInit_ex.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_DigestSignFinal.3openssl \
+    target=EVP_DigestSignInit.3openssl
+file path=usr/share/man/man3openssl/EVP_DigestSignInit.3openssl
+link path=usr/share/man/man3openssl/EVP_DigestSignUpdate.3openssl \
+    target=EVP_DigestSignInit.3openssl
+link path=usr/share/man/man3openssl/EVP_DigestUpdate.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_DigestVerifyFinal.3openssl \
+    target=EVP_DigestVerifyInit.3openssl
+file path=usr/share/man/man3openssl/EVP_DigestVerifyInit.3openssl
+link path=usr/share/man/man3openssl/EVP_DigestVerifyUpdate.3openssl \
+    target=EVP_DigestVerifyInit.3openssl
+link path=usr/share/man/man3openssl/EVP_EncryptFinal.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_EncryptFinal_ex.3openssl \
+    target=EVP_EncryptInit.3openssl
+file path=usr/share/man/man3openssl/EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_EncryptInit_ex.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_EncryptUpdate.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_MAX_MD_SIZE.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_MD_CTX_block_size.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_MD_CTX_cleanup.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_MD_CTX_copy.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_MD_CTX_copy_ex.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_MD_CTX_create.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_MD_CTX_destroy.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_MD_CTX_init.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_MD_CTX_md.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_MD_CTX_size.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_MD_CTX_type.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_MD_block_size.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_MD_pkey_type.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_MD_size.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_MD_type.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_OpenFinal.3openssl \
+    target=EVP_OpenInit.3openssl
+file path=usr/share/man/man3openssl/EVP_OpenInit.3openssl
+link path=usr/share/man/man3openssl/EVP_OpenUpdate.3openssl \
+    target=EVP_OpenInit.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEVP_PKEY_CTX_set_app_data.3openssl \
+    target=EVP_PKEY_keygen.3openssl
+file path=usr/share/man/man3openssl/EVP_PKEY_CTX_ctrl.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_CTX_dup.3openssl \
+    target=EVP_PKEY_CTX_new.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_CTX_free.3openssl \
+    target=EVP_PKEY_CTX_new.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_CTX_get_app_data.3openssl \
+    target=EVP_PKEY_keygen.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_CTX_get_cb.3openssl \
+    target=EVP_PKEY_keygen.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_CTX_get_keygen_info.3openssl \
+    target=EVP_PKEY_keygen.3openssl
+file path=usr/share/man/man3openssl/EVP_PKEY_CTX_new.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_CTX_new_id.3openssl \
+    target=EVP_PKEY_CTX_new.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_CTX_set_cb.3openssl \
+    target=EVP_PKEY_keygen.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_assign_DH.3openssl \
+    target=EVP_PKEY_set1_RSA.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_assign_DSA.3openssl \
+    target=EVP_PKEY_set1_RSA.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_assign_EC_KEY.3openssl \
+    target=EVP_PKEY_set1_RSA.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_assign_RSA.3openssl \
+    target=EVP_PKEY_set1_RSA.3openssl
+file path=usr/share/man/man3openssl/EVP_PKEY_cmp.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_cmp_parameters.3openssl \
+    target=EVP_PKEY_cmp.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_copy_parameters.3openssl \
+    target=EVP_PKEY_cmp.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_ctrl.3openssl \
+    target=EVP_PKEY_CTX_ctrl.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_ctrl_str.3openssl \
+    target=EVP_PKEY_CTX_ctrl.3openssl
+file path=usr/share/man/man3openssl/EVP_PKEY_decrypt.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_decrypt_init.3openssl \
+    target=EVP_PKEY_decrypt.3openssl
+file path=usr/share/man/man3openssl/EVP_PKEY_derive.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_derive_init.3openssl \
+    target=EVP_PKEY_derive.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_derive_set_peer.3openssl \
+    target=EVP_PKEY_derive.3openssl
+file path=usr/share/man/man3openssl/EVP_PKEY_encrypt.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_encrypt_init.3openssl \
+    target=EVP_PKEY_encrypt.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_free.3openssl \
+    target=EVP_PKEY_new.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_get1_DH.3openssl \
+    target=EVP_PKEY_set1_RSA.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_get1_DSA.3openssl \
+    target=EVP_PKEY_set1_RSA.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_get1_EC_KEY.3openssl \
+    target=EVP_PKEY_set1_RSA.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_get1_RSA.3openssl \
+    target=EVP_PKEY_set1_RSA.3openssl
+file path=usr/share/man/man3openssl/EVP_PKEY_get_default_digest.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_get_default_digest_nid.3openssl \
+    target=EVP_PKEY_get_default_digest.3openssl
+file path=usr/share/man/man3openssl/EVP_PKEY_keygen.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_keygen_init.3openssl \
+    target=EVP_PKEY_keygen.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_missing_parameters.3openssl \
+    target=EVP_PKEY_cmp.3openssl
+file path=usr/share/man/man3openssl/EVP_PKEY_new.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_paramgen.3openssl \
+    target=EVP_PKEY_keygen.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_paramgen_init.3openssl \
+    target=EVP_PKEY_keygen.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_print_params.3openssl \
+    target=EVP_PKEY_print_private.3openssl
+file path=usr/share/man/man3openssl/EVP_PKEY_print_private.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_print_public.3openssl \
+    target=EVP_PKEY_print_private.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_set1_DH.3openssl \
+    target=EVP_PKEY_set1_RSA.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_set1_DSA.3openssl \
+    target=EVP_PKEY_set1_RSA.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_set1_EC_KEY.3openssl \
+    target=EVP_PKEY_set1_RSA.3openssl
+file path=usr/share/man/man3openssl/EVP_PKEY_set1_RSA.3openssl
+file path=usr/share/man/man3openssl/EVP_PKEY_sign.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_sign_init.3openssl \
+    target=EVP_PKEY_sign.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_type.3openssl \
+    target=EVP_PKEY_set1_RSA.3openssl
+file path=usr/share/man/man3openssl/EVP_PKEY_verify.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_verify_init.3openssl \
+    target=EVP_PKEY_verify.3openssl
+file path=usr/share/man/man3openssl/EVP_PKEY_verify_recover.3openssl
+link path=usr/share/man/man3openssl/EVP_PKEY_verify_recover_init.3openssl \
+    target=EVP_PKEY_verify_recover.3openssl
+link path=usr/share/man/man3openssl/EVP_SealFinal.3openssl \
+    target=EVP_SealInit.3openssl
+file path=usr/share/man/man3openssl/EVP_SealInit.3openssl
+link path=usr/share/man/man3openssl/EVP_SealUpdate.3openssl \
+    target=EVP_SealInit.3openssl
+link path=usr/share/man/man3openssl/EVP_SignFinal.3openssl \
+    target=EVP_SignInit.3openssl
+file path=usr/share/man/man3openssl/EVP_SignInit.3openssl
+link path=usr/share/man/man3openssl/EVP_SignUpdate.3openssl \
+    target=EVP_SignInit.3openssl
+link path=usr/share/man/man3openssl/EVP_VerifyFinal.3openssl \
+    target=EVP_VerifyInit.3openssl
+file path=usr/share/man/man3openssl/EVP_VerifyInit.3openssl
+link path=usr/share/man/man3openssl/EVP_VerifyUpdate.3openssl \
+    target=EVP_VerifyInit.3openssl
+link path=usr/share/man/man3openssl/EVP_dss.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_dss1.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_get_cipherbyname.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_get_cipherbynid.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_get_cipherbyobj.3openssl \
+    target=EVP_EncryptInit.3openssl
+link path=usr/share/man/man3openssl/EVP_get_digestbyname.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_get_digestbynid.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_get_digestbyobj.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_md2.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_md5.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_md_null.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_mdc2.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_ripemd160.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_sha.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/EVP_sha1.3openssl \
+    target=EVP_DigestInit.3openssl
+link path=usr/share/man/man3openssl/HMAC.3openssl target=hmac.3openssl
+link path=usr/share/man/man3openssl/HMAC_CTX_cleanup.3openssl \
+    target=hmac.3openssl
+link path=usr/share/man/man3openssl/HMAC_CTX_init.3openssl target=hmac.3openssl
+link path=usr/share/man/man3openssl/HMAC_Final.3openssl target=hmac.3openssl
+link path=usr/share/man/man3openssl/HMAC_Init.3openssl target=hmac.3openssl
+link path=usr/share/man/man3openssl/HMAC_Init_ex.3openssl target=hmac.3openssl
+link path=usr/share/man/man3openssl/HMAC_Update.3openssl target=hmac.3openssl
+link path=usr/share/man/man3openssl/HMAC_cleanup.3openssl target=hmac.3openssl
+link path=usr/share/man/man3openssl/MD2.3openssl target=md5.3openssl
+link path=usr/share/man/man3openssl/MD2_Final.3openssl target=md5.3openssl
+link path=usr/share/man/man3openssl/MD2_Init.3openssl target=md5.3openssl
+link path=usr/share/man/man3openssl/MD2_Update.3openssl target=md5.3openssl
+link path=usr/share/man/man3openssl/MD4.3openssl target=md5.3openssl
+link path=usr/share/man/man3openssl/MD4_Final.3openssl target=md5.3openssl
+link path=usr/share/man/man3openssl/MD4_Init.3openssl target=md5.3openssl
+link path=usr/share/man/man3openssl/MD4_Update.3openssl target=md5.3openssl
+link path=usr/share/man/man3openssl/MD5.3openssl target=md5.3openssl
+link path=usr/share/man/man3openssl/MD5_Final.3openssl target=md5.3openssl
+link path=usr/share/man/man3openssl/MD5_Init.3openssl target=md5.3openssl
+link path=usr/share/man/man3openssl/MD5_Update.3openssl target=md5.3openssl
+link path=usr/share/man/man3openssl/MDC2.3openssl target=mdc2.3openssl
+link path=usr/share/man/man3openssl/MDC2_Final.3openssl target=mdc2.3openssl
+link path=usr/share/man/man3openssl/MDC2_Init.3openssl target=mdc2.3openssl
+link path=usr/share/man/man3openssl/MDC2_Update.3openssl target=mdc2.3openssl
+link path=usr/share/man/man3openssl/OBJ_cleanup.3openssl \
+    target=OBJ_nid2obj.3openssl
+link path=usr/share/man/man3openssl/OBJ_cmp.3openssl target=OBJ_nid2obj.3openssl
+link path=usr/share/man/man3openssl/OBJ_create.3openssl \
+    target=OBJ_nid2obj.3openssl
+link path=usr/share/man/man3openssl/OBJ_dup.3openssl target=OBJ_nid2obj.3openssl
+link path=usr/share/man/man3openssl/OBJ_ln2nid.3openssl \
+    target=OBJ_nid2obj.3openssl
+link path=usr/share/man/man3openssl/OBJ_nid2ln.3openssl \
+    target=OBJ_nid2obj.3openssl
+file path=usr/share/man/man3openssl/OBJ_nid2obj.3openssl
+link path=usr/share/man/man3openssl/OBJ_nid2sn.3openssl \
+    target=OBJ_nid2obj.3openssl
+link path=usr/share/man/man3openssl/OBJ_obj2nid.3openssl \
+    target=OBJ_nid2obj.3openssl
+link path=usr/share/man/man3openssl/OBJ_obj2txt.3openssl \
+    target=OBJ_nid2obj.3openssl
+link path=usr/share/man/man3openssl/OBJ_sn2nid.3openssl \
+    target=OBJ_nid2obj.3openssl
+link path=usr/share/man/man3openssl/OBJ_txt2nid.3openssl \
+    target=OBJ_nid2obj.3openssl
+link path=usr/share/man/man3openssl/OBJ_txt2obj.3openssl \
+    target=OBJ_nid2obj.3openssl
+file path=usr/share/man/man3openssl/OPENSSL_Applink.3openssl
+file path=usr/share/man/man3openssl/OPENSSL_VERSION_NUMBER.3openssl
+file path=usr/share/man/man3openssl/OPENSSL_config.3openssl
+file path=usr/share/man/man3openssl/OPENSSL_ia32cap.3openssl
+file path=usr/share/man/man3openssl/OPENSSL_load_builtin_modules.3openssl
+link path=usr/share/man/man3openssl/OPENSSL_no_config.3openssl \
+    target=OPENSSL_config.3openssl
+file path=usr/share/man/man3openssl/OpenSSL_add_all_algorithms.3openssl
+link path=usr/share/man/man3openssl/OpenSSL_add_all_ciphers.3openssl \
+    target=OpenSSL_add_all_algorithms.3openssl
+link path=usr/share/man/man3openssl/OpenSSL_add_all_digests.3openssl \
+    target=OpenSSL_add_all_algorithms.3openssl
+link path=usr/share/man/man3openssl/OpenSSL_add_ssl_algorithms.3openssl \
+    target=SSL_library_init.3openssl
+link path=usr/share/man/man3openssl/PEM.3openssl target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_DHparams.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_DSAPrivateKey.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_DSA_PUBKEY.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_DSAparams.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_NETSCAPE_CERT_SEQUENCE.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_PKCS7.3openssl target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_PUBKEY.3openssl target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_PrivateKey.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_RSAPrivateKey.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_RSAPublicKey.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_RSA_PUBKEY.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_X509.3openssl target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_X509_AUX.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_X509_CRL.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_X509_REQ.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_bio_DHparams.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_bio_DSAPrivateKey.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_bio_DSA_PUBKEY.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_bio_DSAparams.3openssl \
+    target=pem.3openssl
+link \
+    path=usr/share/man/man3openssl/PEM_read_bio_NETSCAPE_CERT_SEQUENCE.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_bio_PKCS7.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_bio_PUBKEY.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_bio_PrivateKey.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_bio_RSAPrivateKey.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_bio_RSAPublicKey.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_bio_RSA_PUBKEY.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_bio_X509.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_bio_X509_AUX.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_bio_X509_CRL.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_read_bio_X509_REQ.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_DHparams.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_DSAPrivateKey.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_DSA_PUBKEY.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_DSAparams.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_NETSCAPE_CERT_SEQUENCE.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_PKCS7.3openssl target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_PKCS8PrivateKey.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_PKCS8PrivateKey_nid.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_PUBKEY.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_PrivateKey.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_RSAPrivateKey.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_RSAPublicKey.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_RSA_PUBKEY.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_X509.3openssl target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_X509_AUX.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_X509_CRL.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_X509_REQ.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_X509_REQ_NEW.3openssl \
+    target=pem.3openssl
+file path=usr/share/man/man3openssl/PEM_write_bio_CMS_stream.3openssl
+link path=usr/share/man/man3openssl/PEM_write_bio_DHparams.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_bio_DSAPrivateKey.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_bio_DSA_PUBKEY.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_bio_DSAparams.3openssl \
+    target=pem.3openssl
+link \
+    path=usr/share/man/man3openssl/PEM_write_bio_NETSCAPE_CERT_SEQUENCE.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_bio_PKCS7.3openssl \
+    target=pem.3openssl
+file path=usr/share/man/man3openssl/PEM_write_bio_PKCS7_stream.3openssl
+link path=usr/share/man/man3openssl/PEM_write_bio_PKCS8PrivateKey.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_bio_PKCS8PrivateKey_nid.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_bio_PUBKEY.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_bio_PrivateKey.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_bio_RSAPrivateKey.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_bio_RSAPublicKey.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_bio_RSA_PUBKEY.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_bio_X509.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_bio_X509_AUX.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_bio_X509_CRL.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_bio_X509_REQ.3openssl \
+    target=pem.3openssl
+link path=usr/share/man/man3openssl/PEM_write_bio_X509_REQ_NEW.3openssl \
+    target=pem.3openssl
+file path=usr/share/man/man3openssl/PKCS12_create.3openssl
+file path=usr/share/man/man3openssl/PKCS12_parse.3openssl
+file path=usr/share/man/man3openssl/PKCS7_decrypt.3openssl
+file path=usr/share/man/man3openssl/PKCS7_encrypt.3openssl
+file path=usr/share/man/man3openssl/PKCS7_sign.3openssl
+file path=usr/share/man/man3openssl/PKCS7_sign_add_signer.3openssl
+file path=usr/share/man/man3openssl/PKCS7_verify.3openssl
+link path=usr/share/man/man3openssl/RAND_SSLeay.3openssl \
+    target=RAND_set_rand_method.3openssl
+file path=usr/share/man/man3openssl/RAND_add.3openssl
+file path=usr/share/man/man3openssl/RAND_bytes.3openssl
+file path=usr/share/man/man3openssl/RAND_cleanup.3openssl
+file path=usr/share/man/man3openssl/RAND_egd.3openssl
+link path=usr/share/man/man3openssl/RAND_event.3openssl target=RAND_add.3openssl
+link path=usr/share/man/man3openssl/RAND_file_name.3openssl \
+    target=RAND_load_file.3openssl
+link path=usr/share/man/man3openssl/RAND_get_rand_method.3openssl \
+    target=RAND_set_rand_method.3openssl
+file path=usr/share/man/man3openssl/RAND_load_file.3openssl
+link path=usr/share/man/man3openssl/RAND_pseudo_bytes.3openssl \
+    target=RAND_bytes.3openssl
+link path=usr/share/man/man3openssl/RAND_screen.3openssl \
+    target=RAND_add.3openssl
+link path=usr/share/man/man3openssl/RAND_seed.3openssl target=RAND_add.3openssl
+file path=usr/share/man/man3openssl/RAND_set_rand_method.3openssl
+link path=usr/share/man/man3openssl/RAND_status.3openssl \
+    target=RAND_add.3openssl
+link path=usr/share/man/man3openssl/RAND_write_file.3openssl \
+    target=RAND_load_file.3openssl
+link path=usr/share/man/man3openssl/RC4.3openssl target=rc4.3openssl
+link path=usr/share/man/man3openssl/RC4_set_key.3openssl target=rc4.3openssl
+link path=usr/share/man/man3openssl/RIPEMD160.3openssl target=ripemd.3openssl
+link path=usr/share/man/man3openssl/RIPEMD160_Final.3openssl \
+    target=ripemd.3openssl
+link path=usr/share/man/man3openssl/RIPEMD160_Init.3openssl \
+    target=ripemd.3openssl
+link path=usr/share/man/man3openssl/RIPEMD160_Update.3openssl \
+    target=ripemd.3openssl
+link path=usr/share/man/man3openssl/RSA_PKCS1_SSLeay.3openssl \
+    target=RSA_set_method.3openssl
+link path=usr/share/man/man3openssl/RSA_blinding_off.3openssl \
+    target=RSA_blinding_on.3openssl
+file path=usr/share/man/man3openssl/RSA_blinding_on.3openssl
+file path=usr/share/man/man3openssl/RSA_check_key.3openssl
+link path=usr/share/man/man3openssl/RSA_flags.3openssl \
+    target=RSA_set_method.3openssl
+link path=usr/share/man/man3openssl/RSA_free.3openssl target=RSA_new.3openssl
+file path=usr/share/man/man3openssl/RSA_generate_key.3openssl
+link path=usr/share/man/man3openssl/RSA_get_default_method.3openssl \
+    target=RSA_set_method.3openssl
+link path=usr/share/man/man3openssl/RSA_get_ex_data.3openssl \
+    target=RSA_get_ex_new_index.3openssl
+file path=usr/share/man/man3openssl/RSA_get_ex_new_index.3openssl
+link path=usr/share/man/man3openssl/RSA_get_method.3openssl \
+    target=RSA_set_method.3openssl
+file path=usr/share/man/man3openssl/RSA_new.3openssl
+link path=usr/share/man/man3openssl/RSA_new_method.3openssl \
+    target=RSA_set_method.3openssl
+link path=usr/share/man/man3openssl/RSA_null_method.3openssl \
+    target=RSA_set_method.3openssl
+link path=usr/share/man/man3openssl/RSA_padding_add_PKCS1_OAEP.3openssl \
+    target=RSA_padding_add_PKCS1_type_1.3openssl
+file path=usr/share/man/man3openssl/RSA_padding_add_PKCS1_type_1.3openssl
+link path=usr/share/man/man3openssl/RSA_padding_add_PKCS1_type_2.3openssl \
+    target=RSA_padding_add_PKCS1_type_1.3openssl
+link path=usr/share/man/man3openssl/RSA_padding_add_SSLv23.3openssl \
+    target=RSA_padding_add_PKCS1_type_1.3openssl
+link path=usr/share/man/man3openssl/RSA_padding_add_none.3openssl \
+    target=RSA_padding_add_PKCS1_type_1.3openssl
+link path=usr/share/man/man3openssl/RSA_padding_check_PKCS1_OAEP.3openssl \
+    target=RSA_padding_add_PKCS1_type_1.3openssl
+link path=usr/share/man/man3openssl/RSA_padding_check_PKCS1_type_1.3openssl \
+    target=RSA_padding_add_PKCS1_type_1.3openssl
+link path=usr/share/man/man3openssl/RSA_padding_check_PKCS1_type_2.3openssl \
+    target=RSA_padding_add_PKCS1_type_1.3openssl
+link path=usr/share/man/man3openssl/RSA_padding_check_SSLv23.3openssl \
+    target=RSA_padding_add_PKCS1_type_1.3openssl
+link path=usr/share/man/man3openssl/RSA_padding_check_none.3openssl \
+    target=RSA_padding_add_PKCS1_type_1.3openssl
+file path=usr/share/man/man3openssl/RSA_print.3openssl
+link path=usr/share/man/man3openssl/RSA_print_fp.3openssl \
+    target=RSA_print.3openssl
+link path=usr/share/man/man3openssl/RSA_private_decrypt.3openssl \
+    target=RSA_public_encrypt.3openssl
+file path=usr/share/man/man3openssl/RSA_private_encrypt.3openssl
+link path=usr/share/man/man3openssl/RSA_public_decrypt.3openssl \
+    target=RSA_private_encrypt.3openssl
+file path=usr/share/man/man3openssl/RSA_public_encrypt.3openssl
+link path=usr/share/man/man3openssl/RSA_set_default_method.3openssl \
+    target=RSA_set_method.3openssl
+link path=usr/share/man/man3openssl/RSA_set_ex_data.3openssl \
+    target=RSA_get_ex_new_index.3openssl
+file path=usr/share/man/man3openssl/RSA_set_method.3openssl
+file path=usr/share/man/man3openssl/RSA_sign.3openssl
+file path=usr/share/man/man3openssl/RSA_sign_ASN1_OCTET_STRING.3openssl
+file path=usr/share/man/man3openssl/RSA_size.3openssl
+link path=usr/share/man/man3openssl/RSA_verify.3openssl target=RSA_sign.3openssl
+link path=usr/share/man/man3openssl/RSA_verify_ASN1_OCTET_STRING.3openssl \
+    target=RSA_sign_ASN1_OCTET_STRING.3openssl
+link path=usr/share/man/man3openssl/SHA1.3openssl target=sha.3openssl
+link path=usr/share/man/man3openssl/SHA1_Final.3openssl target=sha.3openssl
+link path=usr/share/man/man3openssl/SHA1_Init.3openssl target=sha.3openssl
+link path=usr/share/man/man3openssl/SHA1_Update.3openssl target=sha.3openssl
+file path=usr/share/man/man3openssl/SMIME_read_CMS.3openssl
+file path=usr/share/man/man3openssl/SMIME_read_PKCS7.3openssl
+file path=usr/share/man/man3openssl/SMIME_write_CMS.3openssl
+file path=usr/share/man/man3openssl/SMIME_write_PKCS7.3openssl
+link path=usr/share/man/man3openssl/SSL.3openssl target=ssl.3openssl
+link path=usr/share/man/man3openssl/SSL_CIPHER_description.3openssl \
+    target=SSL_CIPHER_get_name.3openssl
+link path=usr/share/man/man3openssl/SSL_CIPHER_get_bits.3openssl \
+    target=SSL_CIPHER_get_name.3openssl
+file path=usr/share/man/man3openssl/SSL_CIPHER_get_name.3openssl
+link path=usr/share/man/man3openssl/SSL_CIPHER_get_version.3openssl \
+    target=SSL_CIPHER_get_name.3openssl
+file path=usr/share/man/man3openssl/SSL_COMP_add_compression_method.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_add_client_CA.3openssl \
+    target=SSL_CTX_set_client_CA_list.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_add_extra_chain_cert.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_add_session.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_callback_ctrl.3openssl \
+    target=SSL_CTX_ctrl.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_check_private_key.3openssl \
+    target=SSL_CTX_use_certificate.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_clear_options.3openssl \
+    target=SSL_CTX_set_options.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_ctrl.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_flush_sessions.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_free.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_get_cert_store.3openssl \
+    target=SSL_CTX_set_cert_store.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_get_client_CA_list.3openssl \
+    target=SSL_get_client_CA_list.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_get_client_cert_cb.3openssl \
+    target=SSL_CTX_set_client_cert_cb.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_get_ex_data.3openssl \
+    target=SSL_CTX_get_ex_new_index.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_get_ex_new_index.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_get_info_callback.3openssl \
+    target=SSL_CTX_set_info_callback.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_get_max_cert_list.3openssl \
+    target=SSL_CTX_set_max_cert_list.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_get_mode.3openssl \
+    target=SSL_CTX_set_mode.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_get_options.3openssl \
+    target=SSL_CTX_set_options.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_get_quiet_shutdown.3openssl \
+    target=SSL_CTX_set_quiet_shutdown.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_get_session_cache_mode.3openssl \
+    target=SSL_CTX_set_session_cache_mode.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_get_timeout.3openssl \
+    target=SSL_CTX_set_timeout.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_get_verify_callback.3openssl \
+    target=SSL_CTX_get_verify_mode.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_get_verify_depth.3openssl \
+    target=SSL_CTX_get_verify_mode.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_get_verify_mode.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_load_verify_locations.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_need_tmp_rsa.3openssl \
+    target=SSL_CTX_set_tmp_rsa_callback.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_new.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_remove_session.3openssl \
+    target=SSL_CTX_add_session.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_sess_accept.3openssl \
+    target=SSL_CTX_sess_number.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_sess_accept_good.3openssl \
+    target=SSL_CTX_sess_number.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_sess_accept_renegotiate.3openssl \
+    target=SSL_CTX_sess_number.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_sess_cache_full.3openssl \
+    target=SSL_CTX_sess_number.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_sess_cb_hits.3openssl \
+    target=SSL_CTX_sess_number.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_sess_connect.3openssl \
+    target=SSL_CTX_sess_number.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_sess_connect_good.3openssl \
+    target=SSL_CTX_sess_number.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_sess_connect_renegotiate.3openssl \
+    target=SSL_CTX_sess_number.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_sess_get_cache_size.3openssl \
+    target=SSL_CTX_sess_set_cache_size.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_sess_get_get_cb.3openssl \
+    target=SSL_CTX_sess_set_get_cb.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_sess_get_new_cb.3openssl \
+    target=SSL_CTX_sess_set_get_cb.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_sess_get_remove_cb.3openssl \
+    target=SSL_CTX_sess_set_get_cb.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_sess_hits.3openssl \
+    target=SSL_CTX_sess_number.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_sess_misses.3openssl \
+    target=SSL_CTX_sess_number.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_sess_number.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_sess_set_cache_size.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_sess_set_get_cb.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_sess_set_new_cb.3openssl \
+    target=SSL_CTX_sess_set_get_cb.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_sess_set_remove_cb.3openssl \
+    target=SSL_CTX_sess_set_get_cb.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_sess_timeouts.3openssl \
+    target=SSL_CTX_sess_number.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_sessions.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_set_cert_store.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_set_cert_verify_callback.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_set_cipher_list.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_set_client_CA_list.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_set_client_cert_cb.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_set_default_passwd_cb.3openssl
+link \
+    path=usr/share/man/man3openssl/SSL_CTX_set_default_passwd_cb_userdata.3openssl \
+    target=SSL_CTX_set_default_passwd_cb.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_set_ex_data.3openssl \
+    target=SSL_CTX_get_ex_new_index.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_set_generate_session_id.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_set_info_callback.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_set_max_cert_list.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_set_mode.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_set_msg_callback.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_set_msg_callback_arg.3openssl \
+    target=SSL_CTX_set_msg_callback.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_set_options.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_set_psk_client_callback.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_set_psk_server_callback.3openssl \
+    target=SSL_CTX_use_psk_identity_hint.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_set_quiet_shutdown.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_set_session_cache_mode.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_set_session_id_context.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_set_ssl_version.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_set_timeout.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_set_tmp_dh.3openssl \
+    target=SSL_CTX_set_tmp_dh_callback.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_set_tmp_dh_callback.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_set_tmp_rsa.3openssl \
+    target=SSL_CTX_set_tmp_rsa_callback.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_set_tmp_rsa_callback.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_set_verify.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_set_verify_depth.3openssl \
+    target=SSL_CTX_set_verify.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_use_PrivateKey.3openssl \
+    target=SSL_CTX_use_certificate.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_use_PrivateKey_ASN1.3openssl \
+    target=SSL_CTX_use_certificate.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_use_PrivateKey_file.3openssl \
+    target=SSL_CTX_use_certificate.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_use_RSAPrivateKey.3openssl \
+    target=SSL_CTX_use_certificate.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_use_RSAPrivateKey_ASN1.3openssl \
+    target=SSL_CTX_use_certificate.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_use_RSAPrivateKey_file.3openssl \
+    target=SSL_CTX_use_certificate.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_use_certificate.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_use_certificate_ASN1.3openssl \
+    target=SSL_CTX_use_certificate.3openssl
+link \
+    path=usr/share/man/man3openssl/SSL_CTX_use_certificate_chain_file.3openssl \
+    target=SSL_CTX_use_certificate.3openssl
+link path=usr/share/man/man3openssl/SSL_CTX_use_certificate_file.3openssl \
+    target=SSL_CTX_use_certificate.3openssl
+file path=usr/share/man/man3openssl/SSL_CTX_use_psk_identity_hint.3openssl
+file path=usr/share/man/man3openssl/SSL_SESSION_free.3openssl
+link path=usr/share/man/man3openssl/SSL_SESSION_get_ex_data.3openssl \
+    target=SSL_SESSION_get_ex_new_index.3openssl
+file path=usr/share/man/man3openssl/SSL_SESSION_get_ex_new_index.3openssl
+file path=usr/share/man/man3openssl/SSL_SESSION_get_time.3openssl
+link path=usr/share/man/man3openssl/SSL_SESSION_get_timeout.3openssl \
+    target=SSL_SESSION_get_time.3openssl
+link path=usr/share/man/man3openssl/SSL_SESSION_set_ex_data.3openssl \
+    target=SSL_SESSION_get_ex_new_index.3openssl
+link path=usr/share/man/man3openssl/SSL_SESSION_set_time.3openssl \
+    target=SSL_SESSION_get_time.3openssl
+link path=usr/share/man/man3openssl/SSL_SESSION_set_timeout.3openssl \
+    target=SSL_SESSION_get_time.3openssl
+file path=usr/share/man/man3openssl/SSL_accept.3openssl
+link path=usr/share/man/man3openssl/SSL_add_client_CA.3openssl \
+    target=SSL_CTX_set_client_CA_list.3openssl
+link path=usr/share/man/man3openssl/SSL_add_session.3openssl \
+    target=SSL_CTX_add_session.3openssl
+link path=usr/share/man/man3openssl/SSL_alert_desc_string.3openssl \
+    target=SSL_alert_type_string.3openssl
+link path=usr/share/man/man3openssl/SSL_alert_desc_string_long.3openssl \
+    target=SSL_alert_type_string.3openssl
+file path=usr/share/man/man3openssl/SSL_alert_type_string.3openssl
+link path=usr/share/man/man3openssl/SSL_alert_type_string_long.3openssl \
+    target=SSL_alert_type_string.3openssl
+link path=usr/share/man/man3openssl/SSL_callback_ctrl.3openssl \
+    target=SSL_CTX_ctrl.3openssl
+link path=usr/share/man/man3openssl/SSL_check_private_key.3openssl \
+    target=SSL_CTX_use_certificate.3openssl
+file path=usr/share/man/man3openssl/SSL_clear.3openssl
+link path=usr/share/man/man3openssl/SSL_clear_options.3openssl \
+    target=SSL_CTX_set_options.3openssl
+file path=usr/share/man/man3openssl/SSL_connect.3openssl
+link path=usr/share/man/man3openssl/SSL_ctrl.3openssl \
+    target=SSL_CTX_ctrl.3openssl
+file path=usr/share/man/man3openssl/SSL_do_handshake.3openssl
+link path=usr/share/man/man3openssl/SSL_flush_sessions.3openssl \
+    target=SSL_CTX_flush_sessions.3openssl
+file path=usr/share/man/man3openssl/SSL_free.3openssl
+file path=usr/share/man/man3openssl/SSL_get_SSL_CTX.3openssl
+link path=usr/share/man/man3openssl/SSL_get_accept_state.3openssl \
+    target=SSL_set_connect_state.3openssl
+link path=usr/share/man/man3openssl/SSL_get_cipher.3openssl \
+    target=SSL_get_current_cipher.3openssl
+link path=usr/share/man/man3openssl/SSL_get_cipher_bits.3openssl \
+    target=SSL_get_current_cipher.3openssl
+link path=usr/share/man/man3openssl/SSL_get_cipher_list.3openssl \
+    target=SSL_get_ciphers.3openssl
+link path=usr/share/man/man3openssl/SSL_get_cipher_name.3openssl \
+    target=SSL_get_current_cipher.3openssl
+link path=usr/share/man/man3openssl/SSL_get_cipher_version.3openssl \
+    target=SSL_get_current_cipher.3openssl
+file path=usr/share/man/man3openssl/SSL_get_ciphers.3openssl
+file path=usr/share/man/man3openssl/SSL_get_client_CA_list.3openssl
+file path=usr/share/man/man3openssl/SSL_get_current_cipher.3openssl
+file path=usr/share/man/man3openssl/SSL_get_default_timeout.3openssl
+file path=usr/share/man/man3openssl/SSL_get_error.3openssl
+link path=usr/share/man/man3openssl/SSL_get_ex_data.3openssl \
+    target=SSL_get_ex_new_index.3openssl
+file path=usr/share/man/man3openssl/SSL_get_ex_data_X509_STORE_CTX_idx.3openssl
+file path=usr/share/man/man3openssl/SSL_get_ex_new_index.3openssl
+file path=usr/share/man/man3openssl/SSL_get_fd.3openssl
+link path=usr/share/man/man3openssl/SSL_get_info_callback.3openssl \
+    target=SSL_CTX_set_info_callback.3openssl
+link path=usr/share/man/man3openssl/SSL_get_max_cert_list.3openssl \
+    target=SSL_CTX_set_max_cert_list.3openssl
+link path=usr/share/man/man3openssl/SSL_get_mode.3openssl \
+    target=SSL_CTX_set_mode.3openssl
+link path=usr/share/man/man3openssl/SSL_get_msg_callback_arg.3openssl \
+    target=SSL_CTX_set_msg_callback.3openssl
+link path=usr/share/man/man3openssl/SSL_get_options.3openssl \
+    target=SSL_CTX_set_options.3openssl
+file path=usr/share/man/man3openssl/SSL_get_peer_cert_chain.3openssl
+file path=usr/share/man/man3openssl/SSL_get_peer_certificate.3openssl
+file path=usr/share/man/man3openssl/SSL_get_psk_identity.3openssl
+link path=usr/share/man/man3openssl/SSL_get_psk_identity_hint.3openssl \
+    target=SSL_get_psk_identity.3openssl
+link path=usr/share/man/man3openssl/SSL_get_quiet_shutdown.3openssl \
+    target=SSL_CTX_set_quiet_shutdown.3openssl
+file path=usr/share/man/man3openssl/SSL_get_rbio.3openssl
+link \
+    path=usr/share/man/man3openssl/SSL_get_secure_renegotiation_support.3openssl \
+    target=SSL_CTX_set_options.3openssl
+file path=usr/share/man/man3openssl/SSL_get_session.3openssl
+link path=usr/share/man/man3openssl/SSL_get_shutdown.3openssl \
+    target=SSL_set_shutdown.3openssl
+link path=usr/share/man/man3openssl/SSL_get_ssl_method.3openssl \
+    target=SSL_CTX_set_ssl_version.3openssl
+link path=usr/share/man/man3openssl/SSL_get_verify_callback.3openssl \
+    target=SSL_CTX_get_verify_mode.3openssl
+link path=usr/share/man/man3openssl/SSL_get_verify_depth.3openssl \
+    target=SSL_CTX_get_verify_mode.3openssl
+link path=usr/share/man/man3openssl/SSL_get_verify_mode.3openssl \
+    target=SSL_CTX_get_verify_mode.3openssl
+file path=usr/share/man/man3openssl/SSL_get_verify_result.3openssl
+file path=usr/share/man/man3openssl/SSL_get_version.3openssl
+link path=usr/share/man/man3openssl/SSL_has_matching_session_id.3openssl \
+    target=SSL_CTX_set_generate_session_id.3openssl
+file path=usr/share/man/man3openssl/SSL_library_init.3openssl
+file path=usr/share/man/man3openssl/SSL_load_client_CA_file.3openssl
+link path=usr/share/man/man3openssl/SSL_load_error_strings.3openssl \
+    target=ERR_load_crypto_strings.3openssl
+link path=usr/share/man/man3openssl/SSL_need_tmp_rsa.3openssl \
+    target=SSL_CTX_set_tmp_rsa_callback.3openssl
+file path=usr/share/man/man3openssl/SSL_new.3openssl
+file path=usr/share/man/man3openssl/SSL_pending.3openssl
+file path=usr/share/man/man3openssl/SSL_read.3openssl
+link path=usr/share/man/man3openssl/SSL_remove_session.3openssl \
+    target=SSL_CTX_add_session.3openssl
+file path=usr/share/man/man3openssl/SSL_rstate_string.3openssl
+link path=usr/share/man/man3openssl/SSL_rstate_string_long.3openssl \
+    target=SSL_rstate_string.3openssl
+file path=usr/share/man/man3openssl/SSL_session_reused.3openssl
+file path=usr/share/man/man3openssl/SSL_set_bio.3openssl
+link path=usr/share/man/man3openssl/SSL_set_cipher_list.3openssl \
+    target=SSL_CTX_set_cipher_list.3openssl
+link path=usr/share/man/man3openssl/SSL_set_client_CA_list.3openssl \
+    target=SSL_CTX_set_client_CA_list.3openssl
+file path=usr/share/man/man3openssl/SSL_set_connect_state.3openssl
+link path=usr/share/man/man3openssl/SSL_set_ex_data.3openssl \
+    target=SSL_get_ex_new_index.3openssl
+file path=usr/share/man/man3openssl/SSL_set_fd.3openssl
+link path=usr/share/man/man3openssl/SSL_set_generate_session_id.3openssl \
+    target=SSL_CTX_set_generate_session_id.3openssl
+link path=usr/share/man/man3openssl/SSL_set_info_callback.3openssl \
+    target=SSL_CTX_set_info_callback.3openssl
+link path=usr/share/man/man3openssl/SSL_set_max_cert_list.3openssl \
+    target=SSL_CTX_set_max_cert_list.3openssl
+link path=usr/share/man/man3openssl/SSL_set_mode.3openssl \
+    target=SSL_CTX_set_mode.3openssl
+link path=usr/share/man/man3openssl/SSL_set_msg_callback.3openssl \
+    target=SSL_CTX_set_msg_callback.3openssl
+link path=usr/share/man/man3openssl/SSL_set_options.3openssl \
+    target=SSL_CTX_set_options.3openssl
+link path=usr/share/man/man3openssl/SSL_set_psk_client_callback.3openssl \
+    target=SSL_CTX_set_psk_client_callback.3openssl
+link path=usr/share/man/man3openssl/SSL_set_psk_server_callback.3openssl \
+    target=SSL_CTX_use_psk_identity_hint.3openssl
+link path=usr/share/man/man3openssl/SSL_set_quiet_shutdown.3openssl \
+    target=SSL_CTX_set_quiet_shutdown.3openssl
+file path=usr/share/man/man3openssl/SSL_set_session.3openssl
+link path=usr/share/man/man3openssl/SSL_set_session_id_context.3openssl \
+    target=SSL_CTX_set_session_id_context.3openssl
+file path=usr/share/man/man3openssl/SSL_set_shutdown.3openssl
+link path=usr/share/man/man3openssl/SSL_set_ssl_method.3openssl \
+    target=SSL_CTX_set_ssl_version.3openssl
+link path=usr/share/man/man3openssl/SSL_set_tmp_dh.3openssl \
+    target=SSL_CTX_set_tmp_dh_callback.3openssl
+link path=usr/share/man/man3openssl/SSL_set_tmp_dh_callback.3openssl \
+    target=SSL_CTX_set_tmp_dh_callback.3openssl
+link path=usr/share/man/man3openssl/SSL_set_tmp_rsa.3openssl \
+    target=SSL_CTX_set_tmp_rsa_callback.3openssl
+link path=usr/share/man/man3openssl/SSL_set_tmp_rsa_callback.3openssl \
+    target=SSL_CTX_set_tmp_rsa_callback.3openssl
+link path=usr/share/man/man3openssl/SSL_set_verify.3openssl \
+    target=SSL_CTX_set_verify.3openssl
+link path=usr/share/man/man3openssl/SSL_set_verify_depth.3openssl \
+    target=SSL_CTX_set_verify.3openssl
+file path=usr/share/man/man3openssl/SSL_set_verify_result.3openssl
+file path=usr/share/man/man3openssl/SSL_shutdown.3openssl
+file path=usr/share/man/man3openssl/SSL_state_string.3openssl
+link path=usr/share/man/man3openssl/SSL_state_string_long.3openssl \
+    target=SSL_state_string.3openssl
+link path=usr/share/man/man3openssl/SSL_use_PrivateKey.3openssl \
+    target=SSL_CTX_use_certificate.3openssl
+link path=usr/share/man/man3openssl/SSL_use_PrivateKey_ASN1.3openssl \
+    target=SSL_CTX_use_certificate.3openssl
+link path=usr/share/man/man3openssl/SSL_use_PrivateKey_file.3openssl \
+    target=SSL_CTX_use_certificate.3openssl
+link path=usr/share/man/man3openssl/SSL_use_RSAPrivateKey.3openssl \
+    target=SSL_CTX_use_certificate.3openssl
+link path=usr/share/man/man3openssl/SSL_use_RSAPrivateKey_ASN1.3openssl \
+    target=SSL_CTX_use_certificate.3openssl
+link path=usr/share/man/man3openssl/SSL_use_RSAPrivateKey_file.3openssl \
+    target=SSL_CTX_use_certificate.3openssl
+link path=usr/share/man/man3openssl/SSL_use_certificate.3openssl \
+    target=SSL_CTX_use_certificate.3openssl
+link path=usr/share/man/man3openssl/SSL_use_certificate_ASN1.3openssl \
+    target=SSL_CTX_use_certificate.3openssl
+link path=usr/share/man/man3openssl/SSL_use_certificate_file.3openssl \
+    target=SSL_CTX_use_certificate.3openssl
+link path=usr/share/man/man3openssl/SSL_use_psk_identity_hint.3openssl \
+    target=SSL_CTX_use_psk_identity_hint.3openssl
+file path=usr/share/man/man3openssl/SSL_want.3openssl
+link path=usr/share/man/man3openssl/SSL_want_nothing.3openssl \
+    target=SSL_want.3openssl
+link path=usr/share/man/man3openssl/SSL_want_read.3openssl \
+    target=SSL_want.3openssl
+link path=usr/share/man/man3openssl/SSL_want_write.3openssl \
+    target=SSL_want.3openssl
+link path=usr/share/man/man3openssl/SSL_want_x509_lookup.3openssl \
+    target=SSL_want.3openssl
+file path=usr/share/man/man3openssl/SSL_write.3openssl
+link path=usr/share/man/man3openssl/SSLeay.3openssl \
+    target=OPENSSL_VERSION_NUMBER.3openssl
+link path=usr/share/man/man3openssl/SSLeay_add_ssl_algorithms.3openssl \
+    target=SSL_library_init.3openssl
+link path=usr/share/man/man3openssl/SSLeay_version.3openssl \
+    target=OPENSSL_VERSION_NUMBER.3openssl
+link path=usr/share/man/man3openssl/UI_OpenSSL.3openssl target=ui.3openssl
+link path=usr/share/man/man3openssl/UI_add_error_string.3openssl \
+    target=ui.3openssl
+link path=usr/share/man/man3openssl/UI_add_info_string.3openssl \
+    target=ui.3openssl
+link path=usr/share/man/man3openssl/UI_add_input_boolean.3openssl \
+    target=ui.3openssl
+link path=usr/share/man/man3openssl/UI_add_input_string.3openssl \
+    target=ui.3openssl
+link path=usr/share/man/man3openssl/UI_add_user_data.3openssl target=ui.3openssl
+link path=usr/share/man/man3openssl/UI_add_verify_string.3openssl \
+    target=ui.3openssl
+link path=usr/share/man/man3openssl/UI_construct_prompt.3openssl \
+    target=ui.3openssl
+link path=usr/share/man/man3openssl/UI_ctrl.3openssl target=ui.3openssl
+link path=usr/share/man/man3openssl/UI_dup_error_string.3openssl \
+    target=ui.3openssl
+link path=usr/share/man/man3openssl/UI_dup_info_string.3openssl \
+    target=ui.3openssl
+link path=usr/share/man/man3openssl/UI_dup_input_boolean.3openssl \
+    target=ui.3openssl
+link path=usr/share/man/man3openssl/UI_dup_input_string.3openssl \
+    target=ui.3openssl
+link path=usr/share/man/man3openssl/UI_dup_verify_string.3openssl \
+    target=ui.3openssl
+link path=usr/share/man/man3openssl/UI_free.3openssl target=ui.3openssl
+link path=usr/share/man/man3openssl/UI_get0_result.3openssl target=ui.3openssl
+link path=usr/share/man/man3openssl/UI_get0_user_data.3openssl \
+    target=ui.3openssl
+link path=usr/share/man/man3openssl/UI_get_default_method.3openssl \
+    target=ui.3openssl
+link path=usr/share/man/man3openssl/UI_get_method.3openssl target=ui.3openssl
+link path=usr/share/man/man3openssl/UI_new.3openssl target=ui.3openssl
+link path=usr/share/man/man3openssl/UI_new_method.3openssl target=ui.3openssl
+link path=usr/share/man/man3openssl/UI_process.3openssl target=ui.3openssl
+link path=usr/share/man/man3openssl/UI_set_default_method.3openssl \
+    target=ui.3openssl
+link path=usr/share/man/man3openssl/UI_set_method.3openssl target=ui.3openssl
+link path=usr/share/man/man3openssl/X509_NAME_ENTRY_create_by_NID.3openssl \
+    target=X509_NAME_ENTRY_get_object.3openssl
+link path=usr/share/man/man3openssl/X509_NAME_ENTRY_create_by_OBJ.3openssl \
+    target=X509_NAME_ENTRY_get_object.3openssl
+link path=usr/share/man/man3openssl/X509_NAME_ENTRY_create_by_txt.3openssl \
+    target=X509_NAME_ENTRY_get_object.3openssl
+link path=usr/share/man/man3openssl/X509_NAME_ENTRY_get_data.3openssl \
+    target=X509_NAME_ENTRY_get_object.3openssl
+file path=usr/share/man/man3openssl/X509_NAME_ENTRY_get_object.3openssl
+link path=usr/share/man/man3openssl/X509_NAME_ENTRY_set_data.3openssl \
+    target=X509_NAME_ENTRY_get_object.3openssl
+link path=usr/share/man/man3openssl/X509_NAME_ENTRY_set_object.3openssl \
+    target=X509_NAME_ENTRY_get_object.3openssl
+link path=usr/share/man/man3openssl/X509_NAME_add_entry.3openssl \
+    target=X509_NAME_add_entry_by_txt.3openssl
+link path=usr/share/man/man3openssl/X509_NAME_add_entry_by_NID.3openssl \
+    target=X509_NAME_add_entry_by_txt.3openssl
+link path=usr/share/man/man3openssl/X509_NAME_add_entry_by_OBJ.3openssl \
+    target=X509_NAME_add_entry_by_txt.3openssl
+file path=usr/share/man/man3openssl/X509_NAME_add_entry_by_txt.3openssl
+link path=usr/share/man/man3openssl/X509_NAME_delete_entry.3openssl \
+    target=X509_NAME_add_entry_by_txt.3openssl
+link path=usr/share/man/man3openssl/X509_NAME_entry_count.3openssl \
+    target=X509_NAME_get_index_by_NID.3openssl
+link path=usr/share/man/man3openssl/X509_NAME_get_entry.3openssl \
+    target=X509_NAME_get_index_by_NID.3openssl
+file path=usr/share/man/man3openssl/X509_NAME_get_index_by_NID.3openssl
+link path=usr/share/man/man3openssl/X509_NAME_get_index_by_OBJ.3openssl \
+    target=X509_NAME_get_index_by_NID.3openssl
+link path=usr/share/man/man3openssl/X509_NAME_get_text_by_NID.3openssl \
+    target=X509_NAME_get_index_by_NID.3openssl
+link path=usr/share/man/man3openssl/X509_NAME_get_text_by_OBJ.3openssl \
+    target=X509_NAME_get_index_by_NID.3openssl
+link path=usr/share/man/man3openssl/X509_NAME_oneline.3openssl \
+    target=X509_NAME_print_ex.3openssl
+link path=usr/share/man/man3openssl/X509_NAME_print.3openssl \
+    target=X509_NAME_print_ex.3openssl
+file path=usr/share/man/man3openssl/X509_NAME_print_ex.3openssl
+link path=usr/share/man/man3openssl/X509_NAME_print_ex_fp.3openssl \
+    target=X509_NAME_print_ex.3openssl
+link path=usr/share/man/man3openssl/X509_STORE_CTX_cleanup.3openssl \
+    target=X509_STORE_CTX_new.3openssl
+link path=usr/share/man/man3openssl/X509_STORE_CTX_free.3openssl \
+    target=X509_STORE_CTX_new.3openssl
+link path=usr/share/man/man3openssl/X509_STORE_CTX_get0_param.3openssl \
+    target=X509_STORE_CTX_new.3openssl
+link path=usr/share/man/man3openssl/X509_STORE_CTX_get1_chain.3openssl \
+    target=X509_STORE_CTX_get_error.3openssl
+link path=usr/share/man/man3openssl/X509_STORE_CTX_get_current_cert.3openssl \
+    target=X509_STORE_CTX_get_error.3openssl
+file path=usr/share/man/man3openssl/X509_STORE_CTX_get_error.3openssl
+link path=usr/share/man/man3openssl/X509_STORE_CTX_get_error_depth.3openssl \
+    target=X509_STORE_CTX_get_error.3openssl
+link path=usr/share/man/man3openssl/X509_STORE_CTX_get_ex_data.3openssl \
+    target=X509_STORE_CTX_get_ex_new_index.3openssl
+file path=usr/share/man/man3openssl/X509_STORE_CTX_get_ex_new_index.3openssl
+link path=usr/share/man/man3openssl/X509_STORE_CTX_init.3openssl \
+    target=X509_STORE_CTX_new.3openssl
+file path=usr/share/man/man3openssl/X509_STORE_CTX_new.3openssl
+link path=usr/share/man/man3openssl/X509_STORE_CTX_set0_crls.3openssl \
+    target=X509_STORE_CTX_new.3openssl
+link path=usr/share/man/man3openssl/X509_STORE_CTX_set0_param.3openssl \
+    target=X509_STORE_CTX_new.3openssl
+link path=usr/share/man/man3openssl/X509_STORE_CTX_set_cert.3openssl \
+    target=X509_STORE_CTX_new.3openssl
+link path=usr/share/man/man3openssl/X509_STORE_CTX_set_chain.3openssl \
+    target=X509_STORE_CTX_new.3openssl
+link path=usr/share/man/man3openssl/X509_STORE_CTX_set_default.3openssl \
+    target=X509_STORE_CTX_new.3openssl
+link path=usr/share/man/man3openssl/X509_STORE_CTX_set_error.3openssl \
+    target=X509_STORE_CTX_get_error.3openssl
+link path=usr/share/man/man3openssl/X509_STORE_CTX_set_ex_data.3openssl \
+    target=X509_STORE_CTX_get_ex_new_index.3openssl
+file path=usr/share/man/man3openssl/X509_STORE_CTX_set_verify_cb.3openssl
+link path=usr/share/man/man3openssl/X509_STORE_CTX_trusted_stack.3openssl \
+    target=X509_STORE_CTX_new.3openssl
+link path=usr/share/man/man3openssl/X509_STORE_set_verify_cb.3openssl \
+    target=X509_STORE_set_verify_cb_func.3openssl
+file path=usr/share/man/man3openssl/X509_STORE_set_verify_cb_func.3openssl
+link path=usr/share/man/man3openssl/X509_VERIFY_PARAM_add0_policy.3openssl \
+    target=X509_VERIFY_PARAM_set_flags.3openssl
+link path=usr/share/man/man3openssl/X509_VERIFY_PARAM_clear_flags.3openssl \
+    target=X509_VERIFY_PARAM_set_flags.3openssl
+link path=usr/share/man/man3openssl/X509_VERIFY_PARAM_get_depth.3openssl \
+    target=X509_VERIFY_PARAM_set_flags.3openssl
+link path=usr/share/man/man3openssl/X509_VERIFY_PARAM_get_flags.3openssl \
+    target=X509_VERIFY_PARAM_set_flags.3openssl
+link path=usr/share/man/man3openssl/X509_VERIFY_PARAM_set1_policies.3openssl \
+    target=X509_VERIFY_PARAM_set_flags.3openssl
+link path=usr/share/man/man3openssl/X509_VERIFY_PARAM_set_depth.3openssl \
+    target=X509_VERIFY_PARAM_set_flags.3openssl
+file path=usr/share/man/man3openssl/X509_VERIFY_PARAM_set_flags.3openssl
+link path=usr/share/man/man3openssl/X509_VERIFY_PARAM_set_purpose.3openssl \
+    target=X509_VERIFY_PARAM_set_flags.3openssl
+link path=usr/share/man/man3openssl/X509_VERIFY_PARAM_set_time.3openssl \
+    target=X509_VERIFY_PARAM_set_flags.3openssl
+link path=usr/share/man/man3openssl/X509_VERIFY_PARAM_set_trust.3openssl \
+    target=X509_VERIFY_PARAM_set_flags.3openssl
+link path=usr/share/man/man3openssl/X509_free.3openssl target=X509_new.3openssl
+file path=usr/share/man/man3openssl/X509_new.3openssl
+file path=usr/share/man/man3openssl/X509_verify_cert.3openssl
+link path=usr/share/man/man3openssl/X509_verify_cert_error_string.3openssl \
+    target=X509_STORE_CTX_get_error.3openssl
+file path=usr/share/man/man3openssl/bio.3openssl
+file path=usr/share/man/man3openssl/blowfish.3openssl
+file path=usr/share/man/man3openssl/bn.3openssl
+link path=usr/share/man/man3openssl/bn_add_words.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_check_top.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_cmp_words.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_div_words.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_dump.3openssl target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_expand.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_expand2.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_fix_top.3openssl \
+    target=bn_internal.3openssl
+file path=usr/share/man/man3openssl/bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_mul_add_words.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_mul_comba4.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_mul_comba8.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_mul_high.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_mul_low_normal.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_mul_low_recursive.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_mul_normal.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_mul_part_recursive.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_mul_recursive.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_mul_words.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_print.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_set_high.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_set_low.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_set_max.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_sqr_comba4.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_sqr_comba8.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_sqr_normal.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_sqr_recursive.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_sqr_words.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_sub_words.3openssl \
+    target=bn_internal.3openssl
+link path=usr/share/man/man3openssl/bn_wexpand.3openssl \
+    target=bn_internal.3openssl
+file path=usr/share/man/man3openssl/buffer.3openssl
+file path=usr/share/man/man3openssl/crypto.3openssl
+link path=usr/share/man/man3openssl/d2i_509_CRL_fp.3openssl \
+    target=d2i_X509_CRL.3openssl
+file path=usr/share/man/man3openssl/d2i_ASN1_OBJECT.3openssl
+file path=usr/share/man/man3openssl/d2i_DHparams.3openssl
+link path=usr/share/man/man3openssl/d2i_DSAPrivateKey.3openssl \
+    target=d2i_DSAPublicKey.3openssl
+file path=usr/share/man/man3openssl/d2i_DSAPublicKey.3openssl
+link path=usr/share/man/man3openssl/d2i_DSA_PUBKEY.3openssl \
+    target=d2i_DSAPublicKey.3openssl
+link path=usr/share/man/man3openssl/d2i_DSA_SIG.3openssl \
+    target=d2i_DSAPublicKey.3openssl
+link path=usr/share/man/man3openssl/d2i_Netscape_RSA.3openssl \
+    target=d2i_RSAPublicKey.3openssl
+file path=usr/share/man/man3openssl/d2i_PKCS8PrivateKey.3openssl
+link path=usr/share/man/man3openssl/d2i_PKCS8PrivateKey_bio.3openssl \
+    target=d2i_PKCS8PrivateKey.3openssl
+link path=usr/share/man/man3openssl/d2i_PKCS8PrivateKey_fp.3openssl \
+    target=d2i_PKCS8PrivateKey.3openssl
+link path=usr/share/man/man3openssl/d2i_RSAPrivateKey.3openssl \
+    target=d2i_RSAPublicKey.3openssl
+file path=usr/share/man/man3openssl/d2i_RSAPublicKey.3openssl
+link path=usr/share/man/man3openssl/d2i_RSA_PUBKEY.3openssl \
+    target=d2i_RSAPublicKey.3openssl
+file path=usr/share/man/man3openssl/d2i_SSL_SESSION.3openssl
+file path=usr/share/man/man3openssl/d2i_X509.3openssl
+file path=usr/share/man/man3openssl/d2i_X509_ALGOR.3openssl
+file path=usr/share/man/man3openssl/d2i_X509_CRL.3openssl
+link path=usr/share/man/man3openssl/d2i_X509_CRL_bio.3openssl \
+    target=d2i_X509_CRL.3openssl
+file path=usr/share/man/man3openssl/d2i_X509_NAME.3openssl
+file path=usr/share/man/man3openssl/d2i_X509_REQ.3openssl
+link path=usr/share/man/man3openssl/d2i_X509_REQ_bio.3openssl \
+    target=d2i_X509_REQ.3openssl
+link path=usr/share/man/man3openssl/d2i_X509_REQ_fp.3openssl \
+    target=d2i_X509_REQ.3openssl
+file path=usr/share/man/man3openssl/d2i_X509_SIG.3openssl
+link path=usr/share/man/man3openssl/d2i_X509_bio.3openssl \
+    target=d2i_X509.3openssl
+link path=usr/share/man/man3openssl/d2i_X509_fp.3openssl \
+    target=d2i_X509.3openssl
+file path=usr/share/man/man3openssl/des.3openssl
+link path=usr/share/man/man3openssl/des_read_2passwords.3openssl \
+    target=ui_compat.3openssl
+link path=usr/share/man/man3openssl/des_read_password.3openssl \
+    target=ui_compat.3openssl
+link path=usr/share/man/man3openssl/des_read_pw.3openssl \
+    target=ui_compat.3openssl
+link path=usr/share/man/man3openssl/des_read_pw_string.3openssl \
+    target=ui_compat.3openssl
+file path=usr/share/man/man3openssl/dh.3openssl
+file path=usr/share/man/man3openssl/dsa.3openssl
+file path=usr/share/man/man3openssl/ecdsa.3openssl
+file path=usr/share/man/man3openssl/engine.3openssl
+file path=usr/share/man/man3openssl/err.3openssl
+file path=usr/share/man/man3openssl/evp.3openssl
+file path=usr/share/man/man3openssl/hmac.3openssl
+link path=usr/share/man/man3openssl/i2d_ASN1_OBJECT.3openssl \
+    target=d2i_ASN1_OBJECT.3openssl
+file path=usr/share/man/man3openssl/i2d_CMS_bio_stream.3openssl
+link path=usr/share/man/man3openssl/i2d_DHparams.3openssl \
+    target=d2i_DHparams.3openssl
+link path=usr/share/man/man3openssl/i2d_DSAPrivateKey.3openssl \
+    target=d2i_DSAPublicKey.3openssl
+link path=usr/share/man/man3openssl/i2d_DSAPublicKey.3openssl \
+    target=d2i_DSAPublicKey.3openssl
+link path=usr/share/man/man3openssl/i2d_DSA_PUBKEY.3openssl \
+    target=d2i_DSAPublicKey.3openssl
+link path=usr/share/man/man3openssl/i2d_DSA_SIG.3openssl \
+    target=d2i_DSAPublicKey.3openssl
+link path=usr/share/man/man3openssl/i2d_Netscape_RSA.3openssl \
+    target=d2i_RSAPublicKey.3openssl
+file path=usr/share/man/man3openssl/i2d_PKCS7_bio_stream.3openssl
+link path=usr/share/man/man3openssl/i2d_PKCS8PrivateKey_bio.3openssl \
+    target=d2i_PKCS8PrivateKey.3openssl
+link path=usr/share/man/man3openssl/i2d_PKCS8PrivateKey_fp.3openssl \
+    target=d2i_PKCS8PrivateKey.3openssl
+link path=usr/share/man/man3openssl/i2d_PKCS8PrivateKey_nid_bio.3openssl \
+    target=d2i_PKCS8PrivateKey.3openssl
+link path=usr/share/man/man3openssl/i2d_PKCS8PrivateKey_nid_fp.3openssl \
+    target=d2i_PKCS8PrivateKey.3openssl
+link path=usr/share/man/man3openssl/i2d_RSAPrivateKey.3openssl \
+    target=d2i_RSAPublicKey.3openssl
+link path=usr/share/man/man3openssl/i2d_RSAPublicKey.3openssl \
+    target=d2i_RSAPublicKey.3openssl
+link path=usr/share/man/man3openssl/i2d_RSA_PUBKEY.3openssl \
+    target=d2i_RSAPublicKey.3openssl
+link path=usr/share/man/man3openssl/i2d_SSL_SESSION.3openssl \
+    target=d2i_SSL_SESSION.3openssl
+link path=usr/share/man/man3openssl/i2d_X509.3openssl target=d2i_X509.3openssl
+link path=usr/share/man/man3openssl/i2d_X509_ALGOR.3openssl \
+    target=d2i_X509_ALGOR.3openssl
+link path=usr/share/man/man3openssl/i2d_X509_CRL.3openssl \
+    target=d2i_X509_CRL.3openssl
+link path=usr/share/man/man3openssl/i2d_X509_CRL_bio.3openssl \
+    target=d2i_X509_CRL.3openssl
+link path=usr/share/man/man3openssl/i2d_X509_CRL_fp.3openssl \
+    target=d2i_X509_CRL.3openssl
+link path=usr/share/man/man3openssl/i2d_X509_NAME.3openssl \
+    target=d2i_X509_NAME.3openssl
+link path=usr/share/man/man3openssl/i2d_X509_REQ.3openssl \
+    target=d2i_X509_REQ.3openssl
+link path=usr/share/man/man3openssl/i2d_X509_REQ_bio.3openssl \
+    target=d2i_X509_REQ.3openssl
+link path=usr/share/man/man3openssl/i2d_X509_REQ_fp.3openssl \
+    target=d2i_X509_REQ.3openssl
+link path=usr/share/man/man3openssl/i2d_X509_SIG.3openssl \
+    target=d2i_X509_SIG.3openssl
+link path=usr/share/man/man3openssl/i2d_X509_bio.3openssl \
+    target=d2i_X509.3openssl
+link path=usr/share/man/man3openssl/i2d_X509_fp.3openssl \
+    target=d2i_X509.3openssl
+link path=usr/share/man/man3openssl/lh_delete.3openssl target=lhash.3openssl
+link path=usr/share/man/man3openssl/lh_doall.3openssl target=lhash.3openssl
+link path=usr/share/man/man3openssl/lh_doall_arg.3openssl target=lhash.3openssl
+link path=usr/share/man/man3openssl/lh_error.3openssl target=lhash.3openssl
+link path=usr/share/man/man3openssl/lh_free.3openssl target=lhash.3openssl
+link path=usr/share/man/man3openssl/lh_insert.3openssl target=lhash.3openssl
+link path=usr/share/man/man3openssl/lh_new.3openssl target=lhash.3openssl
+link path=usr/share/man/man3openssl/lh_node_stats.3openssl \
+    target=lh_stats.3openssl
+link path=usr/share/man/man3openssl/lh_node_stats_bio.3openssl \
+    target=lh_stats.3openssl
+link path=usr/share/man/man3openssl/lh_node_usage_stats.3openssl \
+    target=lh_stats.3openssl
+link path=usr/share/man/man3openssl/lh_node_usage_stats_bio.3openssl \
+    target=lh_stats.3openssl
+link path=usr/share/man/man3openssl/lh_retrieve.3openssl target=lhash.3openssl
+file path=usr/share/man/man3openssl/lh_stats.3openssl
+link path=usr/share/man/man3openssl/lh_stats_bio.3openssl \
+    target=lh_stats.3openssl
+file path=usr/share/man/man3openssl/lhash.3openssl
+file path=usr/share/man/man3openssl/md5.3openssl
+file path=usr/share/man/man3openssl/mdc2.3openssl
+file path=usr/share/man/man3openssl/pem.3openssl
+file path=usr/share/man/man3openssl/rand.3openssl
+file path=usr/share/man/man3openssl/rc4.3openssl
+file path=usr/share/man/man3openssl/ripemd.3openssl
+file path=usr/share/man/man3openssl/rsa.3openssl
+file path=usr/share/man/man3openssl/sha.3openssl
+file path=usr/share/man/man3openssl/ssl.3openssl
+file path=usr/share/man/man3openssl/threads.3openssl
+file path=usr/share/man/man3openssl/ui.3openssl
+file path=usr/share/man/man3openssl/ui_compat.3openssl
+file path=usr/share/man/man3openssl/x509.3openssl
+file path=usr/share/man/man5openssl/config.5openssl
+file path=usr/share/man/man5openssl/x509v3_config.5openssl
+file path=usr/share/man/man7openssl/des_modes.7openssl
+legacy pkg=SUNWopensslr desc="OpenSSL Libraries (Root)" \
+    name="OpenSSL Libraries (Root)"
+license openssl-default.license license="OpenSSL, SSLeay"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/openssl-default/patches-post-config/opensslconf.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,54 @@
+--- /tmp/opensslconf.h	Fri Feb 11 15:36:12 2011
++++ openssl-1.0.0d/crypto/opensslconf.h	Fri Feb 11 16:58:36 2011
+@@ -181,7 +181,11 @@
+ 
+ #if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
+ #if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
++#if defined(__sparcv9) || defined(__x86_64)
++#define ENGINESDIR "/lib/openssl/engines/64"
++#else
+ #define ENGINESDIR "/lib/openssl/engines"
++#endif
+ #define OPENSSLDIR "/etc/openssl"
+ #endif
+ #endif
+@@ -228,21 +232,39 @@
+ /* 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
++#if defined(__sparcv9) || defined(__x86_64)
++#define DES_LONG unsigned int
++#else
+ #define DES_LONG unsigned long
+ #endif
+ #endif
++#endif
+ 
+ #if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
+ #define CONFIG_HEADER_BN_H
++/*
++ * OpenSSL revision 1.521 from 2005-12-15 in OpenSSL_1_0_0-stable branch changed
++ * 64 bit sparcv9 configuration from SIXTY_FOUR_BIT_LONG to BN_LLONG.
++ */
++#if defined(__x86_64)
++#undef BN_LLONG
++#else
+ #define BN_LLONG
++#endif
+ 
+ /* Should we define BN_DIV2W here? */
+ 
+ /* Only one for the following should be defined */
++#if defined(__x86_64)
++#define SIXTY_FOUR_BIT_LONG
++#undef THIRTY_TWO_BIT
++#else
+ #undef SIXTY_FOUR_BIT_LONG
+ #undef SIXTY_FOUR_BIT
+ #define THIRTY_TWO_BIT
+ #endif
++#undef SIXTY_FOUR_BIT
++#endif
+ 
+ #if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
+ #define CONFIG_HEADER_RC4_LOCL_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/openssl-default/patches/101-manpage_openssl.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,16 @@
+diff -ruN openssl-0.9.8a/util/extract-section.pl openssl-0.9.8a/util/extract-section.pl
+--- openssl-0.9.8a/util/extract-section.pl	2004-11-25 18:47:31.000000000 +0100
++++ openssl-0.9.8a/util/extract-section.pl	2009-04-08 12:05:03.128230348 +0200
+@@ -3,10 +3,10 @@
+ while(<STDIN>) {
+ 	if (/=for\s+comment\s+openssl_manual_section:(\S+)/)
+ 		{
+-		print "$1\n";
++		print "${1}openssl\n";
+ 		exit 0;
+ 		}
+ }
+ 
+-print "$ARGV[0]\n";
++print "${ARGV[0]}openssl\n";
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/openssl-default/patches/102-wanboot.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,950 @@
+#
+# This patch file makes the changes neccessary to build wanboot-openssl.o
+# binary. This is Solaris-specific: not suitable for upstream.
+#
+--- openssl-1.0.0g/Makefile.org    2010-01-27 08:06:58.000000000 -0800
++++ openssl-1.0.0g-1/Makefile.org    2012-03-26 03:04:08.440194448 -0700
+@@ -139,7 +139,13 @@
+
+ BASEADDR=
+
++# For wanboot, we only need crypto and ssl.
++# 'apps' are not patched to work in stand-alone environment anyway.
++ifeq ($(PLATFORM), solaris64-sparcv9-cc-sunw-wanboot)
++DIRS=   crypto ssl
++else
+ DIRS=   crypto ssl engines apps test tools
++endif
+ ENGDIRS= ccgost
+ SHLIBDIRS= crypto ssl
+
+--- openssl-1.0.0g/Makefile    2012-01-18 05:42:28.000000000 -0800
++++ openssl-1.0.0g-1/Makefile    2012-03-26 03:03:59.170540344 -0700
+@@ -138,7 +138,13 @@
+
+ BASEADDR=0xFB00000
+
++# For wanboot, we only need crypto and ssl.
++# 'apps' are not patched to work in stand-alone environment anyway.
++ifeq ($(PLATFORM), solaris64-sparcv9-cc-sunw-wanboot)
++DIRS=   crypto ssl
++else
+ DIRS=   crypto ssl engines apps test tools
++endif
+ ENGDIRS= ccgost
+ SHLIBDIRS= crypto ssl
+
+--- openssl-1.0.0e/crypto/cryptlib.c    2011-06-22 08:39:00.000000000 -0700
++++ openssl-1.0.0e/crypto/cryptlib.c    2011-12-12 06:17:45.422476900 -0800
+@@ -421,11 +421,13 @@
+ static void solaris_locking_callback(int mode, int type, const char *file,
+     int line)
+ {
++#ifndef    _BOOT
+     if (mode & CRYPTO_LOCK) {
+         (void) pthread_mutex_lock(&solaris_openssl_locks[type]);
+     } else {
+         (void) pthread_mutex_unlock(&solaris_openssl_locks[type]);
+     }
++#endif
+ }
+ 
+ /*
+@@ -434,6 +436,7 @@
+ static struct CRYPTO_dynlock_value *
+ solaris_dynlock_create(const char *file, int line)
+ {
++#ifndef    _BOOT
+     int                        ret;
+     pthread_mutex_t    *dynlock;
+ 
+@@ -446,6 +449,9 @@
+     OPENSSL_assert(ret == 0);
+ 
+     return ((struct CRYPTO_dynlock_value *)dynlock);
++#else
++    return (NULL);
++#endif
+ }
+ 
+ static void
+@@ -452,6 +458,7 @@
+ solaris_dynlock_lock(int mode, struct CRYPTO_dynlock_value *dynlock,
+     const char *file, int line)
+ {
++#ifndef    _BOOT
+     int        ret;
+ 
+     if (mode & CRYPTO_LOCK) {
+@@ -461,6 +468,7 @@
+     }
+ 
+     OPENSSL_assert(ret == 0);
++#endif
+ }
+ 
+ static void
+@@ -467,23 +475,28 @@
+ solaris_dynlock_destroy(struct CRYPTO_dynlock_value *dynlock,
+     const char *file, int line)
+ {
++#ifndef    _BOOT
+     int ret;
+     ret = pthread_mutex_destroy((pthread_mutex_t *)dynlock);
+     OPENSSL_assert(ret == 0);
++#endif
+ }
+ 
+ 
+ static void solaris_fork_prep(void)
+ {
++#ifndef    _BOOT
+     int i;
+ 
+     for (i = 0; i < CRYPTO_NUM_LOCKS; i++) {
+         (void) pthread_mutex_lock(&solaris_openssl_locks[i]);
+     }
++#endif
+ }
+ 
+ static void solaris_fork_post(void)
+ {
++#ifndef	_BOOT
+     int i;
+ 
+     for (i = CRYPTO_NUM_LOCKS - 1; i >= 0; i--) {
+@@ -494,6 +507,7 @@
+     OPENSSL_assert(dynlock_lock_callback == solaris_dynlock_lock);
+     OPENSSL_assert(dynlock_destroy_callback == solaris_dynlock_destroy);
+     OPENSSL_assert(locking_callback == solaris_locking_callback);
++#endif
+ }
+ 
+ /*
+@@ -517,6 +531,12 @@
+ 	    locking_callback = solaris_locking_callback;
+     }
+ 
++    /*
++     * pthread_* can't be used in wanboot.
++     * wanboot needs not be thread-safe and mutexes and locking callback
++     * function will not be setup for wanboot.
++     */
++#ifndef    _BOOT
+     /* allocate and initialize locks needed by OpenSSL  */
+     solaris_openssl_locks =
+         OPENSSL_malloc(sizeof (pthread_mutex_t) * CRYPTO_NUM_LOCKS);
+@@ -530,6 +550,7 @@
+     }
+ 
+     (void) pthread_atfork(solaris_fork_prep, solaris_fork_post, solaris_fork_post);
++#endif
+ }
+ 
+ 
+@@ -1104,6 +1120,12 @@
+         MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONERROR);
+ }
+ #else
++/*
++ * Solaris libsa.a used for WAN boot doesn't provide for vfprintf(). Since
++ * OPENSSL_showfatal() is not used anywhere else then here we can safely use
++ * the code from 0.9.7d version.
++ */
++#ifndef    _BOOT
+ void OPENSSL_showfatal(const char *fmta, ...)
+ {
+     va_list ap;
+@@ -1112,6 +1134,7 @@
+     vfprintf(stderr, fmta, ap);
+     va_end(ap);
+ }
++#endif    /* _BOOT */
+ 
+ int OPENSSL_isservice(void)
+ {
+@@ -1121,9 +1144,15 @@
+ 
+ void OpenSSLDie(const char *file, int line, const char *assertion)
+ {
++#ifndef _BOOT
+     OPENSSL_showfatal
+         ("%s(%d): OpenSSL internal error, assertion failed: %s\n", file, line,
+          assertion);
++#else
++    fprintf(stderr,
++        "%s(%d): OpenSSL internal error, assertion failed: %s\n",
++        file,line,assertion);
++#endif
+ #if !defined(_WIN32) || defined(__CYGWIN__)
+     abort();
+ #else
+--- openssl-1.0.0e/crypto/err/err_all.c    2009-08-09 07:58:05.000000000 -0700
++++ openssl-1.0.0e_patched/crypto/err/err_all.c    2011-12-13 05:22:01.205351400 -0800
+@@ -148,7 +148,9 @@
+     ERR_load_X509V3_strings();
+     ERR_load_PKCS12_strings();
+     ERR_load_RAND_strings();
++#ifndef _BOOT
+     ERR_load_DSO_strings();
++#endif /* _BOOT */
+     ERR_load_TS_strings();
+ # ifndef OPENSSL_NO_ENGINE
+     ERR_load_ENGINE_strings();
+--- openssl-1.0.0e/crypto/evp/evp_key.c    2010-03-27 12:27:50.000000000 -0700
++++ openssl-1.0.0e_patched/crypto/evp/evp_key.c    2011-12-13 05:19:32.956908600 -0800
+@@ -83,7 +83,7 @@
+     else
+         return (prompt_string);
+ }
+-
++#ifndef    _BOOT
+ /*
+  * For historical reasons, the standard function for reading passwords is in
+  * the DES library -- if someone ever wants to disable DES, this function
+@@ -115,6 +115,7 @@
+     OPENSSL_cleanse(buff, BUFSIZ);
+     return ret;
+ }
++#endif    /* !_BOOT */
+ 
+ int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
+                    const unsigned char *salt, const unsigned char *data,
+--- openssl-1.0.0e/crypto/rand/rand_unix.c    2009-04-06 07:31:36.000000000 -0700
++++ openssl-1.0.0e_patched/crypto/rand/rand_unix.c    2011-12-19 07:28:39.988944800 -0800
+@@ -122,7 +122,11 @@
+ # include <sys/time.h>
+ # include <sys/times.h>
+ # include <sys/stat.h>
++#ifdef    _BOOT
++# include <sys/fcntl.h>
++#else
+ # include <fcntl.h>
++#endif
+ # include <unistd.h>
+ # include <time.h>
+ # if defined(OPENSSL_SYS_LINUX) /* should actually be available virtually
+@@ -259,6 +263,11 @@
+     const char **egdsocket = NULL;
+ #  endif
+ 
++#ifdef _BOOT
++/* open() is provided by standalone libsa not visible from here */
++extern int open(const char *, int);
++#endif
++
+ #  ifdef DEVRANDOM
+     memset(randomstats, 0, sizeof(randomstats));
+     /*
+@@ -307,11 +316,15 @@
+             do {
+                 int try_read = 0;
+
+-#   if defined(OPENSSL_SYS_BEOS_R5)
++#   if defined(OPENSSL_SYS_BEOS_R5) || defined(_BOOT)
+                 /*
+                  * select() is broken in BeOS R5, so we simply try to read
+                  * something and snooze if we couldn't
+                  */
++               /*
++                * select() is not available when linking stand-alone
++                * library for wanboot
++                */
+                 try_read = 1;
+ 
+ #   elif defined(OPENSSL_SYS_LINUX)
+@@ -365,6 +378,7 @@
+                 } else
+                     r = -1;
+
++#ifndef        _BOOT
+                 /*
+                  * Some Unixen will update t in select(), some won't.  For
+                  * those who won't, or if we didn't use select() in the first
+@@ -377,13 +391,17 @@
+             while ((r > 0 ||
+                     (errno == EINTR || errno == EAGAIN)) && usec != 0
+                    && n < ENTROPY_NEEDED);
++#else  /* _BOOT */
++            }
++            while (r > 0 && n < ENTROPY_NEEDED);
++#endif /* _BOOT */
+
+             close(fd);
+         }
+     }
+ #  endif                        /* defined(DEVRANDOM) */
+
+-#  ifdef DEVRANDOM_EGD
++#  if defined(DEVRANDOM_EGD) && !defined(_BOOT)
+     /*
+      * Use an EGD socket to read entropy from an EGD or PRNGD entropy
+      * collecting daemon.
+@@ -407,6 +424,7 @@
+     }
+ #  endif
+ 
++#ifndef    _BOOT
+     /* put in some default random data, we need more than just this */
+     l = curr_pid;
+     RAND_add(&l, sizeof(l), 0.0);
+@@ -415,6 +433,7 @@
+ 
+     l = time(NULL);
+     RAND_add(&l, sizeof(l), 0.0);
++#endif /* !_BOOT */    
+ 
+ #  if defined(OPENSSL_SYS_BEOS)
+     {
+--- openssl-1.0.0e/crypto/rand/randfile.c    2011-03-19 02:44:37.000000000 -0700
++++ openssl-1.0.0e_patched/crypto/rand/randfile.c    2011-12-13 05:26:51.884824200 -0800
+@@ -191,6 +193,7 @@
+     return (ret);
+ }
+ 
++#ifndef    _BOOT
+ int RAND_write_file(const char *file)
+ {
+     unsigned char buf[BUFSIZE];
+@@ -335,3 +338,5 @@
+ #endif
+     return (buf);
+ }
++
++#endif /* _BOOT */
+--- openssl-1.0.0e/crypto/x509v3/v3_utl.c    2009-07-27 14:08:53.000000000 -0700
++++ openssl-1.0.0e_patched/crypto/x509v3/v3_utl.c    2011-12-13 05:10:08.844191400 -0800
+@@ -1146,9 +1146,50 @@
+     }
+ }
+ 
++#if    defined(_BOOT)
++/* This function was copied from bio/b_sock.c */
++static int get_ip(const char *str, unsigned char ip[4])
++{
++    unsigned int tmp[4];
++    int num = 0, c, ok = 0;
++
++    tmp[0]=tmp[1]=tmp[2]=tmp[3]=0;
++
++    for (;;) {
++        c = *(str++);
++        if ((c >= '0') && (c <= '9')) {
++            ok = 1;
++            tmp[num] = tmp[num]*10+c-'0';
++            if (tmp[num] > 255)
++                return(0);
++        } else if (c == '.') {
++            if (!ok)
++                return (-1);
++            if (num == 3)
++                return (0);
++            num++;
++            ok = 0;
++        } else if (c == '\0' && (num == 3) && ok)
++            break;
++        else
++            return(0);
++        }
++    ip[0]=tmp[0];
++    ip[1]=tmp[1];
++    ip[2]=tmp[2];
++    ip[3]=tmp[3];
++    return(1);
++}
++#endif /* _BOOT */
++
+ static int ipv4_from_asc(unsigned char *v4, const char *in)
+ {
+     int a0, a1, a2, a3;
++
++#if    defined(_BOOT)
++    if (get_ip(in, v4) != 1)
++        return 0;
++#else    /* _BOOT */
+     if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4)
+         return 0;
+     if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255)
+@@ -1158,6 +1199,7 @@
+     v4[1] = a1;
+     v4[2] = a2;
+     v4[3] = a3;
++#endif    /* _BOOT */
+     return 1;
+ }
+
+--- openssl-1.0.0e/e_os.h    2011-12-19 04:17:51.631087400 -0800
++++ openssl-1.0.0e_patched/e_os.h    2011-12-19 04:15:15.776668900 -0800
+@@ -213,10 +213,19 @@
+ #  define get_last_socket_error() errno
+ #  define clear_socket_error()    errno=0
+ #  define ioctlsocket(a,b,c)      ioctl(a,b,c)
++#ifdef    _BOOT
++#include <netinet/in.h>
++extern int socket_read(int, void *, size_t, int);
++extern int socket_close(int);
++#  define closesocket(s)          socket_close(s)
++#  define readsocket(s,b,n)       socket_read((s),(b),(n), 200)
++#  define writesocket(s,b,n)      send((s),(b),(n), 0)
++#else  /* !_BOOT */
+ #  define closesocket(s)          close(s)
+ #  define readsocket(s,b,n)       read((s),(b),(n))
+ #  define writesocket(s,b,n)      write((s),(b),(n))
+ # endif
++#endif
+ 
+ # ifdef WIN16                   /* never the case */
+ #  define MS_CALLBACK   _far _loadds
+--- openssl-1.0.0e/crypto/sparcv9cap.c	2010-09-05 12:48:01.000000000 -0700
++++ openssl-1.0.0e_patched/crypto/sparcv9cap.c	2011-12-23 05:24:02.011607700 -0800
+@@ -12,7 +12,11 @@
+ #if defined(__GNUC__) && defined(__linux)
+ __attribute__ ((visibility("hidden")))
+ #endif
++#ifndef        _BOOT
+ unsigned int OPENSSL_sparcv9cap_P[2] = { SPARCV9_TICK_PRIVILEGED, 0 };
++#else
++unsigned int OPENSSL_sparcv9cap_P[2] = { SPARCV9_VIS1, 0 };
++#endif
+ 
+ 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)
+@@ -74,6 +78,7 @@
+ size_t _sparcv9_vis1_instrument_bus(unsigned int *, size_t);
+ size_t _sparcv9_vis1_instrument_bus2(unsigned int *, size_t, size_t);
+ 
++#ifndef _BOOT
+ unsigned long OPENSSL_rdtsc(void)
+ {
+     if (OPENSSL_sparcv9cap_P[0] & SPARCV9_TICK_PRIVILEGED)
+@@ -103,9 +108,20 @@
+     else
+         return 0;
+ }
++#endif
+ 
+-#if 0 && defined(__sun) && defined(__SVR4)
++#if defined(_BOOT)
+ /*
++ * Hardcoding sparc capabilities for wanboot.
++ * Older CPUs are EOLed anyway.
++ */
++void OPENSSL_cpuid_setup(void)
++{
++    OPENSSL_sparcv9cap_P[0] = SPARCV9_VIS1;
++}
++
++#elif 0 && defined(__sun) && defined(__SVR4)
++/*
+  * This code path is disabled, because of incompatibility of libdevinfo.so.1
+  * and libmalloc.so.1 (see below for details)
+  */
+--- openssl-1.0.0e/crypto/sparccpuid.S	2010-09-05 12:48:01.000000000 -0700
++++ openssl-1.0.0e_patched/crypto/sparccpuid.S	2012-02-13 07:42:58.259478325 -0800
+@@ -400,6 +400,7 @@
+ .type	OPENSSL_cleanse,#function
+ .size	OPENSSL_cleanse,.-OPENSSL_cleanse
+
++#ifndef _BOOT
+ .global	_sparcv9_vis1_instrument_bus
+ .weak	_sparcv9_vis1_instrument_bus
+ .align	8
+@@ -501,3 +502,7 @@
+ 	nop
+ 	call	OPENSSL_cpuid_setup
+ 	nop
++#else
++	nop
++	nop
++#endif
+--- openssl-1.0.1c/crypto/Makefile      Thu Aug  2 12:56:38 2012
++++ openssl-1.0.1c/crypto/Makefile.new  Thu Aug  2 12:59:43 2012
+@@ -36,9 +36,9 @@
+ LIB= $(TOP)/libcrypto.a
+ SHARED_LIB= libcrypto$(SHLIB_EXT)
+ LIBSRC=	cryptlib.c mem.c mem_clr.c mem_dbg.c cversion.c ex_data.c cpt_err.c \
+-	ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fips.c o_init.c fips_ers.c
++	ebcdic.c uid.c o_time.c o_str.c o_dir.c o_fips.c o_init.c fips_ers.c wanboot-stubs.c
+ LIBOBJ= cryptlib.o mem.o mem_dbg.o cversion.o ex_data.o cpt_err.o ebcdic.o \
+-	uid.o o_time.o o_str.o o_dir.o o_fips.o o_init.o fips_ers.o $(CPUID_OBJ)
++	uid.o o_time.o o_str.o o_dir.o o_fips.o o_init.o fips_ers.o wanboot-stubs.o $(CPUID_OBJ)
+
+ SRC= $(LIBSRC)
+
+--- openssl-1.0.1f/ssl/s3_clnt.c    Thu Jan 30 02:53:33 2014
++++ openssl-1.0.1f/ssl/s3_clnt.c.new   Thu Jan 30 02:57:51 2014
+@@ -698,6 +698,7 @@
+             if (!ssl_get_new_session(s, 0))
+                 goto err;
+         }
++#ifndef        _BOOT
+         if (s->method->version == DTLS_ANY_VERSION) {
+             /* Determine which DTLS version to use */
+             int options = s->options;
+@@ -730,6 +731,7 @@
+             }
+             s->client_version = s->version;
+         }
++#endif
+         /* else use the pre-loaded session */
+
+         p = s->s3->client_random;
+@@ -750,8 +750,12 @@
+         } else
+             i = 1;
+ 
++#ifndef    _BOOT
+         if (i && ssl_fill_hello_random(s, 0, p,
+                                        sizeof(s->s3->client_random)) <= 0)
++#else
++        if (i && RAND_pseudo_bytes(p, sizeof(s->s3->client_random)) <= 0)
++#endif
+             goto err;
+ 
+         /* Do the message type and length last */
+@@ -938,6 +942,7 @@
+     }
+ 
+     d = p = (unsigned char *)s->init_msg;
++#ifndef	_BOOT
+     if (s->method->version == DTLS_ANY_VERSION) {
+         /* Work out correct protocol version to use */
+         int hversion = (p[0] << 8) | p[1];
+@@ -960,6 +965,7 @@
+         }
+         s->session->ssl_version = s->version = s->method->version;
+     }
++#endif
+ 
+     if ((p[0] != (s->version >> 8)) || (p[1] != (s->version & 0xff))) {
+         SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_SSL_VERSION);
+--- openssl-1.0.1f/ssl/s3_lib.c       Wed Oct 15 11:18:30 2014
++++ openssl-1.0.1f/ssl/s3_lib.c.new    Wed Oct 15 11:20:07 2014
+@@ -3574,7 +3574,11 @@
+          * Apparently we're using a version-flexible SSL_METHOD (not at its
+          * highest protocol version).
+          */
++#ifndef    _BOOT
+         if (s->ctx->method->version == SSLv23_method()->version) {
++#else
++        if (s->ctx->method->version == TLS1_2_VERSION) {
++#endif
+ #if TLS_MAX_VERSION != TLS1_2_VERSION
+ # error Code needs update for SSLv23_method() support beyond TLS1_2_VERSION.
+ #endif
+--- openssl-1.0.2d/ssl/ssl_algs.c.orig	Fri Aug  7 08:54:56 2015
++++ openssl-1.0.2d/ssl/ssl_algs.c	Fri Aug  7 08:14:38 2015
+@@ -96,8 +96,10 @@
+     EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
+ # endif
+ # if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256)
++#ifndef	_BOOT
+     EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256());
+     EVP_add_cipher(EVP_aes_256_cbc_hmac_sha256());
++#endif
+ # endif
+ 
+ #endif
+--- openssl-1.0.2d/ssl/ssl_cert.c.orig	Fri Aug  7 08:57:29 2015
++++ openssl-1.0.2d/ssl/ssl_cert.c	Fri Aug  7 08:14:37 2015
+@@ -384,11 +384,13 @@
+     ret->ciphers_raw = NULL;
+ 
+ #ifndef OPENSSL_NO_TLSEXT
++#ifndef	_BOOT
+     if (!custom_exts_copy(&ret->cli_ext, &cert->cli_ext))
+         goto err;
+     if (!custom_exts_copy(&ret->srv_ext, &cert->srv_ext))
+         goto err;
+ #endif
++#endif
+ 
+     return (ret);
+ 
+@@ -409,9 +411,11 @@
+ #endif
+ 
+ #ifndef OPENSSL_NO_TLSEXT
++#ifndef	_BOOT
+     custom_exts_free(&ret->cli_ext);
+     custom_exts_free(&ret->srv_ext);
+ #endif
++#endif
+ 
+     ssl_cert_clear_certs(ret);
+ 
+@@ -502,11 +506,13 @@
+     if (c->ciphers_raw)
+         OPENSSL_free(c->ciphers_raw);
+ #ifndef OPENSSL_NO_TLSEXT
++#ifndef        _BOOT
+     custom_exts_free(&c->cli_ext);
+     custom_exts_free(&c->srv_ext);
+     if (c->alpn_proposed)
+         OPENSSL_free(c->alpn_proposed);
+ #endif
++#endif
+     OPENSSL_free(c);
+ }
+ 
+--- openssl-1.0.2d/ssl/ssl_conf.c.orig	Fri Aug  7 08:57:43 2015
++++ openssl-1.0.2d/ssl/ssl_conf.c	Fri Aug  7 08:14:38 2015
+@@ -386,6 +386,7 @@
+     return rv > 0;
+ }
+ 
++#ifndef	_BOOT
+ static int cmd_ServerInfoFile(SSL_CONF_CTX *cctx, const char *value)
+ {
+     int rv = 1;
+@@ -398,6 +399,8 @@
+     return rv > 0;
+ }
+ 
++#endif
++
+ #ifndef OPENSSL_NO_DH
+ static int cmd_DHParameters(SSL_CONF_CTX *cctx, const char *value)
+ {
+@@ -456,7 +459,9 @@
+     SSL_CONF_CMD_STRING(Options, NULL),
+     SSL_CONF_CMD(Certificate, "cert", SSL_CONF_TYPE_FILE),
+     SSL_CONF_CMD(PrivateKey, "key", SSL_CONF_TYPE_FILE),
++#ifndef	_BOOT
+     SSL_CONF_CMD(ServerInfoFile, NULL, SSL_CONF_TYPE_FILE),
++#endif
+ #ifndef OPENSSL_NO_DH
+     SSL_CONF_CMD(DHParameters, "dhparam", SSL_CONF_TYPE_FILE)
+ #endif
+--- openssl-1.0.2d/ssl/ssl_rsa.c.orig	Fri Aug  7 08:58:26 2015
++++ openssl-1.0.2d/ssl/ssl_rsa.c	Fri Aug  7 08:14:38 2015
+@@ -788,6 +788,7 @@
+     return 0;                   /* Error */
+ }
+ 
++#ifndef	_BOOT
+ static int serverinfo_srv_parse_cb(SSL *s, unsigned int ext_type,
+                                    const unsigned char *in,
+                                    size_t inlen, int *al, void *arg)
+@@ -1005,4 +1006,5 @@
+     return ret;
+ }
+ # endif                         /* OPENSSL_NO_STDIO */
++#endif	/*!_BOOT*/
+ #endif                          /* OPENSSL_NO_TLSEXT */
+--- openssl-1.0.2d/ssl/t1_lib.c.orig	Fri Aug  7 08:59:39 2015
++++ openssl-1.0.2d/ssl/t1_lib.c	Fri Aug  7 09:01:32 2015
+@@ -1559,10 +1559,12 @@
+         ret += el;
+     }
+ # endif
++#ifndef	_BOOT
+     custom_ext_init(&s->cert->cli_ext);
+     /* Add custom TLS Extensions to ClientHello */
+     if (!custom_ext_add(s, 0, &ret, limit, al))
+         return NULL;
++#endif
+ 
+     /*
+      * Add padding to workaround bugs in F5 terminators. See
+@@ -1798,8 +1800,10 @@
+         }
+     }
+ # endif
++#ifndef	_BOOT
+     if (!custom_ext_add(s, 1, &ret, limit, al))
+         return NULL;
++#endif
+ 
+     if (s->s3->alpn_selected) {
+         const unsigned char *selected = s->s3->alpn_selected;
+@@ -2428,6 +2432,7 @@
+     return 0;
+ }
+ 
++#ifndef	_BOOT
+ /*
+  * Parse any custom extensions found.  "data" is the start of the extension data
+  * and "limit" is the end of the record. TODO: add strict syntax checking.
+@@ -2464,6 +2469,7 @@
+ 
+     return 1;
+ }
++#endif /*!_BOOT*/
+ 
+ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p,
+                                  unsigned char *limit)
+@@ -2486,11 +2492,13 @@
+         return 0;
+     }
+ 
++#ifndef	_BOOT
+     custom_ext_init(&s->cert->srv_ext);
+     if (ssl_scan_clienthello_custom_tlsext(s, ptmp, limit, &al) <= 0) {
+         ssl3_send_alert(s, SSL3_AL_FATAL, al);
+         return 0;
+     }
++#endif
+ 
+     return 1;
+ }
+@@ -2762,6 +2770,7 @@
+                 return 0;
+         }
+ # endif
++#ifndef	_BOOT
+         /*
+          * If this extension type was not otherwise handled, but matches a
+          * custom_cli_ext_record, then send it to the c callback
+@@ -2768,6 +2777,7 @@
+          */
+         else if (custom_ext_parse(s, 0, type, data, size, al) <= 0)
+             return 0;
++#endif
+ 
+         data += size;
+     }
+--- openssl-1.0.2d/crypto/x509/x_all.c.orig	Fri Aug  7 09:28:54 2015
++++ openssl-1.0.2d/crypto/x509/x_all.c	Fri Aug  7 08:14:33 2015
+@@ -106,11 +106,13 @@
+                               x->sig_alg, x->signature, x->cert_info, ctx);
+ }
+ 
++#ifndef	_BOOT
+ int X509_http_nbio(OCSP_REQ_CTX *rctx, X509 **pcert)
+ {
+     return OCSP_REQ_CTX_nbio_d2i(rctx,
+                                  (ASN1_VALUE **)pcert, ASN1_ITEM_rptr(X509));
+ }
++#endif
+ 
+ int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md)
+ {
+@@ -140,6 +142,7 @@
+                               x->crl, ctx);
+ }
+ 
++#ifndef	_BOOT
+ int X509_CRL_http_nbio(OCSP_REQ_CTX *rctx, X509_CRL **pcrl)
+ {
+     return OCSP_REQ_CTX_nbio_d2i(rctx,
+@@ -146,6 +149,7 @@
+                                  (ASN1_VALUE **)pcrl,
+                                  ASN1_ITEM_rptr(X509_CRL));
+ }
++#endif
+ 
+ int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md)
+ {
+--- openssl-1.0.2d/crypto/dh/dh_ameth.c.orig	Fri Aug  7 10:19:49 2015
++++ openssl-1.0.2d/crypto/dh/dh_ameth.c	Fri Aug  7 08:14:35 2015
+@@ -557,6 +557,7 @@
+     return do_dh_print(bp, x, 4, NULL, 0);
+ }
+ 
++#ifndef	_BOOT
+ #ifndef OPENSSL_NO_CMS
+ static int dh_cms_decrypt(CMS_RecipientInfo *ri);
+ static int dh_cms_encrypt(CMS_RecipientInfo *ri);
+@@ -583,6 +584,7 @@
+     }
+ 
+ }
++#endif
+ 
+ const EVP_PKEY_ASN1_METHOD dh_asn1_meth = {
+     EVP_PKEY_DH,
+@@ -645,9 +647,14 @@
+     0,
+ 
+     int_dh_free,
++#ifndef	_BOOT
+     dh_pkey_ctrl
++#else
++    0
++#endif
+ };
+ 
++#ifndef	_BOOT
+ #ifndef OPENSSL_NO_CMS
+ 
+ static int dh_cms_set_peerkey(EVP_PKEY_CTX *pctx,
+@@ -955,3 +962,5 @@
+ }
+ 
+ #endif
++
++#endif
+--- openssl-1.0.2d/crypto/dh/dh_pmeth.c.orig	Fri Aug  7 10:16:52 2015
++++ openssl-1.0.2d/crypto/dh/dh_pmeth.c	Fri Aug  7 08:14:34 2015
+@@ -194,11 +194,13 @@
+         dctx->use_dsa = p1;
+         return 1;
+ 
++#ifndef	_BOOT
+     case EVP_PKEY_CTRL_DH_RFC5114:
+         if (p1 < 1 || p1 > 3)
+             return -2;
+         dctx->rfc5114_param = p1;
+         return 1;
++#endif
+ 
+     case EVP_PKEY_CTRL_PEER_KEY:
+         /* Default behaviour is OK */
+@@ -207,7 +209,11 @@
+     case EVP_PKEY_CTRL_DH_KDF_TYPE:
+         if (p1 == -2)
+             return dctx->kdf_type;
++#ifndef	_BOOT
+         if (p1 != EVP_PKEY_DH_KDF_NONE && p1 != EVP_PKEY_DH_KDF_X9_42)
++#else
++        if (p1 != EVP_PKEY_DH_KDF_NONE)
++#endif
+             return -2;
+         dctx->kdf_type = p1;
+         return 1;
+@@ -268,6 +274,7 @@
+         len = atoi(value);
+         return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len);
+     }
++#ifndef	_BOOT
+     if (!strcmp(type, "dh_rfc5114")) {
+         DH_PKEY_CTX *dctx = ctx->data;
+         int len;
+@@ -277,6 +284,7 @@
+         dctx->rfc5114_param = len;
+         return 1;
+     }
++#endif
+     if (!strcmp(type, "dh_paramgen_generator")) {
+         int len;
+         len = atoi(value);
+@@ -355,6 +363,7 @@
+     DH_PKEY_CTX *dctx = ctx->data;
+     BN_GENCB *pcb, cb;
+     int ret;
++#ifndef	_BOOT
+     if (dctx->rfc5114_param) {
+         switch (dctx->rfc5114_param) {
+         case 1:
+@@ -375,6 +384,7 @@
+         EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
+         return 1;
+     }
++#endif
+ 
+     if (ctx->pkey_gencb) {
+         pcb = &cb;
+@@ -448,6 +458,7 @@
+             return ret;
+         *keylen = ret;
+         return 1;
++#ifndef	_BOOT
+     } else if (dctx->kdf_type == EVP_PKEY_DH_KDF_X9_42) {
+         unsigned char *Z = NULL;
+         size_t Zlen = 0;
+@@ -478,6 +489,7 @@
+             OPENSSL_free(Z);
+         }
+         return ret;
++#endif
+     }
+     return 1;
+ }
+--- openssl-1.0.2d/crypto/evp/e_des3.c.orig	Fri Aug  7 10:22:12 2015
++++ openssl-1.0.2d/crypto/evp/e_des3.c	Fri Aug  7 10:23:16 2015
+@@ -381,6 +381,8 @@
+     return &des_ede3_ecb;
+ }
+ 
++#ifndef	_BOOT
++
+ # ifndef OPENSSL_NO_SHA
+ 
+ #  include <openssl/sha.h>
+@@ -491,4 +493,6 @@
+ }
+ 
+ # endif
++#endif
++
+ #endif
+--- openssl-1.0.2d/crypto/evp/c_allc.c.orig	Fri Aug  7 10:21:48 2015
++++ openssl-1.0.2d/crypto/evp/c_allc.c	Fri Aug  7 08:14:31 2015
+@@ -93,8 +93,10 @@
+     EVP_add_cipher(EVP_des_ecb());
+     EVP_add_cipher(EVP_des_ede());
+     EVP_add_cipher(EVP_des_ede3());
++#ifndef	_BOOT
+     EVP_add_cipher(EVP_des_ede3_wrap());
+ #endif
++#endif
+ 
+ #ifndef OPENSSL_NO_RC4
+     EVP_add_cipher(EVP_rc4());
+@@ -207,8 +209,10 @@
+     EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1());
+ # endif
+ # if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256)
++#ifndef	_BOOT
+     EVP_add_cipher(EVP_aes_128_cbc_hmac_sha256());
+     EVP_add_cipher(EVP_aes_256_cbc_hmac_sha256());
++#endif
+ # endif
+ #endif
+ 
+--- openssl-1.0.2d/crypto/cms/cms_env.c.orig	Fri Aug  7 10:25:00 2015
++++ openssl-1.0.2d/crypto/cms/cms_env.c	Fri Aug  7 10:25:37 2015
+@@ -106,6 +106,7 @@
+     int i;
+     if (ri->type == CMS_RECIPINFO_TRANS)
+         pkey = ri->d.ktri->pkey;
++#ifndef	_BOOT
+     else if (ri->type == CMS_RECIPINFO_AGREE) {
+         EVP_PKEY_CTX *pctx = ri->d.kari->pctx;
+         if (!pctx)
+@@ -114,6 +115,9 @@
+         if (!pkey)
+             return 0;
+     } else
++#else
++    else
++#endif
+         return 0;
+     if (!pkey->ameth || !pkey->ameth->pkey_ctrl)
+         return 1;
+@@ -148,8 +152,10 @@
+ {
+     if (ri->type == CMS_RECIPINFO_TRANS)
+         return ri->d.ktri->pctx;
++#ifndef	_BOOT
+     else if (ri->type == CMS_RECIPINFO_AGREE)
+         return ri->d.kari->pctx;
++#endif
+     return NULL;
+ }
+ 
+@@ -255,10 +261,12 @@
+             goto err;
+         break;
+ 
++#ifndef	_BOOT
+     case CMS_RECIPINFO_AGREE:
+         if (!cms_RecipientInfo_kari_init(ri, recip, pk, flags))
+             goto err;
+         break;
++#endif
+ 
+     default:
+         CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT,
+@@ -827,8 +835,10 @@
+     case CMS_RECIPINFO_TRANS:
+         return cms_RecipientInfo_ktri_encrypt(cms, ri);
+ 
++#ifndef	_BOOT
+     case CMS_RECIPINFO_AGREE:
+         return cms_RecipientInfo_kari_encrypt(cms, ri);
++#endif
+ 
+     case CMS_RECIPINFO_KEK:
+         return cms_RecipientInfo_kekri_encrypt(cms, ri);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/openssl-default/wanboot-openssl/wanboot-stubs.c	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,122 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* Content of this file is only needed for wanboot. */
+#ifdef	_BOOT
+
+#include <sys/types.h>
+#include <dirent.h>
+#include <errno.h>
+#include <stddef.h>
+
+/*
+ * In OpenSSL 0.9.7 the EVP_read_pw_string now calls into the new "ui"
+ * routines of 0.9.7, which is not compiled in the standalone, so it is
+ * stubbed out here to avoid having to add a bunch of #ifndef's elsewhere.
+ */
+/* ARGSUSED */
+int
+EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt, int
+    verify)
+{
+	return (-1); /* failure */
+}
+
+/*
+ * In standalone issetugid() is always false.
+ */
+int
+OPENSSL_issetugid(void)
+{
+	return (1);
+}
+
+/*
+ * Directory routines -- currently, the only consumer of these interfaces
+ * is $SRC/common/openssl/ssl/ssl_cert.c, and it has fallback code in the
+ * case of failure, so we just fail opendir() and stub out the rest.  At
+ * some point, we may need to provide a real implementation.
+ */
+/* ARGSUSED */
+DIR *
+opendir(const char *dirname)
+{
+	errno = EACCES;
+	return (NULL);
+}
+
+/* ARGSUSED */
+struct dirent *
+readdir(DIR *dirp)
+{
+	return (NULL);
+}
+
+/* ARGSUSED */
+int
+closedir(DIR *dirp)
+{
+	return (0);
+}
+
+/*
+ * Atoi is used on multiple places in libcrypto.
+ * This implementation is taken from stand-alone libsock library:
+ * usr/src/stand/lib/sock/sock_test.c
+ * Alternative solution: just extern it here, wanboot has -lsock anyway.
+ */
+#ifndef	isdigit
+#define	isdigit(c) ((c) >= '0' && (c) <= '9')
+#endif
+
+#ifndef	isspace
+#define	isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || \
+		    (c) == '\r' || (c) == '\f' || (c) == '\013')
+#endif
+int
+atoi(const char *p)
+{
+	int n;
+	int c = *p++, neg = 0;
+
+	while (isspace(c)) {
+		c = *p++;
+	}
+	if (!isdigit(c)) {
+		switch (c) {
+		case '-':
+			neg++;
+			/* FALLTHROUGH */
+		case '+':
+			c = *p++;
+		}
+	}
+	for (n = 0; isdigit(c); c = *p++) {
+		n *= 10; /* two steps to avoid unnecessary overflow */
+		n += '0' - c; /* accum neg to avoid surprises at MAX */
+	}
+	return (neg ? n : -n);
+}
+
+#endif	/* _BOOT */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/openssl-fips-140/Makefile	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,217 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+#
+
+include ../../../make-rules/shared-macros.mk
+
+PATH=$(SPRO_VROOT)/bin:/usr/bin:/usr/gnu/bin:/usr/perl5/bin
+ifeq   ($(strip $(PARFAIT_BUILD)),yes)
+PATH=$(PARFAIT_TOOLS):$(SPRO_VROOT)/bin:/usr/bin:/usr/gnu/bin:/usr/perl5/bin
+endif
+
+COMPONENT_NAME =	openssl-fips-140
+# Note: COMPONENT_VERSION is the core OpenSSL version, and IPS_COMPONENT_VERSION
+# is the FIPS module version. The COMPONENT_VERSION changes with the core
+# OpenSSL version, but the IPS_COMPONENT_VERSION is purposely only to change if
+# the FIPS module version changes.
+COMPONENT_VERSION =	1.0.2j
+IPS_COMPONENT_VERSION = 2.0.12
+COMPONENT_PROJECT_URL=	http://www.openssl.org/
+COMPONENT_SRC_NAME =	openssl
+COMPONENT_SRC =		$(COMPONENT_SRC_NAME)-$(COMPONENT_VERSION)
+COMPONENT_ARCHIVE =	$(COMPONENT_SRC).tar.gz
+COMPONENT_ARCHIVE_HASH=	\
+    sha256:e7aff292be21c259c6af26469c7a9b3ba26e9abaaffd325e3dccc9785256c431
+COMPONENT_ARCHIVE_URL =	$(COMPONENT_PROJECT_URL)source/$(COMPONENT_ARCHIVE)
+COMPONENT_BUGDB=	library/openssl
+
+TPNO=			31866
+
+# Clone the patch files to the patches-all dir.
+# COPY_COMMON_FILES is there so that rsync is called as soon as
+# the Makefile is parsed.
+PATCH_DIR=patches-all
+CLEAN_PATHS += $(PATCH_DIR)
+COPY_COMMON_FILES:= $(shell rsync -ac ../common/patches/ patches/ $(PATCH_DIR))
+
+# OpenSSL FIPS directory
+OPENSSL_FIPS_DIR = $(COMPONENT_DIR)/../openssl-fips
+
+include $(WS_MAKE_RULES)/prep.mk
+include $(WS_MAKE_RULES)/configure.mk
+include $(WS_MAKE_RULES)/ips.mk
+include $(WS_MAKE_RULES)/lint-libraries.mk
+
+# OpenSSL does not use autoconf but its own configure system.
+CONFIGURE_SCRIPT = $(SOURCE_DIR)/Configure
+
+# Used in the configure options below.
+PKCS11_LIB32 = /usr/lib/libpkcs11.so.1
+PKCS11_LIB64 = /usr/lib/64/libpkcs11.so.1
+ENGINESDIR_32 = /lib/openssl/engines
+ENGINESDIR_64 = /lib/openssl/engines/64
+
+# Built openssl/openssl-fips component is used when building FIPS-140 libraries.
+# What we do here follows the OpenSSL FIPS-140 User Guide instructions.
+FIPS_BUILD_DIR_32 = $(shell echo $(BUILD_DIR_32) | \
+    sed -e 's/openssl-fips-140/openssl-fips/g' )
+FIPS_BUILD_DIR_64 = $(shell echo $(BUILD_DIR_64) | \
+    sed -e 's/openssl-fips-140/openssl-fips/g' )
+
+# Ignore default CC_FOR_BUILD, CC, and CXX in CONFIGURE_ENV.
+CONFIGURE_ENV += CC_FOR_BUILD=
+CONFIGURE_ENV += CC=
+CONFIGURE_ENV += CXX=
+
+CONFIGURE_OPTIONS =  -DSOLARIS_OPENSSL -DNO_WINDOWS_BRAINDEATH
+CONFIGURE_OPTIONS += --openssldir=/etc/openssl
+CONFIGURE_OPTIONS += --prefix=/usr
+# We use OpenSSL install code for installing only manual pages and we do that
+# for 32-bit version only.
+CONFIGURE_OPTIONS += --install_prefix=$(PROTO_DIR)
+CONFIGURE_OPTIONS += no-ec2m
+CONFIGURE_OPTIONS += no-rc3
+CONFIGURE_OPTIONS += no-rc5
+CONFIGURE_OPTIONS += no-mdc2
+CONFIGURE_OPTIONS += no-idea
+CONFIGURE_OPTIONS += no-hw_4758_cca
+CONFIGURE_OPTIONS += no-hw_aep
+CONFIGURE_OPTIONS += no-hw_atalla
+CONFIGURE_OPTIONS += no-hw_chil
+CONFIGURE_OPTIONS += no-hw_gmp
+CONFIGURE_OPTIONS += no-hw_ncipher
+CONFIGURE_OPTIONS += no-hw_nuron
+CONFIGURE_OPTIONS += no-hw_padlock
+CONFIGURE_OPTIONS += no-hw_sureware
+CONFIGURE_OPTIONS += no-hw_ubsec
+CONFIGURE_OPTIONS += no-hw_cswift
+CONFIGURE_OPTIONS += threads
+CONFIGURE_OPTIONS += shared
+CONFIGURE_OPTIONS += fips --with-fipslibdir="$(FIPS_BUILD_DIR_$(BITS))/fips/"
+CONFIGURE_OPTIONS += --with-fipsdir="$(BUILD_DIR_$(BITS))"
+
+# MD2 is not enabled by default in OpensSSL but some software we have in
+# Userland needs it. One example is nmap.
+CONFIGURE_OPTIONS += enable-md2
+CONFIGURE_OPTIONS += no-seed
+
+# Disable SSLv2 protocol
+CONFIGURE_OPTIONS += no-ssl2
+
+# We define our own compiler and linker option sets for Solaris. See Configure
+# for more information.
+CONFIGURE_OPTIONS32_i386 =	solaris-x86-cc-sunw
+CONFIGURE_OPTIONS32_sparc =	solaris-fips-sparcv9-cc-sunw
+CONFIGURE_OPTIONS64_i386 =	solaris64-x86_64-cc-sunw
+CONFIGURE_OPTIONS64_sparc =	solaris64-fips-sparcv9-cc-sunw
+
+# Some additional options needed for our engines.
+CONFIGURE_OPTIONS += --pk11-libname=$(PKCS11_LIB$(BITS))
+CONFIGURE_OPTIONS += --enginesdir=$(ENGINESDIR_$(BITS))
+CONFIGURE_OPTIONS += $(CONFIGURE_OPTIONS$(BITS)_$(MACH))
+
+# OpenSSL has its own configure system which must be run from the fully
+# populated source code directory. However, the Userland configuration phase is
+# run from the build directory. The easiest way to workaround it is to copy all
+# the source files there.
+COMPONENT_PRE_CONFIGURE_ACTION = \
+    ( $(CLONEY) $(SOURCE_DIR) $(BUILD_DIR)/$(MACH$(BITS)); )
+
+# We deliver only one opensslconf.h file which must be suitable for both 32 and
+# 64 bits. Depending on the configuration option, OpenSSL's Configure script
+# creates opensslconf.h for either 32 or 64 bits. A patch makes the resulting
+# header file usable on both architectures. The patch was generated against the
+# opensslconf.h version from the 32 bit build.
+COMPONENT_POST_CONFIGURE_ACTION = \
+   ( [ $(BITS) -eq 32 ] && $(GPATCH) -p1 $(@D)/crypto/opensslconf.h \
+      patches-post-config/opensslconf.patch; cd $(@D); $(MAKE) depend; )
+
+# We must make sure that openssl-fips component is built before this openssl-fips-140
+# component since in order to build FIPS-140 certified libraries, the canister
+# is needed. Note that we must unset BITS that would override the same variable
+# used in openssl-fips' Makefile, and we would end up up with both canisters
+# built in 64 (or 32) bits.
+$(COMPONENT_DIR)/../openssl-fips/build/$(MACH32)/.installed \
+$(COMPONENT_DIR)/../openssl-fips/build/$(MACH64)/.installed:
+	( unset BITS; \
+	$(MAKE) -C $(COMPONENT_DIR)/../openssl-fips install; )
+
+# download, clean, and clobber should all propogate to the fips bits
+download clobber clean::
+	(cd ../openssl-fips ; $(GMAKE) $@)
+
+# We do not ship our engines as patches since it would be more difficult to
+# update the files which have been under continuous development. We rather copy
+# the files to the right directories and let OpenSSL makefiles build it.
+# We also copy some FIPS specific header files needed to build FIPS version
+# of OpenSSL from FIPS module.
+COMPONENT_PRE_BUILD_ACTION = \
+    ( $(LN) -fs $(COMPONENT_DIR)/../common/engines/pkcs11/*     $(@D)/engines; \
+      $(MKDIR) $(@D)/bin; \
+      $(LN) -fs $(OPENSSL_FIPS_DIR)/openssl-fips-ecp-$(IPS_COMPONENT_VERSION)/fips/fips.h $(@D)/include/openssl; \
+      $(LN) -fs $(OPENSSL_FIPS_DIR)/openssl-fips-ecp-$(IPS_COMPONENT_VERSION)/fips/fipssyms.h $(@D)/include/openssl; \
+      $(LN) -fs $(OPENSSL_FIPS_DIR)/openssl-fips-ecp-$(IPS_COMPONENT_VERSION)/fips/rand/fips_rand.h $(@D)/include/openssl; \
+      $(LN) -fs $(OPENSSL_FIPS_DIR)/openssl-fips-ecp-$(IPS_COMPONENT_VERSION)/fips/fipsld $(@D)/bin/; \
+      $(LN) -fs $(OPENSSL_FIPS_DIR)/build/$(MACH$(BITS))/fips/fips_standalone_sha1 $(@D)/bin/; \
+      $(LN) -fs $(COMPONENT_DIR)/build/$(MACH$(BITS))/fips_premain_dso $(@D)/bin/;)
+
+# OpenSSL does not install into <dir>/$(MACH64) for 64-bit install so no such
+# directory is created and Userland install code would fail when installing lint
+# libraries.
+COMPONENT_PRE_INSTALL_ACTION = ( $(MKDIR) $(PROTO_DIR)/usr/lib/$(MACH64); )
+
+$(SOURCE_DIR)/.prep: $(COMPONENT_DIR)/../openssl-fips/build/$(MACH32)/.installed \
+		     $(COMPONENT_DIR)/../openssl-fips/build/$(MACH64)/.installed
+
+configure:	$(CONFIGURE_32_and_64)
+
+build:			$(BUILD_32_and_64)
+
+# We follow what we do for install in openssl/openssl-1.0.0 component. Please
+# see the comment in Makefile in there for more information.
+install:	$(INSTALL_32_and_64)
+
+# We need to modify the default lint flags to include patched opensslconf.h from
+# the build directory. If we do not do that, lint will complain about md2.h
+# which is not enabled by default but it is in our opensslconf.h.
+LFLAGS_32 := -I$(BUILD_DIR_32)/include $(LINT_FLAGS)
+LFLAGS_64 := -I$(BUILD_DIR_64)/include $(LINT_FLAGS)
+
+# Set modified lint flags for our lint library targets.
+$(BUILD_DIR_32)/llib-lcrypto.ln: LINT_FLAGS=$(LFLAGS_32) -I$(PROTOUSRINCDIR)
+$(BUILD_DIR_32)/llib-lssl.ln: LINT_FLAGS=$(LFLAGS_32) -I$(PROTOUSRINCDIR)
+$(BUILD_DIR_64)/llib-lcrypto.ln: LINT_FLAGS=$(LFLAGS_64) -I$(PROTOUSRINCDIR)
+$(BUILD_DIR_64)/llib-lssl.ln: LINT_FLAGS=$(LFLAGS_64) -I$(PROTOUSRINCDIR)
+
+# There are also separate STC test suites 'openssl' and 'openssl-engine'
+# for regression testing. These internal tests are unit tests only.
+COMPONENT_TEST_TARGETS = test
+test:		$(TEST_32_and_64)
+
+system-test:    $(SYSTEM_TESTS_NOT_IMPLEMENTED)
+
+
+REQUIRED_PACKAGES += developer/build/makedepend
+REQUIRED_PACKAGES += network/rsync
+REQUIRED_PACKAGES += system/library
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/openssl-fips-140/llib-lcrypto	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,67 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* LINTLIBRARY */
+/* PROTOLIB1 */
+
+#include <openssl/asn1.h>
+#include <openssl/asn1_mac.h>
+#include <openssl/bio.h>
+#include <openssl/blowfish.h>
+#include <openssl/bn.h>
+#include <openssl/buffer.h>
+#include <openssl/comp.h>
+#include <openssl/conf.h>
+#include <openssl/conf_api.h>
+#include <openssl/crypto.h>
+#include <openssl/des.h>
+#include <openssl/dh.h>
+#include <openssl/dsa.h>
+#include <openssl/dso.h>
+#include <openssl/e_os2.h>
+#include <openssl/ebcdic.h>
+#include <openssl/engine.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/hmac.h>
+#include <openssl/lhash.h>
+#include <openssl/obj_mac.h>
+#include <openssl/objects.h>
+#include <openssl/opensslconf.h>
+#include <openssl/opensslv.h>
+#include <openssl/pem.h>
+#include <openssl/pem2.h>
+#include <openssl/pkcs12.h>
+#include <openssl/pkcs7.h>
+#include <openssl/rand.h>
+#include <openssl/rsa.h>
+#include <openssl/safestack.h>
+#include <openssl/sha.h>
+#include <openssl/stack.h>
+#include <openssl/symhacks.h>
+#include <openssl/txt_db.h>
+#include <openssl/x509.h>
+#include <openssl/x509_vfy.h>
+#include <openssl/x509v3.h>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/openssl-fips-140/llib-lssl	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,32 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ */
+
+/* LINTLIBRARY */
+/* PROTOLIB1 */
+
+#include <openssl/ssl.h>
+#include <openssl/ssl2.h>
+#include <openssl/ssl23.h>
+#include <openssl/ssl3.h>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/openssl-fips-140/openssl-fips-140.license	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,127 @@
+
+  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. Actually both licenses are BSD-style
+  Open Source licenses. In case of any license issues related to OpenSSL
+  please contact [email protected].
+
+  OpenSSL License
+  ---------------
+
+/* ====================================================================
+ * Copyright (c) 1998-2016 The OpenSSL Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ *    software must display the following acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ *    endorse or promote products derived from this software without
+ *    prior written permission. For written permission, please contact
+ *    [email protected].
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ *    nor may "OpenSSL" appear in their names without prior written
+ *    permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ *    acknowledgment:
+ *    "This product includes software developed by the OpenSSL Project
+ *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * ([email protected]).  This product includes software written by Tim
+ * Hudson ([email protected]).
+ *
+ */
+
+ Original SSLeay License
+ -----------------------
+
+/* Copyright (C) 1995-1998 Eric Young ([email protected])
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young ([email protected]).
+ * The implementation was written so as to conform with Netscapes SSL.
+ * 
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to.  The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson ([email protected]).
+ * 
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *    "This product includes cryptographic software written by
+ *     Eric Young ([email protected])"
+ *    The word 'cryptographic' can be left out if the rouines from the library
+ *    being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from 
+ *    the apps directory (application code) you must include an acknowledgement:
+ *    "This product includes software written by Tim Hudson ([email protected])"
+ * 
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * 
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed.  i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/openssl-fips-140/openssl-fips-140.p5m	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,211 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+#
+
+# Header files.
+#
+# Take header files from the 32-bit build. This build has the patched
+# opensslconf.h (64-bit build does not). We cannot take header files from the
+# proto area since it could contain headers installed for the 64-bit build.
+<transform file path=usr/include/openssl/fips-140/openssl/(.+\.h)$ -> \
+    set action.hash $(MACH32)/include/openssl/%<1> >
+set name=pkg.fmri \
+    value=pkg:/library/security/openssl/openssl-fips-140@$(IPS_COMPONENT_VERSION),$(BUILD_VERSION)
+set name=pkg.summary value="FIPS 140-2 Capable OpenSSL libraries"
+set name=pkg.human-version value=$(COMPONENT_VERSION)
+set name=com.oracle.info.description \
+    value="the FIPS 140-2 Capable OpenSSL libraries"
+set name=com.oracle.info.tpno value=$(TPNO)
+set name=info.classification value=org.opensolaris.category.2008:System/Security
+set name=info.source-url value=$(COMPONENT_ARCHIVE_URL)
+set name=info.upstream-url value=$(COMPONENT_PROJECT_URL)
+set name=org.opensolaris.arc-caseid value=PSARC/2009/507
+set name=org.opensolaris.consolidation value=$(CONSOLIDATION)
+
+# Basic directories and a configuration file.
+file etc/openssl/openssl.cnf path=etc/openssl/fips-140/openssl.cnf group=sys \
+    mode=0644 preserve=true
+link path=lib/$(MACH64)/libcrypto.so.1.0.0 \
+    target=../openssl/fips-140/$(MACH64)/libcrypto.so.1.0.0 mediator=openssl \
+    mediator-implementation=fips-140
+link path=lib/$(MACH64)/libssl.so.1.0.0 \
+    target=../openssl/fips-140/$(MACH64)/libssl.so.1.0.0 mediator=openssl \
+    mediator-implementation=fips-140
+link path=lib/$(MACH64)/llib-lcrypto \
+    target=../openssl/fips-140/$(MACH64)/llib-lcrypto mediator=openssl \
+    mediator-implementation=fips-140
+link path=lib/$(MACH64)/llib-lcrypto.ln \
+    target=../openssl/fips-140/$(MACH64)/llib-lcrypto.ln mediator=openssl \
+    mediator-implementation=fips-140
+link path=lib/$(MACH64)/llib-lssl \
+    target=../openssl/fips-140/$(MACH64)/llib-lssl mediator=openssl \
+    mediator-implementation=fips-140
+link path=lib/$(MACH64)/llib-lssl.ln \
+    target=../openssl/fips-140/$(MACH64)/llib-lssl.ln mediator=openssl \
+    mediator-implementation=fips-140
+
+# Mediator links for 32-bit libraries
+link path=lib/libcrypto.so.1.0.0 target=openssl/fips-140/libcrypto.so.1.0.0 \
+    mediator=openssl mediator-implementation=fips-140
+link path=lib/libssl.so.1.0.0 target=openssl/fips-140/libssl.so.1.0.0 \
+    mediator=openssl mediator-implementation=fips-140
+link path=lib/llib-lcrypto target=openssl/fips-140/llib-lcrypto \
+    mediator=openssl mediator-implementation=fips-140
+link path=lib/llib-lcrypto.ln target=openssl/fips-140/llib-lcrypto.ln \
+    mediator=openssl mediator-implementation=fips-140
+link path=lib/llib-lssl target=openssl/fips-140/llib-lssl mediator=openssl \
+    mediator-implementation=fips-140
+link path=lib/llib-lssl.ln target=openssl/fips-140/llib-lssl.ln \
+    mediator=openssl mediator-implementation=fips-140
+
+# Mediator links for 64-bit libraries
+link path=lib/openssl/engines/$(MACH64)/libpk11.so.1 \
+    target=../../fips-140/engines/$(MACH64)/libpk11.so.1 mediator=openssl \
+    mediator-implementation=fips-140
+link path=lib/openssl/engines/libpk11.so.1 \
+    target=../fips-140/engines/libpk11.so.1 mediator=openssl \
+    mediator-implementation=fips-140
+file $(MACH32)/apps/openssl path=lib/openssl/fips-140/$(MACH32)/openssl \
+    owner=root group=bin mode=0555
+link path=lib/openssl/fips-140/$(MACH64)/libcrypto.so target=libcrypto.so.1.0.0
+
+# 64 bit libraries, lint libraries, and engines.
+file $(MACH64)/libcrypto.so.1.0.0 \
+    path=lib/openssl/fips-140/$(MACH64)/libcrypto.so.1.0.0
+link path=lib/openssl/fips-140/$(MACH64)/libssl.so target=libssl.so.1.0.0
+file $(MACH64)/libssl.so.1.0.0 \
+    path=lib/openssl/fips-140/$(MACH64)/libssl.so.1.0.0
+file llib-lcrypto path=lib/openssl/fips-140/$(MACH64)/llib-lcrypto
+file $(MACH64)/llib-lcrypto.ln \
+    path=lib/openssl/fips-140/$(MACH64)/llib-lcrypto.ln
+file llib-lssl path=lib/openssl/fips-140/$(MACH64)/llib-lssl
+file $(MACH64)/llib-lssl.ln path=lib/openssl/fips-140/$(MACH64)/llib-lssl.ln
+link path=lib/openssl/fips-140/64 target=$(MACH64)
+file etc/openssl/misc/CA.pl path=lib/openssl/fips-140/CA.pl
+link path=lib/openssl/fips-140/engines/$(MACH64)/libpk11.so target=libpk11.so.1
+file $(MACH64)/engines/libpk11.so \
+    path=lib/openssl/fips-140/engines/$(MACH64)/libpk11.so.1
+link path=lib/openssl/fips-140/engines/libpk11.so target=libpk11.so.1
+
+# 32 bit libraries, lint libraries, and engines.
+file $(MACH32)/engines/libpk11.so path=lib/openssl/fips-140/engines/libpk11.so.1
+link path=lib/openssl/fips-140/libcrypto.so target=libcrypto.so.1.0.0
+file $(MACH32)/libcrypto.so.1.0.0 path=lib/openssl/fips-140/libcrypto.so.1.0.0
+link path=lib/openssl/fips-140/libssl.so target=libssl.so.1.0.0
+file $(MACH32)/libssl.so.1.0.0 path=lib/openssl/fips-140/libssl.so.1.0.0
+file llib-lcrypto path=lib/openssl/fips-140/llib-lcrypto
+file $(MACH32)/llib-lcrypto.ln path=lib/openssl/fips-140/llib-lcrypto.ln
+file llib-lssl path=lib/openssl/fips-140/llib-lssl
+file $(MACH32)/llib-lssl.ln path=lib/openssl/fips-140/llib-lssl.ln
+
+# Commands.
+file $(MACH64)/apps/openssl path=lib/openssl/fips-140/openssl owner=root \
+    group=bin mode=0555
+link path=usr/bin/$(MACH32)/openssl \
+    target=../../../lib/openssl/fips-140/$(MACH32)/openssl mediator=openssl \
+    mediator-implementation=fips-140
+link path=usr/bin/CA.pl target=../../lib/openssl/fips-140/CA.pl \
+    mediator=openssl mediator-implementation=fips-140
+
+# Mediator links for the commands
+link path=usr/bin/openssl target=../../lib/openssl/fips-140/openssl \
+    mediator=openssl mediator-implementation=fips-140
+file path=usr/include/openssl/fips-140/openssl/aes.h
+file path=usr/include/openssl/fips-140/openssl/asn1.h
+file path=usr/include/openssl/fips-140/openssl/asn1_mac.h
+file path=usr/include/openssl/fips-140/openssl/asn1t.h
+file path=usr/include/openssl/fips-140/openssl/bio.h
+file path=usr/include/openssl/fips-140/openssl/blowfish.h
+file path=usr/include/openssl/fips-140/openssl/bn.h
+file path=usr/include/openssl/fips-140/openssl/buffer.h
+file path=usr/include/openssl/fips-140/openssl/cast.h
+file path=usr/include/openssl/fips-140/openssl/cmac.h
+file path=usr/include/openssl/fips-140/openssl/cms.h
+file path=usr/include/openssl/fips-140/openssl/comp.h
+file path=usr/include/openssl/fips-140/openssl/conf.h
+file path=usr/include/openssl/fips-140/openssl/conf_api.h
+file path=usr/include/openssl/fips-140/openssl/crypto.h
+file path=usr/include/openssl/fips-140/openssl/des.h
+file path=usr/include/openssl/fips-140/openssl/des_old.h
+file path=usr/include/openssl/fips-140/openssl/dh.h
+file path=usr/include/openssl/fips-140/openssl/dsa.h
+file path=usr/include/openssl/fips-140/openssl/dso.h
+file path=usr/include/openssl/fips-140/openssl/dtls1.h
+file path=usr/include/openssl/fips-140/openssl/e_os2.h
+file path=usr/include/openssl/fips-140/openssl/ebcdic.h
+file path=usr/include/openssl/fips-140/openssl/ec.h
+file path=usr/include/openssl/fips-140/openssl/ecdh.h
+file path=usr/include/openssl/fips-140/openssl/ecdsa.h
+file path=usr/include/openssl/fips-140/openssl/engine.h
+file path=usr/include/openssl/fips-140/openssl/err.h
+file path=usr/include/openssl/fips-140/openssl/evp.h
+file path=usr/include/openssl/fips-140/openssl/fips.h
+file path=usr/include/openssl/fips-140/openssl/fips_rand.h
+file path=usr/include/openssl/fips-140/openssl/hmac.h
+file path=usr/include/openssl/fips-140/openssl/krb5_asn.h
+file path=usr/include/openssl/fips-140/openssl/kssl.h
+file path=usr/include/openssl/fips-140/openssl/lhash.h
+file path=usr/include/openssl/fips-140/openssl/md2.h
+file path=usr/include/openssl/fips-140/openssl/md4.h
+file path=usr/include/openssl/fips-140/openssl/md5.h
+file path=usr/include/openssl/fips-140/openssl/modes.h
+file path=usr/include/openssl/fips-140/openssl/obj_mac.h
+file path=usr/include/openssl/fips-140/openssl/objects.h
+file path=usr/include/openssl/fips-140/openssl/ocsp.h
+file path=usr/include/openssl/fips-140/openssl/opensslconf.h
+file path=usr/include/openssl/fips-140/openssl/opensslv.h
+file path=usr/include/openssl/fips-140/openssl/ossl_typ.h
+file path=usr/include/openssl/fips-140/openssl/pem.h
+file path=usr/include/openssl/fips-140/openssl/pem2.h
+file path=usr/include/openssl/fips-140/openssl/pkcs12.h
+file path=usr/include/openssl/fips-140/openssl/pkcs7.h
+file path=usr/include/openssl/fips-140/openssl/pqueue.h
+file path=usr/include/openssl/fips-140/openssl/rand.h
+file path=usr/include/openssl/fips-140/openssl/rc2.h
+file path=usr/include/openssl/fips-140/openssl/rc4.h
+file path=usr/include/openssl/fips-140/openssl/ripemd.h
+file path=usr/include/openssl/fips-140/openssl/rsa.h
+file path=usr/include/openssl/fips-140/openssl/safestack.h
+file path=usr/include/openssl/fips-140/openssl/sha.h
+file path=usr/include/openssl/fips-140/openssl/srp.h
+file path=usr/include/openssl/fips-140/openssl/srtp.h
+file path=usr/include/openssl/fips-140/openssl/ssl.h
+file path=usr/include/openssl/fips-140/openssl/ssl2.h
+file path=usr/include/openssl/fips-140/openssl/ssl23.h
+file path=usr/include/openssl/fips-140/openssl/ssl3.h
+file path=usr/include/openssl/fips-140/openssl/stack.h
+file path=usr/include/openssl/fips-140/openssl/symhacks.h
+file path=usr/include/openssl/fips-140/openssl/tls1.h
+file path=usr/include/openssl/fips-140/openssl/ts.h
+file path=usr/include/openssl/fips-140/openssl/txt_db.h
+file path=usr/include/openssl/fips-140/openssl/ui.h
+file path=usr/include/openssl/fips-140/openssl/ui_compat.h
+file path=usr/include/openssl/fips-140/openssl/whrlpool.h
+file path=usr/include/openssl/fips-140/openssl/x509.h
+file path=usr/include/openssl/fips-140/openssl/x509_vfy.h
+file path=usr/include/openssl/fips-140/openssl/x509v3.h
+license openssl-fips-140.license license="OpenSSL, SSLeay"
+
+# OpenSSL packages are now managed by 'pkg mediator', and the installation
+# of 'openssl-fips-140' package requires 'openssl' package with the mediator
+# change (s11u2_build35 or later)
+depend type=optional fmri=library/security/[email protected],5.11-0.175.2.0.0.35.0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/openssl-fips-140/patches-post-config/opensslconf.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,54 @@
+--- /tmp/opensslconf.h	Fri Feb 11 15:36:12 2011
++++ openssl-1.0.0d/crypto/opensslconf.h	Fri Feb 11 16:58:36 2011
+@@ -181,7 +181,11 @@
+ 
+ #if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
+ #if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
++#if defined(__sparcv9) || defined(__x86_64)
++#define ENGINESDIR "/lib/openssl/engines/64"
++#else
+ #define ENGINESDIR "/lib/openssl/engines"
++#endif
+ #define OPENSSLDIR "/etc/openssl"
+ #endif
+ #endif
+@@ -228,21 +232,39 @@
+ /* 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
++#if defined(__sparcv9) || defined(__x86_64)
++#define DES_LONG unsigned int
++#else
+ #define DES_LONG unsigned long
+ #endif
+ #endif
++#endif
+ 
+ #if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
+ #define CONFIG_HEADER_BN_H
++/*
++ * OpenSSL revision 1.521 from 2005-12-15 in OpenSSL_1_0_0-stable branch changed
++ * 64 bit sparcv9 configuration from SIXTY_FOUR_BIT_LONG to BN_LLONG.
++ */
++#if defined(__x86_64)
++#undef BN_LLONG
++#else
+ #define BN_LLONG
++#endif
+ 
+ /* Should we define BN_DIV2W here? */
+ 
+ /* Only one for the following should be defined */
++#if defined(__x86_64)
++#define SIXTY_FOUR_BIT_LONG
++#undef THIRTY_TWO_BIT
++#else
+ #undef SIXTY_FOUR_BIT_LONG
+ #undef SIXTY_FOUR_BIT
+ #define THIRTY_TWO_BIT
+ #endif
++#undef SIXTY_FOUR_BIT
++#endif
+ 
+ #if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
+ #define CONFIG_HEADER_RC4_LOCL_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/openssl-fips-140/patches/201-openssl_fips.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,85 @@
+#
+# Patch developed in-house.  Solaris-specific; not suitable for upstream. 
+#
+--- openssl-0.9.8m/apps/openssl.c	Thu Oct 15 19:28:02 2009
++++ openssl-0.9.8m/apps/openssl.c	Fri Feb 26 16:12:30 2010
+@@ -135,6 +135,9 @@
+ # include <openssl/fips.h>
+ #endif
+ 
++/* Solaris OpenSSL */
++#include <dlfcn.h>
++
+ /*
+  * The LHASH callbacks ("hash" & "cmp") have been replaced by functions with
+  * the base prototypes (we cast each variable inside the function to the
+@@ -155,9 +158,10 @@
+ BIO *bio_err = NULL;
+ #endif
+ 
++static int *modes;
++
+ 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;
+ 
+@@ -167,7 +168,7 @@
+         goto err;
+     }
+ 
+-    if (type < 0 || type >= CRYPTO_NUM_LOCKS) {
++    if (type < 0 || type >= CRYPTO_num_locks()) {
+         errstr = "type out of bounds";
+         goto err;
+     }
+@@ -305,6 +306,14 @@
+     if (getenv("OPENSSL_DEBUG_LOCKING") != NULL)
+ #endif
+     {
++        modes = OPENSSL_malloc(CRYPTO_num_locks() * sizeof (int));
++        if (modes == NULL) {
++            ERR_load_crypto_strings();
++            BIO_printf(bio_err,"Memory allocation failure\n");
++            ERR_print_errors(bio_err);
++            EXIT(1);
++        }
++        memset(modes, 0, CRYPTO_num_locks() * sizeof (int));
+         CRYPTO_set_locking_callback(lock_dbg_cb);
+     }
+ 
+@@ -308,18 +320,28 @@
+         CRYPTO_set_locking_callback(lock_dbg_cb);
+     }
+ 
++/*
++ * Solaris OpenSSL
++ * Add a further check for the FIPS_mode_set() symbol before calling to
++ * allow openssl(1openssl) to be run against both fips and non-fips libraries.
++ */
+     if (getenv("OPENSSL_FIPS")) {
+-#ifdef OPENSSL_FIPS
+-        if (!FIPS_mode_set(1)) {
++
++        int (*FIPS_mode_set)(int);
++        FIPS_mode_set = (int (*)(int)) dlsym(RTLD_NEXT, "FIPS_mode_set");
++
++        if (FIPS_mode_set != NULL) {
++            if (!(*FIPS_mode_set)(1)) {
+             ERR_load_crypto_strings();
+             ERR_print_errors(BIO_new_fp(stderr, BIO_NOCLOSE));
+             EXIT(1);
+         }
+-#else
+-        fprintf(stderr, "FIPS mode not supported.\n");
++    } else {
++            fprintf(stderr, "Failed to enable FIPS mode. "
++                "For more information about running in FIPS mode see openssl(5).\n");
+         EXIT(1);
+-#endif
+     }
++    }
+ 
+     apps_startup();
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openssl/openssl-fips-140/patches/203-multi-definition.patch	Wed Oct 26 13:19:33 2016 -0700
@@ -0,0 +1,24 @@
+#
+# Patch developed in house.
+# The issue was reported to the Upstream by external person: Bug #3699.
+#
+--- openssl-0.9.8m/crypto/sparccpuid.S       Mon Jun 29 19:28:02 2015
++++ openssl-0.9.8m/crypto/sparccpuid.S       Mon Jun 29 19:28:02 2015
+@@ -428,6 +428,8 @@
+ .type	OPENSSL_cleanse,#function
+ .size	OPENSSL_cleanse,.-OPENSSL_cleanse
+
++
++#if 0
+ .global	_sparcv9_vis1_instrument_bus
+ .weak	_sparcv9_vis1_instrument_bus
+ .align	8
+@@ -496,6 +498,8 @@
+ .type	_sparcv9_vis1_instrument_bus2,#function
+ .size	_sparcv9_vis1_instrument_bus2,.-_sparcv9_vis1_instrument_bus2
+
++#endif
++
+ .section	".init",#alloc,#execinstr
+ 	call	solaris_locking_setup
+ 	nop
--- a/components/openssl/openssl-fips/Makefile	Wed Oct 12 06:26:22 2016 -0700
+++ b/components/openssl/openssl-fips/Makefile	Wed Oct 26 13:19:33 2016 -0700
@@ -18,7 +18,9 @@
 #
 # CDDL HEADER END
 #
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+
+#
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
 #
 
 #
@@ -29,11 +31,11 @@
 include ../../../make-rules/shared-macros.mk
 
 COMPONENT_NAME =	openssl-fips
-COMPONENT_VERSION =	2.0.6
+COMPONENT_VERSION =	2.0.12
 COMPONENT_SRC =		$(COMPONENT_NAME)-ecp-$(COMPONENT_VERSION)
 COMPONENT_ARCHIVE =	$(COMPONENT_SRC).tar.gz
 COMPONENT_ARCHIVE_HASH=	\
-    sha256:861b431c625c27daf440041fd67c0866ebb84b44cc672cf1ea8f23e883518897
+    sha256:976b264835f7f30bf6545464158613ae5246d9d46913c1ba1534b9ef552dcc3b
 COMPONENT_ARCHIVE_URL =	http://www.openssl.org/source/$(COMPONENT_ARCHIVE)
 COMPONENT_BUGDB=	library/openssl
 
@@ -55,10 +57,10 @@
 FAKE_CC = cc
 FAKE_APPS = $(FAKE_ISALIST) $(FAKE_MAKE) $(FAKE_CC)
 
-CLOBBER_PATHS += $(FAKE_APPS)
+CLEAN_PATHS += $(FAKE_APPS)
 
 # Do not use $(PWD), it would not work if run from a different directory with
-# "gmake -C" as we do from openssl-1.0.1
+# "gmake -C" as we do from openssl-default
 # we'll also pick up gcc if we find it in the path, so force it to
 # find one that doesn't work like it wants
 FIPS_PATH_32 = $(COMPONENT_DIR)/32:$(COMPONENT_DIR)/gcc:$(PATH)
@@ -69,7 +71,7 @@
 # Note: COMPONENT_ARCHIVE_HASH is a SHA256 digest used by the Userland
 # Consolidation to check the file integrity.
 OPENSSL_FIPS_HMAC_KEY = etaonrishdlcupfm
-OPENSSL_FIPS_HMAC = 852f43cd9ae1bd2eba60e4f9f1f266d3c16c0319
+OPENSSL_FIPS_HMAC = 3da3e6d610378ad4b6ee2638a141c17cb3a2aabf
 
 # There is a broken link in the tarball which causes cp(1) to fail which would
 # fail the whole configure process. It's safer to get rid of the link than
@@ -97,6 +99,10 @@
 COMPONENT_BUILD_TARGETS =
 COMPONENT_INSTALL_ARGS =
 COMPONENT_INSTALL_TARGETS = install
+# Ignore default CC_FOR_BUILD, CC, and CXX in CONFIGURE_ENV.
+CONFIGURE_ENV += CC_FOR_BUILD=
+CONFIGURE_ENV += CC=
+CONFIGURE_ENV += CXX=
 CONFIGURE_ENV += FIPS_SITE_LD=$(LD) PATH=$(FIPS_PATH_$(BITS))
 # Add COMPONENT_DIR to PATH so cc wrapper can be found.
 COMPONENT_BUILD_ENV += FIPS_SITE_LD=$(LD) REALCC=$(CC) MYMAKE=$(MAKE) PATH=$(COMPONENT_DIR):$(PATH)
@@ -106,6 +112,8 @@
 # You should not use this target with this component unless testing or
 # debugging. The OpenSSL FIPS-140 policy is strict and full U2 command set
 # should be run. See above for more information.
+configure:	$(CONFIGURE_32_and_64)
+
 build:		$(BUILD_32_and_64)
 
 # We must make the "install" target a no-op (but must run it to be compliant).
@@ -117,12 +125,14 @@
 # used and that we used the correct tarball.
 $(BUILD_DIR)/%/.verified:	$(BUILD_DIR)/%/.installed
 	(printf x; \
-	$(ENV) - OPENSSL_FIPS=1 LD_LIBRARY_PATH=$(@D) \
+	$(ENV) - OPENSSL_FIPS=1 LD_LIBRARY_PATH=/lib/openssl/fips-140/64 \
 	/lib/openssl/fips-140/openssl sha1 -hmac $(OPENSSL_FIPS_HMAC_KEY) \
 	    $(COMPONENT_ARCHIVE)) | \
 	    $(NAWK) '{ if ($$2 != "$(OPENSSL_FIPS_HMAC)") exit 1 }'
 	@echo Basic FIPS-140 mode verification passed.
 	$(TOUCH) $@	    	
 
-test:		$(NO_TESTS)
+test:           $(NO_TESTS)
 
+system-test:    $(NO_TESTS)
+