-Index: openssl/Configure
-diff -u openssl/Configure:1.1.3.1 openssl/Configure:1.7
---- openssl/Configure:1.1.3.1 Mon Feb 16 08:44:22 2009
-+++ openssl/Configure Mon Oct 5 13:16:50 2009
+Index: openssl-0.9.8s/Configure
+diff -Nur openssl-0.9.8s/Configure openssl-0.9.8s-patched/Configure
+--- openssl-0.9.8s/Configure 2010-12-10 16:30:42.000000000 -0800
++++ openssl-0.9.8s-patched/Configure 2012-01-11 12:03:30.011811586 -0800
@@ -12,7 +12,7 @@
# see INSTALL for instructions.
# --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".
-@@ -329,7 +335,7 @@
+@@ -335,7 +341,7 @@
"linux-ppc", "gcc:-DB_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL::linux_ppc32.o::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
#### IA-32 targets...
"linux-ia32-icc", "icc:-DL_ENDIAN -DTERMIO -O2 -no_cpprt::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-KPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"linux-aout", "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -march=i486 -Wall::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_out_asm}",
####
"linux-generic64","gcc:-DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
-@@ -337,7 +343,7 @@
+@@ -343,7 +349,7 @@
"linux-ia64", "gcc:-DL_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"linux-ia64-ecc","ecc:-DL_ENDIAN -DTERMIO -O2 -Wall -no_cpprt::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
"linux-ia64-icc","icc:-DL_ENDIAN -DTERMIO -O2 -Wall -no_cpprt::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
--"linux-x86_64", "gcc:-m64 -DL_ENDIAN -DTERMIO -O3 -Wall -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK BF_PTR2 DES_INT DES_UNROLL:${x86_64_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+-"linux-x86_64", "gcc:-m64 -DL_ENDIAN -DTERMIO -O3 -Wall -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
+"linux-x86_64", "gcc:-m64 -DL_ENDIAN -DTERMIO -O3 -Wall -DMD32_REG_T=int::-D_REENTRANT -pthread::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK BF_PTR2 DES_INT DES_UNROLL:${x86_64_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
#### SPARC Linux setups
# Ray Miller <ray.miller@computing-services.oxford.ac.uk> has patiently
# assisted with debugging of following two configs.
-@@ -580,6 +586,10 @@
+@@ -590,6 +596,10 @@
my $idx_ranlib = $idx++;
my $idx_arflags = $idx++;
+my $pk11_flavor="";
+
my $prefix="";
+ my $libdir="";
my $openssldir="";
- my $exe_ext="";
-@@ -812,6 +822,14 @@
+@@ -828,6 +838,14 @@
{
$flags.=$_." ";
}
elsif (/^--prefix=(.*)$/)
{
$prefix=$1;
-@@ -943,6 +961,22 @@
+@@ -963,6 +981,22 @@
exit 0;
}
if ($target =~ m/^CygWin32(-.*)$/) {
$target = "Cygwin".$1;
}
-@@ -1057,6 +1091,25 @@
+@@ -1078,6 +1112,25 @@
print "\n";
}
my $IsMK1MF=scalar grep /^$target$/,@MK1MF_Builds;
$IsMK1MF=1 if ($target eq "mingw" && $^O ne "cygwin" && !is_msys());
-@@ -1103,6 +1156,8 @@
+@@ -1129,6 +1182,8 @@
if ($flags ne "") { $cflags="$flags$cflags"; }
else { $no_user_cflags=1; }
# Kerberos settings. The flavor must be provided from outside, either through
# the script "config" or manually.
if (!$no_krb5)
-@@ -1456,6 +1511,7 @@
+@@ -1492,6 +1547,7 @@
s/^VERSION=.*/VERSION=$version/;
s/^MAJOR=.*/MAJOR=$major/;
s/^MINOR=.*/MINOR=$minor/;
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/;
-Index: openssl/Makefile.org
-diff -u openssl/Makefile.org:1.1.3.1 openssl/Makefile.org:1.3
---- openssl/Makefile.org:1.1.3.1 Tue Mar 3 22:40:29 2009
-+++ openssl/Makefile.org Fri Sep 4 10:43:21 2009
-@@ -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
-
-Index: openssl/README.pkcs11
-diff -u /dev/null openssl/README.pkcs11:1.6
---- /dev/null Thu Dec 24 13:00:42 2009
-+++ openssl/README.pkcs11 Mon Oct 5 13:16:50 2009
-@@ -0,0 +1,247 @@
-+ISC modified
-+============
-+
-+The PKCS#11 engine exists in two flavors, crypto-accelerator and
-+sign-only. The first one is from the Solaris patch and uses the
-+PKCS#11 device for all crypto operations it supports. The second
-+is a stripped down version which provides only the useful
-+function (i.e., signature with a RSA private key in the device
-+protected key store and key loading).
-+
-+As a hint PKCS#11 boards should use the crypto-accelerator flavor,
-+external PKCS#11 devices the sign-only. SCA 6000 is an example
-+of the first, AEP Keyper of the second.
-+
-+Note it is mandatory to set a pk11-flavor (and only one) in
-+config/Configure.
-+
-+PKCS#11 engine support for OpenSSL 0.9.8j
-+=========================================
-+
-+[March 11, 2009]
-+
-+Contents:
-+
-+Overview
-+Revisions of the patch for 0.9.8 branch
-+FAQs
-+Feedback
-+
-+Overview
-+========
-+
-+This patch containing code available in OpenSolaris adds support for PKCS#11
-+engine into OpenSSL and implements PKCS#11 v2.20. It is to be applied against
-+OpenSSL 0.9.8j source code distribution as shipped by OpenSSL.Org. Your system
-+must provide PKCS#11 backend otherwise the patch is useless. You provide the
-+PKCS#11 library name during the build configuration phase, see below.
-+
-+Patch can be applied like this:
+Index: openssl-0.9.8s/crypto/bio/bss_file.c
+diff -Nur openssl-0.9.8s/crypto/bio/bss_file.c openssl-0.9.8s-patched/crypto/bio/bss_file.c
+--- openssl-0.9.8s/crypto/bio/bss_file.c 2010-03-22 15:40:18.000000000 -0700
++++ openssl-0.9.8s-patched/crypto/bio/bss_file.c 2012-01-11 12:03:30.011811586 -0800
+@@ -125,7 +125,7 @@
+ {
+ SYSerr(SYS_F_FOPEN,get_last_sys_error());
+ ERR_add_error_data(5,"fopen('",filename,"','",mode,"')");
+- if (errno == ENOENT)
++ if ((errno == ENOENT) || ((*mode == 'r') && (errno == EACCES)))
+ BIOerr(BIO_F_BIO_NEW_FILE,BIO_R_NO_SUCH_FILE);
+ else
+ BIOerr(BIO_F_BIO_NEW_FILE,ERR_R_SYS_LIB);
+Index: openssl-0.9.8s/crypto/engine/cryptoki.h
+diff -Nur openssl-0.9.8s/crypto/engine/cryptoki.h openssl-0.9.8s-patched/crypto/engine/cryptoki.h
+--- openssl-0.9.8s/crypto/engine/cryptoki.h 1969-12-31 16:00:00.000000000 -0800
++++ openssl-0.9.8s-patched/crypto/engine/cryptoki.h 2012-01-11 12:03:30.011811586 -0800
+@@ -0,0 +1,103 @@
++/*
++ * CDDL HEADER START
++ *
++ * The contents of this file are subject to the terms of the
++ * Common Development and Distribution License, Version 1.0 only
++ * (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 2003 Sun Microsystems, Inc. All rights reserved.
++ * Use is subject to license terms.
++ */
+
-+ # NOTE: use gtar if on Solaris
-+ tar xfzv openssl-0.9.8j.tar.gz
-+ # now download the patch to the current directory
-+ # ...
-+ cd openssl-0.9.8j
-+ # NOTE: must use gpatch if on Solaris (is part of the system)
-+ patch -p1 < path-to/pkcs11_engine-0.9.8j.patch.2009-03-11
++#ifndef _CRYPTOKI_H
++#define _CRYPTOKI_H
+
-+It is designed to support pure acceleration for RSA, DSA, DH and all the
-+symetric ciphers and message digest algorithms that PKCS#11 and OpenSSL share
-+except for missing support for patented algorithms MDC2, RC3, RC5 and IDEA.
++/* ident "@(#)cryptoki.h 1.2 05/06/08 SMI" */
+
-+According to the PKCS#11 providers installed on your machine, it can support
-+following mechanisms:
++#ifdef __cplusplus
++extern "C" {
++#endif
+
-+ RSA, DSA, DH, RAND, DES-CBC, DES-EDE3-CBC, DES-ECB, DES-EDE3, RC4,
-+ AES-128-CBC, AES-192-CBC, AES-256-CBC, AES-128-ECB, AES-192-ECB,
-+ AES-256-ECB, AES-128-CTR, AES-192-CTR, AES-256-CTR, MD5, SHA1, SHA224,
-+ SHA256, SHA384, SHA512
++#ifndef CK_PTR
++#define CK_PTR *
++#endif
+
-+Note that for AES counter mode the application must provide their own EVP
-+functions since OpenSSL doesn't support counter mode through EVP yet. You may
-+see OpenSSH source code (cipher.c) to get the idea how to do that. SunSSH is an
-+example of code that uses the PKCS#11 engine and deals with the fork-safety
-+problem (see engine.c and packet.c files if interested).
++#ifndef CK_DEFINE_FUNCTION
++#define CK_DEFINE_FUNCTION(returnType, name) returnType name
++#endif
+
-++------------------------------------------------------------------------------+
-+| NOTE: this patch version does NOT contain experimental code for accessing |
-+| RSA keys stored in PKCS#11 key stores by reference. Some problems were found |
-+| (thanks to all who wrote me!) and due to my ENOTIME problem I may address |
-+| those issues in a future version of the patch that will have that code back, |
-+| hopefully fixed. |
-++------------------------------------------------------------------------------+
++#ifndef CK_DECLARE_FUNCTION
++#define CK_DECLARE_FUNCTION(returnType, name) returnType name
++#endif
+
-+You must provide the location of PKCS#11 library in your system to the
-+configure script. You will be instructed to do that when you try to run the
-+config script:
++#ifndef CK_DECLARE_FUNCTION_POINTER
++#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
++#endif
+
-+ $ ./config
-+ Operating system: i86pc-whatever-solaris2
-+ Configuring for solaris-x86-cc
-+ You must set --pk11-libname for PKCS#11 library.
-+ See README.pkcs11 for more information.
++#ifndef CK_CALLBACK_FUNCTION
++#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
++#endif
+
-+Taking openCryptoki project on Linux AMD64 box as an example, you would run
-+configure script like this:
++#ifndef NULL_PTR
++#include <unistd.h> /* For NULL */
++#define NULL_PTR NULL
++#endif
+
-+ ./config --pk11-libname=/usr/lib64/pkcs11/PKCS11_API.so
++/*
++ * pkcs11t.h defines TRUE and FALSE in a way that upsets lint
++ */
++#ifndef CK_DISABLE_TRUE_FALSE
++#define CK_DISABLE_TRUE_FALSE
++#ifndef TRUE
++#define TRUE 1
++#endif /* TRUE */
++#ifndef FALSE
++#define FALSE 0
++#endif /* FALSE */
++#endif /* CK_DISABLE_TRUE_FALSE */
+
-+To check whether newly built openssl really supports PKCS#11 it's enough to run
-+"apps/openssl engine" and look for "(pkcs11) PKCS #11 engine support" in the
-+output. If you see no PKCS#11 engine support check that the built openssl binary
-+and the PKCS#11 library from --pk11-libname don't conflict on 32/64 bits.
++#undef CK_PKCS11_FUNCTION_INFO
+
-+This patch was tested on Solaris against PKCS#11 engine available from Solaris
-+Cryptographic Framework (Solaris 10 and OpenSolaris) and also on Linux using
-+PKCS#11 libraries from openCryptoki project (see openCryptoki website
-+http://sourceforge.net/projects/opencryptoki for more information). Some Linux
-+distributions even ship those libraries with the system. The patch should work
-+on any system that is supported by OpenSSL itself and has functional PKCS#11
-+library.
++#include "pkcs11.h"
+
-+The patch contains "RSA Security Inc. PKCS #11 Cryptographic Token Interface
-+(Cryptoki)" - files cryptoki.h, pkcs11.h, pkcs11f.h and pkcs11t.h which are
-+copyrighted by RSA Security Inc., see pkcs11.h for more information.
++/* Solaris specific functions */
+
-+Other added/modified code in this patch is copyrighted by Sun Microsystems,
-+Inc. and is released under the OpenSSL license (see LICENSE file for more
-+information).
++#include <stdlib.h>
+
-+Revisions of the patch for 0.9.8 branch
-+=======================================
++/*
++ * SUNW_C_GetMechSession will initialize the framework and do all
++ * the necessary PKCS#11 calls to create a session capable of
++ * providing operations on the requested mechanism
++ */
++CK_RV SUNW_C_GetMechSession(CK_MECHANISM_TYPE mech,
++ CK_SESSION_HANDLE_PTR hSession);
+
-+2009-03-11
-+- adjusted for OpenSSL version 0.9.8j
++/*
++ * SUNW_C_KeyToObject will create a secret key object for the given
++ * mechanism from the rawkey data.
++ */
++CK_RV SUNW_C_KeyToObject(CK_SESSION_HANDLE hSession,
++ CK_MECHANISM_TYPE mech, const void *rawkey, size_t rawkey_len,
++ CK_OBJECT_HANDLE_PTR obj);
+
-+- README.pkcs11 moved out of the patch, and is shipped together with it in a
-+ tarball instead so that it can be read before the patch is applied.
+
-+- fixed bugs:
++#ifdef __cplusplus
++}
++#endif
+
-+ 6804216 pkcs#11 engine should support a key length range for RC4
-+ 6734038 Apache SSL web server using the pkcs11 engine fails to start if
-+ meta slot is disabled
++#endif /* _CRYPTOKI_H */
+Index: openssl-0.9.8s/crypto/engine/eng_all.c
+diff -Nur openssl-0.9.8s/crypto/engine/eng_all.c openssl-0.9.8s-patched/crypto/engine/eng_all.c
+--- openssl-0.9.8s/crypto/engine/eng_all.c 2010-02-28 16:30:11.000000000 -0800
++++ openssl-0.9.8s-patched/crypto/engine/eng_all.c 2012-01-11 12:03:30.011811586 -0800
+@@ -110,6 +110,14 @@
+ #if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
+ ENGINE_load_capi();
+ #endif
++#ifndef OPENSSL_NO_HW_PKCS11
++#ifndef OPENSSL_NO_HW_PKCS11CA
++ ENGINE_load_pk11ca();
++#endif
++#ifndef OPENSSL_NO_HW_PKCS11SO
++ ENGINE_load_pk11so();
++#endif
++#endif
+ #endif
+ }
+
+Index: openssl-0.9.8s/crypto/engine/engine.h
+diff -Nur openssl-0.9.8s/crypto/engine/engine.h openssl-0.9.8s-patched/crypto/engine/engine.h
+--- openssl-0.9.8s/crypto/engine/engine.h 2010-02-09 06:18:15.000000000 -0800
++++ openssl-0.9.8s-patched/crypto/engine/engine.h 2012-01-11 12:03:30.011811586 -0800
+@@ -337,6 +337,12 @@
+ void ENGINE_load_ubsec(void);
+ #endif
+ void ENGINE_load_cryptodev(void);
++#ifndef OPENSSL_NO_HW_PKCS11CA
++void ENGINE_load_pk11ca(void);
++#endif
++#ifndef OPENSSL_NO_HW_PKCS11SO
++void ENGINE_load_pk11so(void);
++#endif
+ void ENGINE_load_padlock(void);
+ void ENGINE_load_builtin_engines(void);
+ #ifdef OPENSSL_SYS_WIN32
+Index: openssl-0.9.8s/crypto/engine/eng_list.c
+diff -Nur openssl-0.9.8s/crypto/engine/eng_list.c openssl-0.9.8s-patched/crypto/engine/eng_list.c
+--- openssl-0.9.8s/crypto/engine/eng_list.c 2010-03-27 11:28:24.000000000 -0700
++++ openssl-0.9.8s-patched/crypto/engine/eng_list.c 2012-01-11 12:03:30.011811586 -0800
+@@ -408,7 +408,11 @@
+ !ENGINE_ctrl_cmd_string(iterator, "DIR_ADD",
+ load_dir, 0) ||
+ !ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0))
++ {
++ if (iterator)
++ ENGINE_free(iterator);
+ goto notfound;
++ }
+ return iterator;
+ }
+ notfound:
+Index: openssl-0.9.8s/crypto/engine/hw_pk11.c
+diff -Nur openssl-0.9.8s/crypto/engine/hw_pk11.c openssl-0.9.8s-patched/crypto/engine/hw_pk11.c
+--- openssl-0.9.8s/crypto/engine/hw_pk11.c 1969-12-31 16:00:00.000000000 -0800
++++ openssl-0.9.8s-patched/crypto/engine/hw_pk11.c 2012-01-11 12:03:30.021809298 -0800
+@@ -0,0 +1,3927 @@
++/*
++ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
++ * Use is subject to license terms.
++ */
+
-+2008-12-02
-+- fixed bugs and RFEs (most of the work done by Vladimir Kotal)
++/* crypto/engine/hw_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
++ * licensing@OpenSSL.org.
++ *
++ * 5. Products derived from this software may not be called "OpenSSL"
++ * nor may "OpenSSL" appear in their names without prior written
++ * permission of the OpenSSL Project.
++ *
++ * 6. Redistributions of any form whatsoever must retain the following
++ * acknowledgment:
++ * "This product includes software developed by the OpenSSL Project
++ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
++ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
++ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
++ * OF THE POSSIBILITY OF SUCH DAMAGE.
++ * ====================================================================
++ *
++ * This product includes cryptographic software written by Eric Young
++ * (eay@cryptsoft.com). This product includes software written by Tim
++ * Hudson (tjh@cryptsoft.com).
++ *
++ */
+
-+ 6723504 more granular locking in PKCS#11 engine
-+ 6667128 CRYPTO_LOCK_PK11_ENGINE assumption does not hold true
-+ 6710420 PKCS#11 engine source should be lint clean
-+ 6747327 PKCS#11 engine atfork handlers need to be aware of guys who take
-+ it seriously
-+ 6746712 PKCS#11 engine source code should be cstyle clean
-+ 6731380 return codes of several functions are not checked in the PKCS#11
-+ engine code
-+ 6746735 PKCS#11 engine should use extended FILE space API
-+ 6734038 Apache SSL web server using the pkcs11 engine fails to start if
-+ meta slot is disabled
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sys/types.h>
+
-+2008-08-01
-+- fixed bug
++#include <openssl/e_os2.h>
++#include <openssl/crypto.h>
++#include <cryptlib.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>
+
-+ 6731839 OpenSSL PKCS#11 engine no longer uses n2cp for symmetric ciphers
-+ and digests
++#ifdef OPENSSL_SYS_WIN32
++typedef int pid_t;
++#define getpid() GetCurrentProcessId()
++#define NOPTHREADS
++#ifndef NULL_PTR
++#define NULL_PTR NULL
++#endif
++#define CK_DEFINE_FUNCTION(returnType, name) \
++ returnType __declspec(dllexport) name
++#define CK_DECLARE_FUNCTION(returnType, name) \
++ returnType __declspec(dllimport) name
++#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
++ returnType __declspec(dllimport) (* name)
++#else
++#include <signal.h>
++#include <unistd.h>
++#include <dlfcn.h>
++#endif
+
-+- Solaris specific code for slot selection made automatic
++#ifndef NOPTHREADS
++#include <pthread.h>
++#endif
+
-+2008-07-29
-+- update the patch to OpenSSL 0.9.8h version
-+- pkcs11t.h updated to the latest version:
++#ifndef OPENSSL_NO_HW
++#ifndef OPENSSL_NO_HW_PK11
++#ifndef OPENSSL_NO_HW_PK11CA
+
-+ 6545665 make CKM_AES_CTR available to non-kernel users
++/* 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)
++#undef SOLARIS_HW_SLOT_SELECTION
++#endif
+
-+- fixed bugs in the engine code:
++/*
++ * AES counter mode is not supported in the OpenSSL EVP API yet and neither
++ * there are official OIDs for mechanisms based on this mode. With our changes,
++ * an application can define its own EVP calls for AES counter mode and then
++ * it can make use of hardware acceleration through this engine. However, it's
++ * better if we keep AES CTR support code under ifdef's.
++ */
++#define SOLARIS_AES_CTR
+
-+ 6602801 PK11_SESSION cache has to employ reference counting scheme for
-+ asymmetric key operations
-+ 6605538 pkcs11 functions C_FindObjects[{Init,Final}]() not called
-+ atomically
-+ 6607307 pkcs#11 engine can't read RSA private keys
-+ 6652362 pk11_RSA_finish() is cutting corners
-+ 6662112 pk11_destroy_{rsa,dsa,dh}_key_objects() use locking in
-+ suboptimal way
-+ 6666625 pk11_destroy_{rsa,dsa,dh}_key_objects() should be more
-+ resilient to destroy failures
-+ 6667273 OpenSSL engine should not use free() but OPENSSL_free()
-+ 6670363 PKCS#11 engine fails to reuse existing symmetric keys
-+ 6678135 memory corruption in pk11_DH_generate_key() in pkcs#11 engine
-+ 6678503 DSA signature conversion in pk11_dsa_do_verify() ignores size
-+ of big numbers leading to failures
-+ 6706562 pk11_DH_compute_key() returns 0 in case of failure instead of
-+ -1
-+ 6706622 pk11_load_{pub,priv}key create corrupted RSA key references
-+ 6707129 return values from BN_new() in pk11_DH_generate_key() are not
-+ checked
-+ 6707274 DSA/RSA/DH PKCS#11 engine operations need to be resistant to
-+ structure reuse
-+ 6707782 OpenSSL PKCS#11 engine pretends to be aware of
-+ OPENSSL_NO_{RSA,DSA,DH}
-+ defines but fails miserably
-+ 6709966 make check_new_*() to return values to indicate cache hit/miss
-+ 6705200 pk11_dh struct initialization in PKCS#11 engine is missing
-+ generate_params parameter
-+ 6709513 PKCS#11 engine sets IV length even for ECB modes
-+ 6728296 buffer length not initialized for C_(En|De)crypt_Final() in the
-+ PKCS#11 engine
-+ 6728871 PKCS#11 engine must reset global_session in pk11_finish()
++#ifdef OPENSSL_SYS_WIN32
++#pragma pack(push, cryptoki, 1)
++#include "cryptoki.h"
++#include "pkcs11.h"
++#pragma pack(pop, cryptoki)
++#else
++#include "cryptoki.h"
++#include "pkcs11.h"
++#endif
++#include "hw_pk11ca.h"
++#include "hw_pk11_err.c"
+
-+- new features and enhancements:
++#ifdef SOLARIS_AES_CTR
++/*
++ * NIDs for AES counter mode that will be defined during the engine
++ * initialization.
++ */
++static int NID_aes_128_ctr = NID_undef;
++static int NID_aes_192_ctr = NID_undef;
++static int NID_aes_256_ctr = NID_undef;
++#endif /* SOLARIS_AES_CTR */
+
-+ 6562155 OpenSSL pkcs#11 engine needs support for SHA224/256/384/512
-+ 6685012 OpenSSL pkcs#11 engine needs support for new cipher modes
-+ 6725903 OpenSSL PKCS#11 engine shouldn't use soft token for symmetric
-+ ciphers and digests
++#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.
++ */
++static int *hw_cnids;
++static int *hw_dnids;
++#endif /* SOLARIS_HW_SLOT_SELECTION */
+
-+2007-10-15
-+- update for 0.9.8f version
-+- update for "6607670 teach pkcs#11 engine how to use keys be reference"
++/* PKCS#11 session caches and their locks for all operation types */
++static PK11_CACHE session_cache[OP_MAX];
+
-+2007-10-02
-+- draft for "6607670 teach pkcs#11 engine how to use keys be reference"
-+- draft for "6607307 pkcs#11 engine can't read RSA private keys"
++/*
++ * 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.
++ */
++#ifndef NOPTHREADS
++pthread_mutex_t *find_lock[OP_MAX] = { NULL };
++#endif
+
-+2007-09-26
-+- 6375348 Using pkcs11 as the SSLCryptoDevice with Apache/OpenSSL causes
-+ significant performance drop
-+- 6573196 memory is leaked when OpenSSL is used with PKCS#11 engine
++/*
++ * 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 };
+
-+2007-05-25
-+- 6558630 race in OpenSSL pkcs11 engine when using symetric block ciphers
++/*
++ * 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;
+
-+2007-05-19
-+- initial patch for 0.9.8e using latest OpenSolaris code
++/* 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)(void));
++static int pk11_destroy(ENGINE *e);
+
-+FAQs
-+====
++/* 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);
+
-+(1) my build failed on Linux distro with this error:
++/* 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);
+
-+../libcrypto.a(hw_pk11.o): In function `pk11_library_init':
-+hw_pk11.c:(.text+0x20f5): undefined reference to `pthread_atfork'
++/* 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);
+
-+ - don't use "no-threads" when configuring
-+ - if you didn't then OpenSSL failed to create a threaded library by
-+ default. You may manually edit Configure and try again. Look for the
-+ architecture that Configure printed, for example:
++#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
+
-+Configured for linux-elf.
++/* 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 session,
++ CK_OBJECT_HANDLE oh);
++static const char *get_PK11_LIBNAME(void);
++static void free_PK11_LIBNAME(void);
++static long set_PK11_LIBNAME(const char *name);
+
-+ - then edit Configure, find string "linux-elf" (inluding the quotes),
-+ and add flags to support threads to the 4th column of the 2nd string.
-+ If you build with GCC then adding "-pthread" should be enough. With
-+ "linux-elf" as an example, you would add " -pthread" right after
-+ "-D_REENTRANT", like this:
++/* Symmetric cipher and digest support functions */
++static int cipher_nid_to_pk11(int nid);
++#ifdef SOLARIS_AES_CTR
++static int pk11_add_NID(char *sn, char *ln);
++static int pk11_add_aes_ctr_NIDs(void);
++#endif /* SOLARIS_AES_CTR */
++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, unsigned int 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);
+
-+....-O3 -fomit-frame-pointer -Wall::-D_REENTRANT -pthread::-ldl:.....
++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,
++ CK_MECHANISM_TYPE mech, int *current_slot_n_cipher, int *local_cipher_nids,
++ int id);
++static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
++ CK_MECHANISM_TYPE mech, int *current_slot_n_digest, int *local_digest_nids,
++ int id);
+
++static int pk11_init_all_locks(void);
++static void pk11_free_all_locks(void);
+
-+Feedback
-+========
++#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 */
+
-+Please send feedback to security-discuss@opensolaris.org. The patch was
-+created by Jan.Pechanec@Sun.COM from code available in OpenSolaris.
++/* 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,
++#ifdef SOLARIS_AES_CTR
++ PK11_AES_128_CTR,
++ PK11_AES_192_CTR,
++ PK11_AES_256_CTR,
++#endif /* SOLARIS_AES_CTR */
++ PK11_CIPHER_MAX
++};
+
-+Latest version should be always available on http://blogs.sun.com/janp.
++/* Index for the supported digests */
++enum pk11_digest_id {
++ PK11_MD5,
++ PK11_SHA1,
++ PK11_SHA224,
++ PK11_SHA256,
++ PK11_SHA384,
++ PK11_SHA512,
++ PK11_DIGEST_MAX
++};
+
-Index: openssl/crypto/opensslconf.h
-diff -u openssl/crypto/opensslconf.h:1.1.3.1 openssl/crypto/opensslconf.h:1.5
---- openssl/crypto/opensslconf.h:1.1.3.1 Wed Mar 25 13:11:43 2009
-+++ openssl/crypto/opensslconf.h Fri Sep 4 10:43:21 2009
-@@ -38,6 +38,9 @@
-
- #endif /* OPENSSL_DOING_MAKEDEPEND */
-
-+#ifndef OPENSSL_THREADS
-+# define OPENSSL_THREADS
-+#endif
- #ifndef OPENSSL_NO_DYNAMIC_ENGINE
- # define OPENSSL_NO_DYNAMIC_ENGINE
- #endif
-@@ -79,6 +82,8 @@
- # endif
- #endif
-
-+#define OPENSSL_CPUID_OBJ
++#define TRY_OBJ_DESTROY(sess_hdl, 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(sess_hdl, obj_hdl); \
++ } \
++ if (uselock) \
++ UNLOCK_OBJSTORE(alg_type); \
++ }
+
- /* crypto/opensslconf.h.in */
-
- #ifdef OPENSSL_DOING_MAKEDEPEND
-@@ -140,7 +145,7 @@
- * This enables code handling data aligned at natural CPU word
- * boundary. See crypto/rc4/rc4_enc.c for further details.
- */
--#undef RC4_CHUNK
-+#define RC4_CHUNK unsigned long
- #endif
- #endif
-
-@@ -148,7 +153,7 @@
- /* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
- * %20 speed up (longs are 8 bytes, int's are 4). */
- #ifndef DES_LONG
--#define DES_LONG unsigned long
-+#define DES_LONG unsigned int
- #endif
- #endif
-
-@@ -162,9 +167,9 @@
- /* The prime number generation stuff may not work when
- * EIGHT_BIT but I don't care since I've only used this mode
- * for debuging the bignum libraries */
--#undef SIXTY_FOUR_BIT_LONG
-+#define SIXTY_FOUR_BIT_LONG
- #undef SIXTY_FOUR_BIT
--#define THIRTY_TWO_BIT
-+#undef THIRTY_TWO_BIT
- #undef SIXTEEN_BIT
- #undef EIGHT_BIT
- #endif
-@@ -178,7 +183,7 @@
-
- #if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
- #define CONFIG_HEADER_BF_LOCL_H
--#undef BF_PTR
-+#define BF_PTR2
- #endif /* HEADER_BF_LOCL_H */
-
- #if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
-@@ -208,7 +213,7 @@
- /* Unroll the inner loop, this sometimes helps, sometimes hinders.
- * Very mucy CPU dependant */
- #ifndef DES_UNROLL
--#undef DES_UNROLL
-+#define DES_UNROLL
- #endif
-
- /* These default values were supplied by
-Index: openssl/crypto/bio/bss_file.c
-diff -u openssl/crypto/bio/bss_file.c:1.1.3.1 openssl/crypto/bio/bss_file.c:1.4
---- openssl/crypto/bio/bss_file.c:1.1.3.1 Tue Dec 30 13:30:55 2008
-+++ openssl/crypto/bio/bss_file.c Fri Nov 27 12:32:32 2009
-@@ -125,7 +125,7 @@
- {
- SYSerr(SYS_F_FOPEN,get_last_sys_error());
- ERR_add_error_data(5,"fopen('",filename,"','",mode,"')");
-- if (errno == ENOENT)
-+ if ((errno == ENOENT) || ((*mode == 'r') && (errno == EACCES)))
- BIOerr(BIO_F_BIO_NEW_FILE,BIO_R_NO_SUCH_FILE);
- else
- BIOerr(BIO_F_BIO_NEW_FILE,ERR_R_SYS_LIB);
-Index: openssl/crypto/engine/Makefile
-diff -u openssl/crypto/engine/Makefile:1.1.3.1 openssl/crypto/engine/Makefile:1.5
---- openssl/crypto/engine/Makefile:1.1.3.1 Wed Sep 17 17:10:59 2008
-+++ openssl/crypto/engine/Makefile Mon Oct 5 13:16:50 2009
-@@ -21,12 +21,14 @@
- eng_table.c eng_pkey.c eng_fat.c eng_all.c \
- tb_rsa.c tb_dsa.c tb_ecdsa.c tb_dh.c tb_ecdh.c tb_rand.c tb_store.c \
- tb_cipher.c tb_digest.c \
-- eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c eng_padlock.c
-+ eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c eng_padlock.c \
-+ hw_pk11.c hw_pk11_pub.c hw_pk11so.c hw_pk11so_pub.c
- LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \
- eng_table.o eng_pkey.o eng_fat.o eng_all.o \
- tb_rsa.o tb_dsa.o tb_ecdsa.o tb_dh.o tb_ecdh.o tb_rand.o tb_store.o \
- tb_cipher.o tb_digest.o \
-- eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o eng_padlock.o
-+ eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o eng_padlock.o \
-+ hw_pk11.o hw_pk11_pub.o hw_pk11so.o hw_pk11so_pub.o
-
- SRC= $(LIBSRC)
-
-@@ -286,6 +288,102 @@
- eng_table.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
- eng_table.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
- eng_table.o: eng_table.c
-+hw_pk11.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-+hw_pk11.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
-+hw_pk11.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
-+hw_pk11.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-+hw_pk11.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
-+hw_pk11.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
-+hw_pk11.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
-+hw_pk11.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
-+hw_pk11.o: ../../include/openssl/ui.h ../../include/openssl/err.h
-+hw_pk11.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
-+hw_pk11.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
-+hw_pk11.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
-+hw_pk11.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
-+hw_pk11.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
-+hw_pk11.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
-+hw_pk11.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
-+hw_pk11.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
-+hw_pk11.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
-+hw_pk11.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
-+hw_pk11.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
-+hw_pk11.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
-+hw_pk11.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
-+hw_pk11.o: ../../include/openssl/pem2.h ../cryptlib.h
-+hw_pk11.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11.c
-+hw_pk11_pub.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-+hw_pk11_pub.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
-+hw_pk11_pub.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
-+hw_pk11_pub.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-+hw_pk11_pub.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
-+hw_pk11_pub.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
-+hw_pk11_pub.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
-+hw_pk11_pub.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
-+hw_pk11_pub.o: ../../include/openssl/ui.h ../../include/openssl/err.h
-+hw_pk11_pub.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
-+hw_pk11_pub.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
-+hw_pk11_pub.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
-+hw_pk11_pub.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
-+hw_pk11_pub.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
-+hw_pk11_pub.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
-+hw_pk11_pub.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
-+hw_pk11_pub.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
-+hw_pk11_pub.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
-+hw_pk11_pub.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
-+hw_pk11_pub.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
-+hw_pk11_pub.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
-+hw_pk11_pub.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
-+hw_pk11_pub.o: ../../include/openssl/pem2.h ../cryptlib.h
-+hw_pk11_pub.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11_pub.c
-+hw_pk11so.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-+hw_pk11so.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
-+hw_pk11so.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
-+hw_pk11so.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-+hw_pk11so.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
-+hw_pk11so.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
-+hw_pk11so.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
-+hw_pk11so.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
-+hw_pk11so.o: ../../include/openssl/ui.h ../../include/openssl/err.h
-+hw_pk11so.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
-+hw_pk11so.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
-+hw_pk11so.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
-+hw_pk11so.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
-+hw_pk11so.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
-+hw_pk11so.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
-+hw_pk11so.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
-+hw_pk11so.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
-+hw_pk11so.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
-+hw_pk11so.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
-+hw_pk11so.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
-+hw_pk11so.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
-+hw_pk11so.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
-+hw_pk11so.o: ../../include/openssl/pem2.h ../cryptlib.h
-+hw_pk11so.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11so.c
-+hw_pk11so_pub.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
-+hw_pk11so_pub.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
-+hw_pk11so_pub.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
-+hw_pk11so_pub.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
-+hw_pk11so_pub.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
-+hw_pk11so_pub.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
-+hw_pk11so_pub.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
-+hw_pk11so_pub.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
-+hw_pk11so_pub.o: ../../include/openssl/ui.h ../../include/openssl/err.h
-+hw_pk11so_pub.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
-+hw_pk11so_pub.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
-+hw_pk11so_pub.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
-+hw_pk11so_pub.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
-+hw_pk11so_pub.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
-+hw_pk11so_pub.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
-+hw_pk11so_pub.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
-+hw_pk11so_pub.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
-+hw_pk11so_pub.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
-+hw_pk11so_pub.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
-+hw_pk11so_pub.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
-+hw_pk11so_pub.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
-+hw_pk11so_pub.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
-+hw_pk11so_pub.o: ../../include/openssl/pem2.h ../cryptlib.h
-+hw_pk11so_pub.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11so_pub.c
- tb_cipher.o: ../../e_os.h ../../include/openssl/asn1.h
- tb_cipher.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
- tb_cipher.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
-Index: openssl/crypto/engine/cryptoki.h
-diff -u /dev/null openssl/crypto/engine/cryptoki.h:1.4
---- /dev/null Thu Dec 24 13:00:45 2009
-+++ openssl/crypto/engine/cryptoki.h Thu Dec 18 00:14:12 2008
-@@ -0,0 +1,103 @@
-+/*
-+ * CDDL HEADER START
-+ *
-+ * The contents of this file are subject to the terms of the
-+ * Common Development and Distribution License, Version 1.0 only
-+ * (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 2003 Sun Microsystems, Inc. All rights reserved.
-+ * Use is subject to license terms.
-+ */
-+
-+#ifndef _CRYPTOKI_H
-+#define _CRYPTOKI_H
-+
-+/* ident "@(#)cryptoki.h 1.2 05/06/08 SMI" */
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#ifndef CK_PTR
-+#define CK_PTR *
-+#endif
++#define TRY_OBJ_DELETE(sess_hdl, obj_hdl, retval, uselock, alg_type) \
++ { \
++ if (uselock) \
++ LOCK_OBJSTORE(alg_type); \
++ (void) pk11_active_delete(obj_hdl, alg_type); \
++ if (uselock) \
++ UNLOCK_OBJSTORE(alg_type); \
++ }
+
-+#ifndef CK_DEFINE_FUNCTION
-+#define CK_DEFINE_FUNCTION(returnType, name) returnType name
-+#endif
++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_recover = 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;
+
-+#ifndef CK_DECLARE_FUNCTION
-+#define CK_DECLARE_FUNCTION(returnType, name) returnType name
-+#endif
++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;
+
-+#ifndef CK_DECLARE_FUNCTION_POINTER
-+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
-+#endif
++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, },
++#ifdef SOLARIS_AES_CTR
++ /* we don't know the correct NIDs until the engine is initialized */
++ { PK11_AES_128_CTR, NID_undef, 16, 16, 16,
++ CKK_AES, CKM_AES_CTR, },
++ { PK11_AES_192_CTR, NID_undef, 16, 24, 24,
++ CKK_AES, CKM_AES_CTR, },
++ { PK11_AES_256_CTR, NID_undef, 16, 32, 32,
++ CKK_AES, CKM_AES_CTR, },
++#endif /* SOLARIS_AES_CTR */
++ };
+
-+#ifndef CK_CALLBACK_FUNCTION
-+#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
-+#endif
++typedef struct PK11_DIGEST_st
++ {
++ enum pk11_digest_id id;
++ int nid;
++ CK_MECHANISM_TYPE mech_type;
++ } PK11_DIGEST;
+
-+#ifndef NULL_PTR
-+#include <unistd.h> /* For NULL */
-+#define NULL_PTR NULL
-+#endif
++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, },
++ };
+
+/*
-+ * pkcs11t.h defines TRUE and FALSE in a way that upsets lint
++ * 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
+ */
-+#ifndef CK_DISABLE_TRUE_FALSE
-+#define CK_DISABLE_TRUE_FALSE
-+#ifndef TRUE
-+#define TRUE 1
-+#endif /* TRUE */
-+#ifndef FALSE
-+#define FALSE 0
-+#endif /* FALSE */
-+#endif /* CK_DISABLE_TRUE_FALSE */
-+
-+#undef CK_PKCS11_FUNCTION_INFO
-+
-+#include "pkcs11.h"
-+
-+/* Solaris specific functions */
++typedef struct PK11_CIPHER_STATE_st
++ {
++ PK11_SESSION *sp;
++ } PK11_CIPHER_STATE;
+
-+#include <stdlib.h>
+
+/*
-+ * SUNW_C_GetMechSession will initialize the framework and do all
-+ * the necessary PKCS#11 calls to create a session capable of
-+ * providing operations on the requested mechanism
-+ */
-+CK_RV SUNW_C_GetMechSession(CK_MECHANISM_TYPE mech,
-+ CK_SESSION_HANDLE_PTR hSession);
-+
-+/*
-+ * SUNW_C_KeyToObject will create a secret key object for the given
-+ * mechanism from the rawkey data.
++ * 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.
+ */
-+CK_RV SUNW_C_KeyToObject(CK_SESSION_HANDLE hSession,
-+ CK_MECHANISM_TYPE mech, const void *rawkey, size_t rawkey_len,
-+ CK_OBJECT_HANDLE_PTR obj);
-+
+
-+#ifdef __cplusplus
-+}
-+#endif
++/* 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
++ };
+
-+#endif /* _CRYPTOKI_H */
-Index: openssl/crypto/engine/eng_all.c
-diff -u openssl/crypto/engine/eng_all.c:1.1.3.1 openssl/crypto/engine/eng_all.c:1.3
---- openssl/crypto/engine/eng_all.c:1.1.3.1 Wed Jun 4 18:01:39 2008
-+++ openssl/crypto/engine/eng_all.c Mon Oct 5 13:16:50 2009
-@@ -110,6 +110,14 @@
- #if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
- ENGINE_load_capi();
- #endif
-+#ifndef OPENSSL_NO_HW_PKCS11
-+#ifndef OPENSSL_NO_HW_PKCS11CA
-+ ENGINE_load_pk11ca();
-+#endif
-+#ifndef OPENSSL_NO_HW_PKCS11SO
-+ ENGINE_load_pk11so();
-+#endif
-+#endif
- #endif
- }
-
-Index: openssl/crypto/engine/eng_list.c
-diff -u openssl/crypto/engine/eng_list.c:1.1.3.1 openssl/crypto/engine/eng_list.c:1.2
---- openssl/crypto/engine/eng_list.c:1.1.3.1 Sat Aug 6 10:34:35 2005
-+++ openssl/crypto/engine/eng_list.c Mon Oct 5 13:16:50 2009
-@@ -408,7 +408,11 @@
- !ENGINE_ctrl_cmd_string(iterator, "DIR_ADD",
- load_dir, 0) ||
- !ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0))
-+ {
-+ if (iterator)
-+ ENGINE_free(iterator);
- goto notfound;
-+ }
- return iterator;
- }
- notfound:
-Index: openssl/crypto/engine/engine.h
-diff -u openssl/crypto/engine/engine.h:1.1.3.1 openssl/crypto/engine/engine.h:1.3
---- openssl/crypto/engine/engine.h:1.1.3.1 Wed Jun 4 18:01:40 2008
-+++ openssl/crypto/engine/engine.h Mon Oct 5 13:16:50 2009
-@@ -337,6 +337,12 @@
- void ENGINE_load_ubsec(void);
- #endif
- void ENGINE_load_cryptodev(void);
-+#ifndef OPENSSL_NO_HW_PKCS11CA
-+void ENGINE_load_pk11ca(void);
-+#endif
-+#ifndef OPENSSL_NO_HW_PKCS11SO
-+void ENGINE_load_pk11so(void);
-+#endif
- void ENGINE_load_padlock(void);
- void ENGINE_load_builtin_engines(void);
- #ifndef OPENSSL_NO_CAPIENG
-Index: openssl/crypto/engine/hw_pk11.c
-diff -u /dev/null openssl/crypto/engine/hw_pk11.c:1.26
---- /dev/null Thu Dec 24 13:00:45 2009
-+++ openssl/crypto/engine/hw_pk11.c Mon Oct 5 13:16:50 2009
-@@ -0,0 +1,3927 @@
-+/*
-+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-+ * Use is subject to license terms.
-+ */
++/* 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
++ };
+
-+/* crypto/engine/hw_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
-+ * licensing@OpenSSL.org.
-+ *
-+ * 5. Products derived from this software may not be called "OpenSSL"
-+ * nor may "OpenSSL" appear in their names without prior written
-+ * permission of the OpenSSL Project.
-+ *
-+ * 6. Redistributions of any form whatsoever must retain the following
-+ * acknowledgment:
-+ * "This product includes software developed by the OpenSSL Project
-+ * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
-+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
-+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
-+ * OF THE POSSIBILITY OF SUCH DAMAGE.
-+ * ====================================================================
-+ *
-+ * This product includes cryptographic software written by Eric Young
-+ * (eay@cryptsoft.com). This product includes software written by Tim
-+ * Hudson (tjh@cryptsoft.com).
-+ *
++ * 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
++ };
+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <sys/types.h>
-+
-+#include <openssl/e_os2.h>
-+#include <openssl/crypto.h>
-+#include <cryptlib.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>
++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
++ };
+
-+#ifdef OPENSSL_SYS_WIN32
-+typedef int pid_t;
-+#define getpid() GetCurrentProcessId()
-+#define NOPTHREADS
-+#ifndef NULL_PTR
-+#define NULL_PTR NULL
-+#endif
-+#define CK_DEFINE_FUNCTION(returnType, name) \
-+ returnType __declspec(dllexport) name
-+#define CK_DECLARE_FUNCTION(returnType, name) \
-+ returnType __declspec(dllimport) name
-+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
-+ returnType __declspec(dllimport) (* name)
-+#else
-+#include <signal.h>
-+#include <unistd.h>
-+#include <dlfcn.h>
-+#endif
+
-+#ifndef NOPTHREADS
-+#include <pthread.h>
-+#endif
++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
++ };
+
-+#ifndef OPENSSL_NO_HW
-+#ifndef OPENSSL_NO_HW_PK11
-+#ifndef OPENSSL_NO_HW_PK11CA
++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
++ };
+
-+/* 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)
-+#undef SOLARIS_HW_SLOT_SELECTION
-+#endif
-+
-+/*
-+ * AES counter mode is not supported in the OpenSSL EVP API yet and neither
-+ * there are official OIDs for mechanisms based on this mode. With our changes,
-+ * an application can define its own EVP calls for AES counter mode and then
-+ * it can make use of hardware acceleration through this engine. However, it's
-+ * better if we keep AES CTR support code under ifdef's.
-+ */
-+#define SOLARIS_AES_CTR
-+
-+#ifdef OPENSSL_SYS_WIN32
-+#pragma pack(push, cryptoki, 1)
-+#include "cryptoki.h"
-+#include "pkcs11.h"
-+#pragma pack(pop, cryptoki)
-+#else
-+#include "cryptoki.h"
-+#include "pkcs11.h"
-+#endif
-+#include "hw_pk11ca.h"
-+#include "hw_pk11_err.c"
++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
++ };
+
-+#ifdef SOLARIS_AES_CTR
+/*
-+ * NIDs for AES counter mode that will be defined during the engine
-+ * initialization.
++ * ECB modes don't use IV so that's why set_asn1_parameters and
++ * get_asn1_parameters are set to NULL.
+ */
-+static int NID_aes_128_ctr = NID_undef;
-+static int NID_aes_192_ctr = NID_undef;
-+static int NID_aes_256_ctr = NID_undef;
-+#endif /* SOLARIS_AES_CTR */
++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
++ };
+
-+#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.
-+ */
-+static int *hw_cnids;
-+static int *hw_dnids;
-+#endif /* SOLARIS_HW_SLOT_SELECTION */
++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
++ };
+
-+/* PKCS#11 session caches and their locks for all operation types */
-+static PK11_CACHE session_cache[OP_MAX];
++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
++ };
+
++#ifdef SOLARIS_AES_CTR
+/*
-+ * 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.
++ * NID_undef's will be changed to the AES counter mode NIDs as soon they are
++ * created in pk11_library_init(). Note that the need to change these structures
++ * is the reason why we don't define them with the const keyword.
+ */
-+#ifndef NOPTHREADS
-+pthread_mutex_t *find_lock[OP_MAX] = { NULL };
-+#endif
++static EVP_CIPHER pk11_aes_128_ctr =
++ {
++ NID_undef,
++ 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
++ };
+
-+/*
-+ * 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 };
++static EVP_CIPHER pk11_aes_192_ctr =
++ {
++ NID_undef,
++ 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
++ };
+
-+/*
-+ * 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;
++static EVP_CIPHER pk11_aes_256_ctr =
++ {
++ NID_undef,
++ 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
++ };
++#endif /* SOLARIS_AES_CTR */
+
-+/* 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)(void));
-+static int pk11_destroy(ENGINE *e);
++static const EVP_CIPHER pk11_bf_cbc =
++ {
++ NID_bf_cbc,
++ 8, 16, 8,
++ EVP_CIPH_VARIABLE_LENGTH,
++ 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
++ };
+
-+/* 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);
++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
++ };
+
-+/* 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);
++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),
++ };
+
-+/* 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);
++static const EVP_MD pk11_sha1 =
++ {
++ NID_sha1,
++ NID_sha1WithRSAEncryption,
++ SHA_DIGEST_LENGTH,
++ 0,
++ 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),
++ };
+
-+#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 session,
-+ CK_OBJECT_HANDLE oh);
-+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);
-+#ifdef SOLARIS_AES_CTR
-+static int pk11_add_NID(char *sn, char *ln);
-+static int pk11_add_aes_ctr_NIDs(void);
-+#endif /* SOLARIS_AES_CTR */
-+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, unsigned int 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,
-+ CK_MECHANISM_TYPE mech, int *current_slot_n_cipher, int *local_cipher_nids,
-+ int id);
-+static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
-+ CK_MECHANISM_TYPE mech, int *current_slot_n_digest, int *local_digest_nids,
-+ int id);
-+
-+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 */
-+
-+/* 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,
-+#ifdef SOLARIS_AES_CTR
-+ PK11_AES_128_CTR,
-+ PK11_AES_192_CTR,
-+ PK11_AES_256_CTR,
-+#endif /* SOLARIS_AES_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
-+};
-+
-+#define TRY_OBJ_DESTROY(sess_hdl, 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(sess_hdl, obj_hdl); \
-+ } \
-+ if (uselock) \
-+ UNLOCK_OBJSTORE(alg_type); \
-+ }
-+
-+#define TRY_OBJ_DELETE(sess_hdl, obj_hdl, retval, uselock, alg_type) \
-+ { \
-+ if (uselock) \
-+ LOCK_OBJSTORE(alg_type); \
-+ (void) pk11_active_delete(obj_hdl, alg_type); \
-+ 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_recover = 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;
-+
-+typedef struct PK11_CIPHER_st
++static const EVP_MD pk11_sha224 =
+ {
-+ 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;
++ NID_sha224,
++ NID_sha224WithRSAEncryption,
++ SHA224_DIGEST_LENGTH,
++ 0,
++ 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 PK11_CIPHER ciphers[] =
++static const EVP_MD pk11_sha256 =
+ {
-+ { 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, },
-+#ifdef SOLARIS_AES_CTR
-+ /* we don't know the correct NIDs until the engine is initialized */
-+ { PK11_AES_128_CTR, NID_undef, 16, 16, 16,
-+ CKK_AES, CKM_AES_CTR, },
-+ { PK11_AES_192_CTR, NID_undef, 16, 24, 24,
-+ CKK_AES, CKM_AES_CTR, },
-+ { PK11_AES_256_CTR, NID_undef, 16, 32, 32,
-+ CKK_AES, CKM_AES_CTR, },
-+#endif /* SOLARIS_AES_CTR */
++ NID_sha256,
++ NID_sha256WithRSAEncryption,
++ SHA256_DIGEST_LENGTH,
++ 0,
++ 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),
+ };
+
-+typedef struct PK11_DIGEST_st
++static const EVP_MD pk11_sha384 =
+ {
-+ enum pk11_digest_id id;
-+ int nid;
-+ CK_MECHANISM_TYPE mech_type;
-+ } PK11_DIGEST;
++ NID_sha384,
++ NID_sha384WithRSAEncryption,
++ SHA384_DIGEST_LENGTH,
++ 0,
++ 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 PK11_DIGEST digests[] =
++static const EVP_MD pk11_sha512 =
+ {
-+ {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, },
++ NID_sha512,
++ NID_sha512WithRSAEncryption,
++ SHA512_DIGEST_LENGTH,
++ 0,
++ 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),
+ };
+
+/*
-+ * 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
++ * Initialization function. Sets up various PKCS#11 library components.
++ * The definitions for control commands specific to this engine
+ */
-+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 =
++#define PK11_CMD_SO_PATH ENGINE_CMD_BASE
++#define PK11_CMD_PIN (ENGINE_CMD_BASE+1)
++#define PK11_CMD_SLOT (ENGINE_CMD_BASE+2)
++static const ENGINE_CMD_DEFN pk11_cmd_defns[] =
+ {
-+ 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
++ {
++ PK11_CMD_SO_PATH,
++ "SO_PATH",
++ "Specifies the path to the 'pkcs#11' shared library",
++ ENGINE_CMD_FLAG_STRING
++ },
++ {
++ PK11_CMD_PIN,
++ "PIN",
++ "Specifies the pin code",
++ ENGINE_CMD_FLAG_STRING
++ },
++ {
++ PK11_CMD_SLOT,
++ "SLOT",
++ "Specifies the slot (default is auto select)",
++ ENGINE_CMD_FLAG_NUMERIC,
++ },
++ {0, NULL, NULL, 0}
+ };
+
-+/* 3DES CBC EVP */
-+static const EVP_CIPHER pk11_3des_cbc =
++
++static RAND_METHOD pk11_random =
+ {
-+ 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
++ pk11_rand_seed,
++ pk11_rand_bytes,
++ pk11_rand_cleanup,
++ pk11_rand_add,
++ pk11_rand_bytes,
++ pk11_rand_status
+ };
+
++
++/* Constants used when creating the ENGINE */
++#ifdef OPENSSL_NO_HW_PK11SO
++#error "can't load both crypto-accelerator and sign-only PKCS#11 engines"
++#endif
++static const char *engine_pk11_id = "pkcs11";
++static const char *engine_pk11_name =
++ "PKCS #11 engine support (crypto accelerator)";
++
++CK_FUNCTION_LIST_PTR pFuncList = NULL;
++static const char PK11_GET_FUNCTION_LIST[] = "C_GetFunctionList";
++
+/*
-+ * ECB modes don't use an Initial Vector so that's why set_asn1_parameters and
-+ * get_asn1_parameters fields are set to NULL.
++ * These is the static string constant for the DSO file name and the function
++ * symbol names to bind to.
+ */
-+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 char def_PK11_LIBNAME[] = PK11_LIB_LOCATION;
+
-+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 CK_BBOOL true = TRUE;
++static CK_BBOOL false = FALSE;
++static CK_SLOT_ID pubkey_SLOTID = 0;
++static CK_SLOT_ID rand_SLOTID = 0;
++static CK_SLOT_ID SLOTID = 0;
++char *pk11_pin = NULL;
++static CK_BBOOL pk11_library_initialized = FALSE;
++static CK_BBOOL pk11_atfork_initialized = FALSE;
++static int pk11_pid = 0;
+
++static DSO *pk11_dso = NULL;
+
-+static const EVP_CIPHER pk11_aes_128_cbc =
++/* allocate and initialize all locks used by the engine itself */
++static int pk11_init_all_locks(void)
+ {
-+ 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
-+ };
++#ifndef NOPTHREADS
++ int type;
+
-+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
-+ };
++#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 */
+
-+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
-+ };
++#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 */
+
-+/*
-+ * 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
-+ };
++#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 */
+
-+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
-+ };
++ 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);
++ }
+
-+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
-+ };
++ return (1);
+
-+#ifdef SOLARIS_AES_CTR
-+/*
-+ * NID_undef's will be changed to the AES counter mode NIDs as soon they are
-+ * created in pk11_library_init(). Note that the need to change these structures
-+ * is the reason why we don't define them with the const keyword.
-+ */
-+static EVP_CIPHER pk11_aes_128_ctr =
++malloc_err:
++ pk11_free_all_locks();
++ PK11err(PK11_F_INIT_ALL_LOCKS, PK11_R_MALLOC_FAILURE);
++ return (0);
++#else
++ return (1);
++#endif
++ }
++
++static void pk11_free_all_locks(void)
+ {
-+ NID_undef,
-+ 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
-+ };
++#ifndef NOPTHREADS
++ int type;
+
-+static EVP_CIPHER pk11_aes_192_ctr =
-+ {
-+ NID_undef,
-+ 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
-+ };
++#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 */
+
-+static EVP_CIPHER pk11_aes_256_ctr =
-+ {
-+ NID_undef,
-+ 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
-+ };
-+#endif /* SOLARIS_AES_CTR */
++ 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;
++ }
++ }
++#endif
++ }
+
-+static const EVP_CIPHER pk11_bf_cbc =
++/*
++ * This internal function is used by ENGINE_pk11() and "dynamic" ENGINE support.
++ */
++static int bind_pk11(ENGINE *e)
+ {
-+ NID_bf_cbc,
-+ 8, 16, 8,
-+ EVP_CIPH_VARIABLE_LENGTH,
-+ 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
-+ };
++#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);
+
-+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
-+ };
++ 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);
++#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);
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: registered RSA\n", PK11_DBG);
++#endif /* DEBUG_SLOT_SELECTION */
++ }
++#endif /* OPENSSL_NO_RSA */
++#ifndef OPENSSL_NO_DSA
++ if (pk11_have_dsa == CK_TRUE)
++ {
++ if (!ENGINE_set_DSA(e, PK11_DSA()))
++ return (0);
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: registered DSA\n", PK11_DBG);
++#endif /* DEBUG_SLOT_SELECTION */
++ }
++#endif /* OPENSSL_NO_DSA */
++#ifndef OPENSSL_NO_DH
++ if (pk11_have_dh == CK_TRUE)
++ {
++ if (!ENGINE_set_DH(e, PK11_DH()))
++ return (0);
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: registered DH\n", PK11_DBG);
++#endif /* DEBUG_SLOT_SELECTION */
++ }
++#endif /* OPENSSL_NO_DH */
++ if (pk11_have_random)
++ {
++ if (!ENGINE_set_RAND(e, &pk11_random))
++ return (0);
++#ifdef DEBUG_SLOT_SELECTION
++ fprintf(stderr, "%s: registered random\n", PK11_DBG);
++#endif /* DEBUG_SLOT_SELECTION */
++ }
++ 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);
+
-+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),
-+ };
++/*
++ * 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;
++ if (pk11_have_recover != CK_TRUE)
++ pk11_rsa->rsa_pub_dec = rsa->rsa_pub_dec;
++#endif /* OPENSSL_NO_RSA */
+
-+static const EVP_MD pk11_sha1 =
-+ {
-+ NID_sha1,
-+ NID_sha1WithRSAEncryption,
-+ SHA_DIGEST_LENGTH,
-+ 0,
-+ 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),
-+ };
++ /* Ensure the pk11 error handling is set up */
++ ERR_load_pk11_strings();
+
-+static const EVP_MD pk11_sha224 =
-+ {
-+ NID_sha224,
-+ NID_sha224WithRSAEncryption,
-+ SHA224_DIGEST_LENGTH,
-+ 0,
-+ 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),
-+ };
++ return (1);
++ }
+
-+static const EVP_MD pk11_sha256 =
++/* Dynamic engine support is disabled at a higher level for Solaris */
++#ifdef ENGINE_DYNAMIC_SUPPORT
++#error "dynamic engine not supported"
++static int bind_helper(ENGINE *e, const char *id)
+ {
-+ NID_sha256,
-+ NID_sha256WithRSAEncryption,
-+ SHA256_DIGEST_LENGTH,
-+ 0,
-+ 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),
-+ };
++ if (id && (strcmp(id, engine_pk11_id) != 0))
++ return (0);
+
-+static const EVP_MD pk11_sha384 =
-+ {
-+ NID_sha384,
-+ NID_sha384WithRSAEncryption,
-+ SHA384_DIGEST_LENGTH,
-+ 0,
-+ 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),
-+ };
++ if (!bind_pk11(e))
++ return (0);
+
-+static const EVP_MD pk11_sha512 =
-+ {
-+ NID_sha512,
-+ NID_sha512WithRSAEncryption,
-+ SHA512_DIGEST_LENGTH,
-+ 0,
-+ 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),
-+ };
++ return (1);
++ }
+
-+/*
-+ * 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
-+#define PK11_CMD_PIN (ENGINE_CMD_BASE+1)
-+#define PK11_CMD_SLOT (ENGINE_CMD_BASE+2)
-+static const ENGINE_CMD_DEFN pk11_cmd_defns[] =
++IMPLEMENT_DYNAMIC_CHECK_FN()
++IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
++
++#else
++static ENGINE *engine_pk11(void)
+ {
++ ENGINE *ret = ENGINE_new();
++
++ if (!ret)
++ return (NULL);
++
++ if (!bind_pk11(ret))
+ {
-+ PK11_CMD_SO_PATH,
-+ "SO_PATH",
-+ "Specifies the path to the 'pkcs#11' shared library",
-+ ENGINE_CMD_FLAG_STRING
-+ },
-+ {
-+ PK11_CMD_PIN,
-+ "PIN",
-+ "Specifies the pin code",
-+ ENGINE_CMD_FLAG_STRING
-+ },
-+ {
-+ PK11_CMD_SLOT,
-+ "SLOT",
-+ "Specifies the slot (default is auto select)",
-+ ENGINE_CMD_FLAG_NUMERIC,
-+ },
-+ {0, NULL, NULL, 0}
-+ };
++ ENGINE_free(ret);
++ return (NULL);
++ }
+
++ return (ret);
++ }
+
-+static RAND_METHOD pk11_random =
++void
++ENGINE_load_pk11(void)
+ {
-+ pk11_rand_seed,
-+ pk11_rand_bytes,
-+ pk11_rand_cleanup,
-+ pk11_rand_add,
-+ pk11_rand_bytes,
-+ pk11_rand_status
-+ };
++ ENGINE *e_pk11 = NULL;
+
++ /*
++ * Do not use dynamic PKCS#11 library on Solaris due to
++ * security reasons. We will link it in statically.
++ */
++ /* Attempt to load PKCS#11 library */
++ if (!pk11_dso)
++ pk11_dso = DSO_load(NULL, get_PK11_LIBNAME(), NULL, 0);
+
-+/* Constants used when creating the ENGINE */
-+#ifdef OPENSSL_NO_HW_PK11SO
-+#error "can't load both crypto-accelerator and sign-only PKCS#11 engines"
-+#endif
-+static const char *engine_pk11_id = "pkcs11";
-+static const char *engine_pk11_name =
-+ "PKCS #11 engine support (crypto accelerator)";
++ if (pk11_dso == NULL)
++ {
++ PK11err(PK11_F_LOAD, PK11_R_DSO_FAILURE);
++ return;
++ }
+
-+CK_FUNCTION_LIST_PTR pFuncList = NULL;
-+static const char PK11_GET_FUNCTION_LIST[] = "C_GetFunctionList";
++ e_pk11 = engine_pk11();
++ if (!e_pk11)
++ {
++ DSO_free(pk11_dso);
++ pk11_dso = NULL;
++ return;
++ }
++
++ /*
++ * At this point, the pk11 shared library is either dynamically
++ * loaded or statically linked in. So, initialize the pk11
++ * library before calling ENGINE_set_default since the latter
++ * needs cipher and digest algorithm information
++ */
++ if (!pk11_library_init(e_pk11))
++ {
++ DSO_free(pk11_dso);
++ pk11_dso = NULL;
++ ENGINE_free(e_pk11);
++ return;
++ }
++
++ ENGINE_add(e_pk11);
++
++ ENGINE_free(e_pk11);
++ ERR_clear_error();
++ }
++#endif /* ENGINE_DYNAMIC_SUPPORT */
+
+/*
-+ * These is the static string constant for the DSO file name and the function
-+ * symbol names to bind to.
++ * These are the static string constants for the DSO file name and
++ * the function symbol names to bind to.
+ */
-+static const char def_PK11_LIBNAME[] = PK11_LIB_LOCATION;
++static const char *PK11_LIBNAME = NULL;
+
-+static CK_BBOOL true = TRUE;
-+static CK_BBOOL false = FALSE;
-+static CK_SLOT_ID pubkey_SLOTID = 0;
-+static CK_SLOT_ID rand_SLOTID = 0;
-+static CK_SLOT_ID SLOTID = 0;
-+char *pk11_pin = NULL;
-+static CK_BBOOL pk11_library_initialized = FALSE;
-+static CK_BBOOL pk11_atfork_initialized = FALSE;
-+static int pk11_pid = 0;
++static const char *get_PK11_LIBNAME(void)
++ {
++ if (PK11_LIBNAME)
++ return (PK11_LIBNAME);
+
-+static DSO *pk11_dso = NULL;
++ return (def_PK11_LIBNAME);
++ }
+
-+/* allocate and initialize all locks used by the engine itself */
-+static int pk11_init_all_locks(void)
++static void free_PK11_LIBNAME(void)
+ {
-+#ifndef NOPTHREADS
-+ int type;
++ if (PK11_LIBNAME)
++ OPENSSL_free((void*)PK11_LIBNAME);
+
-+#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 */
++ PK11_LIBNAME = 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 */
++static long set_PK11_LIBNAME(const char *name)
++ {
++ free_PK11_LIBNAME();
+
-+#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 */
++ return ((PK11_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
++ }
+
-+ 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);
-+ }
++/* acquire all engine specific mutexes before fork */
++static void pk11_fork_prepare(void)
++ {
++#ifndef NOPTHREADS
++ int i;
+
-+ return (1);
++ if (!pk11_library_initialized)
++ return;
+
-+malloc_err:
-+ pk11_free_all_locks();
-+ PK11err(PK11_F_INIT_ALL_LOCKS, PK11_R_MALLOC_FAILURE);
-+ return (0);
-+#else
-+ return (1);
++ LOCK_OBJSTORE(OP_RSA);
++ LOCK_OBJSTORE(OP_DSA);
++ LOCK_OBJSTORE(OP_DH);
++ for (i = 0; i < OP_MAX; i++)
++ {
++ (void) pthread_mutex_lock(session_cache[i].lock);
++ }
+#endif
+ }
+
-+static void pk11_free_all_locks(void)
++/* release all engine specific mutexes */
++static void pk11_fork_parent(void)
+ {
+#ifndef NOPTHREADS
-+ int type;
++ int i;
+
-+#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 */
++ if (!pk11_library_initialized)
++ return;
+
-+ for (type = 0; type < OP_MAX; type++)
++ for (i = OP_MAX - 1; i >= 0; i--)
+ {
-+ 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;
-+ }
++ (void) pthread_mutex_unlock(session_cache[i].lock);
+ }
++ UNLOCK_OBJSTORE(OP_DH);
++ UNLOCK_OBJSTORE(OP_DSA);
++ UNLOCK_OBJSTORE(OP_RSA);
+#endif
+ }
+
+/*
-+ * This internal function is used by ENGINE_pk11() and "dynamic" ENGINE support.
++ * same situation as in parent - we need to unlock all locks to make them
++ * accessible to all threads.
+ */
-+static int bind_pk11(ENGINE *e)
++static void pk11_fork_child(void)
+ {
-+#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);
-+#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);
-+#ifdef DEBUG_SLOT_SELECTION
-+ fprintf(stderr, "%s: registered RSA\n", PK11_DBG);
-+#endif /* DEBUG_SLOT_SELECTION */
-+ }
-+#endif /* OPENSSL_NO_RSA */
-+#ifndef OPENSSL_NO_DSA
-+ if (pk11_have_dsa == CK_TRUE)
-+ {
-+ if (!ENGINE_set_DSA(e, PK11_DSA()))
-+ return (0);
-+#ifdef DEBUG_SLOT_SELECTION
-+ fprintf(stderr, "%s: registered DSA\n", PK11_DBG);
-+#endif /* DEBUG_SLOT_SELECTION */
-+ }
-+#endif /* OPENSSL_NO_DSA */
-+#ifndef OPENSSL_NO_DH
-+ if (pk11_have_dh == CK_TRUE)
-+ {
-+ if (!ENGINE_set_DH(e, PK11_DH()))
-+ return (0);
-+#ifdef DEBUG_SLOT_SELECTION
-+ fprintf(stderr, "%s: registered DH\n", PK11_DBG);
-+#endif /* DEBUG_SLOT_SELECTION */
-+ }
-+#endif /* OPENSSL_NO_DH */
-+ if (pk11_have_random)
-+ {
-+ if (!ENGINE_set_RAND(e, &pk11_random))
-+ return (0);
-+#ifdef DEBUG_SLOT_SELECTION
-+ fprintf(stderr, "%s: registered random\n", PK11_DBG);
-+#endif /* DEBUG_SLOT_SELECTION */
-+ }
-+ 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;
-+ if (pk11_have_recover != CK_TRUE)
-+ pk11_rsa->rsa_pub_dec = rsa->rsa_pub_dec;
-+#endif /* OPENSSL_NO_RSA */
-+
-+ /* Ensure the pk11 error handling is set up */
-+ ERR_load_pk11_strings();
-+
-+ return (1);
-+ }
-+
-+/* Dynamic engine support is disabled at a higher level for Solaris */
-+#ifdef ENGINE_DYNAMIC_SUPPORT
-+#error "dynamic engine not supported"
-+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)
-+
-+#else
-+static ENGINE *engine_pk11(void)
-+ {
-+ ENGINE *ret = ENGINE_new();
-+
-+ if (!ret)
-+ return (NULL);
-+
-+ if (!bind_pk11(ret))
-+ {
-+ ENGINE_free(ret);
-+ return (NULL);
-+ }
-+
-+ return (ret);
-+ }
-+
-+void
-+ENGINE_load_pk11(void)
-+ {
-+ ENGINE *e_pk11 = NULL;
-+
-+ /*
-+ * Do not use dynamic PKCS#11 library on Solaris due to
-+ * security reasons. We will link it in statically.
-+ */
-+ /* 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);
-+ return;
-+ }
-+
-+ e_pk11 = engine_pk11();
-+ if (!e_pk11)
-+ {
-+ DSO_free(pk11_dso);
-+ pk11_dso = NULL;
-+ return;
-+ }
-+
-+ /*
-+ * At this point, the pk11 shared library is either dynamically
-+ * loaded or statically linked in. So, initialize the pk11
-+ * library before calling ENGINE_set_default since the latter
-+ * needs cipher and digest algorithm information
-+ */
-+ if (!pk11_library_init(e_pk11))
-+ {
-+ DSO_free(pk11_dso);
-+ pk11_dso = NULL;
-+ ENGINE_free(e_pk11);
-+ return;
-+ }
-+
-+ ENGINE_add(e_pk11);
-+
-+ ENGINE_free(e_pk11);
-+ ERR_clear_error();
-+ }
-+#endif /* ENGINE_DYNAMIC_SUPPORT */
-+
-+/*
-+ * 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)
-+ {
-+#ifndef NOPTHREADS
-+ int i;
-+
-+ if (!pk11_library_initialized)
-+ return;
-+
-+ LOCK_OBJSTORE(OP_RSA);
-+ LOCK_OBJSTORE(OP_DSA);
-+ LOCK_OBJSTORE(OP_DH);
-+ for (i = 0; i < OP_MAX; i++)
-+ {
-+ (void) pthread_mutex_lock(session_cache[i].lock);
-+ }
-+#endif
-+ }
-+
-+/* release all engine specific mutexes */
-+static void pk11_fork_parent(void)
-+ {
-+#ifndef NOPTHREADS
-+ 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);
-+#endif
-+ }
-+
-+/*
-+ * same situation as in parent - we need to unlock all locks to make them
-+ * accessible to all threads.
-+ */
-+static void pk11_fork_child(void)
-+ {
-+#ifndef NOPTHREADS
-+ int i;
-+
++#ifndef NOPTHREADS
++ int i;
++
+ if (!pk11_library_initialized)
+ return;
+
+#endif /* OPENSSL_NO_HW_PK11CA */
+#endif /* OPENSSL_NO_HW_PK11 */
+#endif /* OPENSSL_NO_HW */
-Index: openssl/crypto/engine/hw_pk11_err.c
-diff -u /dev/null openssl/crypto/engine/hw_pk11_err.c:1.4
---- /dev/null Thu Dec 24 13:00:45 2009
-+++ openssl/crypto/engine/hw_pk11_err.c Wed Dec 17 16:14:26 2008
-@@ -0,0 +1,259 @@
-+/*
-+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
-+ * Use is subject to license terms.
-+ */
+Index: openssl-0.9.8s/crypto/engine/hw_pk11ca.h
+diff -Nur openssl-0.9.8s/crypto/engine/hw_pk11ca.h openssl-0.9.8s-patched/crypto/engine/hw_pk11ca.h
+--- openssl-0.9.8s/crypto/engine/hw_pk11ca.h 1969-12-31 16:00:00.000000000 -0800
++++ openssl-0.9.8s-patched/crypto/engine/hw_pk11ca.h 2012-01-11 12:03:30.021809298 -0800
+@@ -0,0 +1,28 @@
++/* Redefine all pk11/PK11 external symbols to pk11ca/PK11CA */
+
-+/* crypto/engine/hw_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:
++#define find_lock pk11ca_find_lock
++#define active_list pk11ca_active_list
++#define ERR_pk11_error ERR_pk11ca_error
++#define PK11err_add_data PK11CAerr_add_data
++#define pk11_get_session pk11ca_get_session
++#define pk11_return_session pk11ca_return_session
++#define pk11_active_add pk11ca_active_add
++#define pk11_active_delete pk11ca_active_delete
++#define pk11_active_remove pk11ca_active_remove
++#define pk11_free_active_list pk11ca_free_active_list
++#define pk11_destroy_rsa_key_objects pk11ca_destroy_rsa_key_objects
++#define pk11_destroy_rsa_object_pub pk11ca_destroy_rsa_object_pub
++#define pk11_destroy_rsa_object_priv pk11ca_destroy_rsa_object_priv
++#define pk11_load_privkey pk11ca_load_privkey
++#define pk11_load_pubkey pk11ca_load_pubkey
++#define PK11_RSA PK11CA_RSA
++#define pk11_destroy_dsa_key_objects pk11ca_destroy_dsa_key_objects
++#define pk11_destroy_dsa_object_pub pk11ca_destroy_dsa_object_pub
++#define pk11_destroy_dsa_object_priv pk11ca_destroy_dsa_object_priv
++#define PK11_DSA PK11CA_DSA
++#define pk11_destroy_dh_key_objects pk11ca_destroy_dh_key_objects
++#define pk11_destroy_dh_object pk11ca_destroy_dh_object
++#define PK11_DH PK11CA_DH
++#define pFuncList pk11ca_pFuncList
++#define pk11_pin pk11ca_pin
++#define ENGINE_load_pk11 ENGINE_load_pk11ca
+Index: openssl-0.9.8s/crypto/engine/hw_pk11_err.c
+diff -Nur openssl-0.9.8s/crypto/engine/hw_pk11_err.c openssl-0.9.8s-patched/crypto/engine/hw_pk11_err.c
+--- openssl-0.9.8s/crypto/engine/hw_pk11_err.c 1969-12-31 16:00:00.000000000 -0800
++++ openssl-0.9.8s-patched/crypto/engine/hw_pk11_err.c 2012-01-11 12:03:30.021809298 -0800
+@@ -0,0 +1,259 @@
++/*
++ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
++ * Use is subject to license terms.
++ */
++
++/* crypto/engine/hw_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.
+ (void) BIO_snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
+ ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
+}
-Index: openssl/crypto/engine/hw_pk11_err.h
-diff -u /dev/null openssl/crypto/engine/hw_pk11_err.h:1.9
---- /dev/null Thu Dec 24 13:00:45 2009
-+++ openssl/crypto/engine/hw_pk11_err.h Wed Dec 17 15:01:45 2008
+Index: openssl-0.9.8s/crypto/engine/hw_pk11_err.h
+diff -Nur openssl-0.9.8s/crypto/engine/hw_pk11_err.h openssl-0.9.8s-patched/crypto/engine/hw_pk11_err.h
+--- openssl-0.9.8s/crypto/engine/hw_pk11_err.h 1969-12-31 16:00:00.000000000 -0800
++++ openssl-0.9.8s-patched/crypto/engine/hw_pk11_err.h 2012-01-11 12:03:30.021809298 -0800
@@ -0,0 +1,402 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+extern CK_FUNCTION_LIST_PTR pFuncList;
+
+#endif /* HW_PK11_ERR_H */
-Index: openssl/crypto/engine/hw_pk11_pub.c
-diff -u /dev/null openssl/crypto/engine/hw_pk11_pub.c:1.32
---- /dev/null Thu Dec 24 13:00:45 2009
-+++ openssl/crypto/engine/hw_pk11_pub.c Mon Oct 5 13:16:55 2009
+Index: openssl-0.9.8s/crypto/engine/hw_pk11_pub.c
+diff -Nur openssl-0.9.8s/crypto/engine/hw_pk11_pub.c openssl-0.9.8s-patched/crypto/engine/hw_pk11_pub.c
+--- openssl-0.9.8s/crypto/engine/hw_pk11_pub.c 1969-12-31 16:00:00.000000000 -0800
++++ openssl-0.9.8s-patched/crypto/engine/hw_pk11_pub.c 2012-01-11 12:03:30.021809298 -0800
@@ -0,0 +1,3140 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+#endif /* OPENSSL_NO_HW_PK11CA */
+#endif /* OPENSSL_NO_HW_PK11 */
+#endif /* OPENSSL_NO_HW */
-Index: openssl/crypto/engine/hw_pk11ca.h
-diff -u /dev/null openssl/crypto/engine/hw_pk11ca.h:1.2
---- /dev/null Thu Dec 24 13:00:45 2009
-+++ openssl/crypto/engine/hw_pk11ca.h Mon Oct 5 13:17:03 2009
-@@ -0,0 +1,28 @@
-+/* Redefine all pk11/PK11 external symbols to pk11ca/PK11CA */
-+
-+#define find_lock pk11ca_find_lock
-+#define active_list pk11ca_active_list
-+#define ERR_pk11_error ERR_pk11ca_error
-+#define PK11err_add_data PK11CAerr_add_data
-+#define pk11_get_session pk11ca_get_session
-+#define pk11_return_session pk11ca_return_session
-+#define pk11_active_add pk11ca_active_add
-+#define pk11_active_delete pk11ca_active_delete
-+#define pk11_active_remove pk11ca_active_remove
-+#define pk11_free_active_list pk11ca_free_active_list
-+#define pk11_destroy_rsa_key_objects pk11ca_destroy_rsa_key_objects
-+#define pk11_destroy_rsa_object_pub pk11ca_destroy_rsa_object_pub
-+#define pk11_destroy_rsa_object_priv pk11ca_destroy_rsa_object_priv
-+#define pk11_load_privkey pk11ca_load_privkey
-+#define pk11_load_pubkey pk11ca_load_pubkey
-+#define PK11_RSA PK11CA_RSA
-+#define pk11_destroy_dsa_key_objects pk11ca_destroy_dsa_key_objects
-+#define pk11_destroy_dsa_object_pub pk11ca_destroy_dsa_object_pub
-+#define pk11_destroy_dsa_object_priv pk11ca_destroy_dsa_object_priv
-+#define PK11_DSA PK11CA_DSA
-+#define pk11_destroy_dh_key_objects pk11ca_destroy_dh_key_objects
-+#define pk11_destroy_dh_object pk11ca_destroy_dh_object
-+#define PK11_DH PK11CA_DH
-+#define pFuncList pk11ca_pFuncList
-+#define pk11_pin pk11ca_pin
-+#define ENGINE_load_pk11 ENGINE_load_pk11ca
-Index: openssl/crypto/engine/hw_pk11so.c
-diff -u /dev/null openssl/crypto/engine/hw_pk11so.c:1.2
---- /dev/null Thu Dec 24 13:00:46 2009
-+++ openssl/crypto/engine/hw_pk11so.c Mon Oct 5 13:17:03 2009
+Index: openssl-0.9.8s/crypto/engine/hw_pk11so.c
+diff -Nur openssl-0.9.8s/crypto/engine/hw_pk11so.c openssl-0.9.8s-patched/crypto/engine/hw_pk11so.c
+--- openssl-0.9.8s/crypto/engine/hw_pk11so.c 1969-12-31 16:00:00.000000000 -0800
++++ openssl-0.9.8s-patched/crypto/engine/hw_pk11so.c 2012-01-11 12:03:30.021809298 -0800
@@ -0,0 +1,1618 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+#endif /* OPENSSL_NO_HW_PK11SO */
+#endif /* OPENSSL_NO_HW_PK11 */
+#endif /* OPENSSL_NO_HW */
-Index: openssl/crypto/engine/hw_pk11so.h
-diff -u /dev/null openssl/crypto/engine/hw_pk11so.h:1.2
---- /dev/null Thu Dec 24 13:00:46 2009
-+++ openssl/crypto/engine/hw_pk11so.h Mon Oct 5 13:17:03 2009
+Index: openssl-0.9.8s/crypto/engine/hw_pk11so.h
+diff -Nur openssl-0.9.8s/crypto/engine/hw_pk11so.h openssl-0.9.8s-patched/crypto/engine/hw_pk11so.h
+--- openssl-0.9.8s/crypto/engine/hw_pk11so.h 1969-12-31 16:00:00.000000000 -0800
++++ openssl-0.9.8s-patched/crypto/engine/hw_pk11so.h 2012-01-11 12:03:30.031811760 -0800
@@ -0,0 +1,28 @@
+/* Redefine all pk11/PK11 external symbols to pk11so/PK11SO */
+
+#define pFuncList pk11so_pFuncList
+#define pk11_pin pk11so_pin
+#define ENGINE_load_pk11 ENGINE_load_pk11so
-Index: openssl/crypto/engine/hw_pk11so_pub.c
-diff -u /dev/null openssl/crypto/engine/hw_pk11so_pub.c:1.2
---- /dev/null Thu Dec 24 13:00:46 2009
-+++ openssl/crypto/engine/hw_pk11so_pub.c Mon Oct 5 13:17:03 2009
+Index: openssl-0.9.8s/crypto/engine/hw_pk11so_pub.c
+diff -Nur openssl-0.9.8s/crypto/engine/hw_pk11so_pub.c openssl-0.9.8s-patched/crypto/engine/hw_pk11so_pub.c
+--- openssl-0.9.8s/crypto/engine/hw_pk11so_pub.c 1969-12-31 16:00:00.000000000 -0800
++++ openssl-0.9.8s-patched/crypto/engine/hw_pk11so_pub.c 2012-01-11 12:03:30.031811760 -0800
@@ -0,0 +1,899 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ rsa = RSA_new_method(e);
+ if (rsa == NULL) {
+ EVP_PKEY_free(pkey);
-+ pkey = NULL;
-+ goto err;
-+ }
-+ EVP_PKEY_assign_RSA(pkey, rsa);
-+
-+ if (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;
-+ }
-+
-+ (void) check_new_rsa_key_pub(sp, rsa);
-+ sp->opdata_rsa_pub = rsa;
-+
-+ attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
-+ attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
-+ }
-+ else if ((pubkey = fopen(pubkey_file, read_mode_flags)) != NULL)
-+ {
-+ pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL);
-+ (void) fclose(pubkey);
-+ }
-+
-+err:
-+ if (sp != NULL)
-+ pk11_return_session(sp, OP_RSA);
-+ return (pkey);
-+ }
-+
-+/*
-+ * Create a private key object in the session from a given rsa structure.
-+ * The *rsa_d_num pointer is non-NULL for RSA private keys.
-+ */
-+static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA *rsa,
-+ RSA **key_ptr, BIGNUM **rsa_d_num, CK_SESSION_HANDLE session)
-+ {
-+ CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
-+
-+ if ((rsa->flags & RSA_FLAG_EXT_PKEY) == 0) {
-+ PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_INCONSISTENT_KEY);
-+ return (h_key);
-+ }
-+
-+ h_key = (CK_OBJECT_HANDLE)RSA_get_ex_data(rsa, hndidx_rsa);
-+ (void) pk11_active_add(h_key, OP_RSA);
-+ if (key_ptr != NULL)
-+ *key_ptr = rsa;
-+ if (rsa_d_num != NULL)
-+ {
-+ if (rsa->d == NULL)
-+ *rsa_d_num = NULL;
-+ else if ((*rsa_d_num = BN_dup(rsa->d)) == NULL)
-+ {
-+ PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
-+ return (h_key);
-+ }
-+ }
-+ 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_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.
-+ */
-+ 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))
-+ {
-+ /*
-+ * 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_pub(sp, 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_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa)
-+ {
-+ /*
-+ * Provide protection against RSA structure reuse by making the
-+ * check for cache hit stronger. Comparing private exponent of RSA
-+ * key with value cached in PK11_SESSION structure should
-+ * be sufficient.
-+ */
-+ if ((sp->opdata_rsa_priv != rsa) ||
-+ (BN_cmp(sp->opdata_rsa_d_num, rsa->d) != 0) ||
-+ ((rsa->flags & RSA_FLAG_EXT_PKEY) != 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_rsa_object_priv(sp, TRUE);
-+ return (0);
-+ }
-+ 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);
-+ }
-+ }
-+
-+#ifdef OPENSSL_SYS_WIN32
-+char *getpassphrase(const char *prompt)
-+ {
-+ static char buf[128];
-+ HANDLE h;
-+ DWORD cc, mode;
-+ int cnt;
-+
-+ h = GetStdHandle(STD_INPUT_HANDLE);
-+ fputs(prompt, stderr);
-+ fflush(stderr);
-+ fflush(stdout);
-+ FlushConsoleInputBuffer(h);
-+ GetConsoleMode(h, &mode);
-+ SetConsoleMode(h, ENABLE_PROCESSED_INPUT);
-+
-+ for (cnt = 0; cnt < sizeof(buf) - 1; cnt++)
-+ {
-+ ReadFile(h, buf + cnt, 1, &cc, NULL);
-+ if (buf[cnt] == '\r')
-+ break;
-+ fputc('*', stdout);
-+ fflush(stderr);
-+ fflush(stdout);
-+ }
-+
-+ SetConsoleMode(h, mode);
-+ buf[cnt] = '\0';
-+ fputs("\n", stderr);
-+ return buf;
-+ }
-+#endif /* OPENSSL_SYS_WIN32 */
-+#endif /* OPENSSL_NO_HW_PK11SO */
-+#endif /* OPENSSL_NO_HW_PK11 */
-+#endif /* OPENSSL_NO_HW */
-Index: openssl/crypto/engine/pkcs11.h
-diff -u /dev/null openssl/crypto/engine/pkcs11.h:1.1.1.1
---- /dev/null Thu Dec 24 13:00:46 2009
-+++ openssl/crypto/engine/pkcs11.h Wed Oct 24 23:27:09 2007
-@@ -0,0 +1,299 @@
-+/* pkcs11.h include file for PKCS #11. */
-+/* $Revision: 1.2 $ */
-+
-+/* License to copy and use this software is granted provided that it is
-+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
-+ * (Cryptoki)" in all material mentioning or referencing this software.
-+
-+ * License is also granted to make and use derivative works provided that
-+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
-+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
-+ * referencing the derived work.
-+
-+ * RSA Security Inc. makes no representations concerning either the
-+ * merchantability of this software or the suitability of this software for
-+ * any particular purpose. It is provided "as is" without express or implied
-+ * warranty of any kind.
-+ */
-+
-+#ifndef _PKCS11_H_
-+#define _PKCS11_H_ 1
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/* Before including this file (pkcs11.h) (or pkcs11t.h by
-+ * itself), 6 platform-specific macros must be defined. These
-+ * macros are described below, and typical definitions for them
-+ * are also given. Be advised that these definitions can depend
-+ * on both the platform and the compiler used (and possibly also
-+ * on whether a Cryptoki library is linked statically or
-+ * dynamically).
-+ *
-+ * In addition to defining these 6 macros, the packing convention
-+ * for Cryptoki structures should be set. The Cryptoki
-+ * convention on packing is that structures should be 1-byte
-+ * aligned.
-+ *
-+ * If you're using Microsoft Developer Studio 5.0 to produce
-+ * Win32 stuff, this might be done by using the following
-+ * preprocessor directive before including pkcs11.h or pkcs11t.h:
-+ *
-+ * #pragma pack(push, cryptoki, 1)
-+ *
-+ * and using the following preprocessor directive after including
-+ * pkcs11.h or pkcs11t.h:
-+ *
-+ * #pragma pack(pop, cryptoki)
-+ *
-+ * If you're using an earlier version of Microsoft Developer
-+ * Studio to produce Win16 stuff, this might be done by using
-+ * the following preprocessor directive before including
-+ * pkcs11.h or pkcs11t.h:
-+ *
-+ * #pragma pack(1)
-+ *
-+ * In a UNIX environment, you're on your own for this. You might
-+ * not need to do (or be able to do!) anything.
-+ *
-+ *
-+ * Now for the macros:
-+ *
-+ *
-+ * 1. CK_PTR: The indirection string for making a pointer to an
-+ * object. It can be used like this:
-+ *
-+ * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
-+ *
-+ * If you're using Microsoft Developer Studio 5.0 to produce
-+ * Win32 stuff, it might be defined by:
-+ *
-+ * #define CK_PTR *
-+ *
-+ * If you're using an earlier version of Microsoft Developer
-+ * Studio to produce Win16 stuff, it might be defined by:
-+ *
-+ * #define CK_PTR far *
-+ *
-+ * In a typical UNIX environment, it might be defined by:
-+ *
-+ * #define CK_PTR *
-+ *
-+ *
-+ * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
-+ * an exportable Cryptoki library function definition out of a
-+ * return type and a function name. It should be used in the
-+ * following fashion to define the exposed Cryptoki functions in
-+ * a Cryptoki library:
-+ *
-+ * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
-+ * CK_VOID_PTR pReserved
-+ * )
-+ * {
-+ * ...
-+ * }
-+ *
-+ * If you're using Microsoft Developer Studio 5.0 to define a
-+ * function in a Win32 Cryptoki .dll, it might be defined by:
-+ *
-+ * #define CK_DEFINE_FUNCTION(returnType, name) \
-+ * returnType __declspec(dllexport) name
-+ *
-+ * If you're using an earlier version of Microsoft Developer
-+ * Studio to define a function in a Win16 Cryptoki .dll, it
-+ * might be defined by:
-+ *
-+ * #define CK_DEFINE_FUNCTION(returnType, name) \
-+ * returnType __export _far _pascal name
-+ *
-+ * In a UNIX environment, it might be defined by:
-+ *
-+ * #define CK_DEFINE_FUNCTION(returnType, name) \
-+ * returnType name
-+ *
-+ *
-+ * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
-+ * an importable Cryptoki library function declaration out of a
-+ * return type and a function name. It should be used in the
-+ * following fashion:
-+ *
-+ * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
-+ * CK_VOID_PTR pReserved
-+ * );
-+ *
-+ * If you're using Microsoft Developer Studio 5.0 to declare a
-+ * function in a Win32 Cryptoki .dll, it might be defined by:
-+ *
-+ * #define CK_DECLARE_FUNCTION(returnType, name) \
-+ * returnType __declspec(dllimport) name
-+ *
-+ * If you're using an earlier version of Microsoft Developer
-+ * Studio to declare a function in a Win16 Cryptoki .dll, it
-+ * might be defined by:
-+ *
-+ * #define CK_DECLARE_FUNCTION(returnType, name) \
-+ * returnType __export _far _pascal name
-+ *
-+ * In a UNIX environment, it might be defined by:
-+ *
-+ * #define CK_DECLARE_FUNCTION(returnType, name) \
-+ * returnType name
-+ *
-+ *
-+ * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
-+ * which makes a Cryptoki API function pointer declaration or
-+ * function pointer type declaration out of a return type and a
-+ * function name. It should be used in the following fashion:
-+ *
-+ * // Define funcPtr to be a pointer to a Cryptoki API function
-+ * // taking arguments args and returning CK_RV.
-+ * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
-+ *
-+ * or
-+ *
-+ * // Define funcPtrType to be the type of a pointer to a
-+ * // Cryptoki API function taking arguments args and returning
-+ * // CK_RV, and then define funcPtr to be a variable of type
-+ * // funcPtrType.
-+ * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
-+ * funcPtrType funcPtr;
-+ *
-+ * If you're using Microsoft Developer Studio 5.0 to access
-+ * functions in a Win32 Cryptoki .dll, in might be defined by:
-+ *
-+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
-+ * returnType __declspec(dllimport) (* name)
-+ *
-+ * If you're using an earlier version of Microsoft Developer
-+ * Studio to access functions in a Win16 Cryptoki .dll, it might
-+ * be defined by:
-+ *
-+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
-+ * returnType __export _far _pascal (* name)
-+ *
-+ * In a UNIX environment, it might be defined by:
-+ *
-+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
-+ * returnType (* name)
-+ *
-+ *
-+ * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
-+ * a function pointer type for an application callback out of
-+ * a return type for the callback and a name for the callback.
-+ * It should be used in the following fashion:
-+ *
-+ * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
-+ *
-+ * to declare a function pointer, myCallback, to a callback
-+ * which takes arguments args and returns a CK_RV. It can also
-+ * be used like this:
-+ *
-+ * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
-+ * myCallbackType myCallback;
-+ *
-+ * If you're using Microsoft Developer Studio 5.0 to do Win32
-+ * Cryptoki development, it might be defined by:
-+ *
-+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
-+ * returnType (* name)
-+ *
-+ * If you're using an earlier version of Microsoft Developer
-+ * Studio to do Win16 development, it might be defined by:
-+ *
-+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
-+ * returnType _far _pascal (* name)
-+ *
-+ * In a UNIX environment, it might be defined by:
-+ *
-+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
-+ * returnType (* name)
-+ *
-+ *
-+ * 6. NULL_PTR: This macro is the value of a NULL pointer.
-+ *
-+ * In any ANSI/ISO C environment (and in many others as well),
-+ * this should best be defined by
-+ *
-+ * #ifndef NULL_PTR
-+ * #define NULL_PTR 0
-+ * #endif
-+ */
-+
-+
-+/* All the various Cryptoki types and #define'd values are in the
-+ * file pkcs11t.h. */
-+#include "pkcs11t.h"
-+
-+#define __PASTE(x,y) x##y
-+
-+
-+/* ==============================================================
-+ * Define the "extern" form of all the entry points.
-+ * ==============================================================
-+ */
-+
-+#define CK_NEED_ARG_LIST 1
-+#define CK_PKCS11_FUNCTION_INFO(name) \
-+ extern CK_DECLARE_FUNCTION(CK_RV, name)
-+
-+/* pkcs11f.h has all the information about the Cryptoki
-+ * function prototypes. */
-+#include "pkcs11f.h"
-+
-+#undef CK_NEED_ARG_LIST
-+#undef CK_PKCS11_FUNCTION_INFO
-+
-+
-+/* ==============================================================
-+ * Define the typedef form of all the entry points. That is, for
-+ * each Cryptoki function C_XXX, define a type CK_C_XXX which is
-+ * a pointer to that kind of function.
-+ * ==============================================================
-+ */
++ pkey = NULL;
++ goto err;
++ }
++ EVP_PKEY_assign_RSA(pkey, rsa);
+
-+#define CK_NEED_ARG_LIST 1
-+#define CK_PKCS11_FUNCTION_INFO(name) \
-+ typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
++ if (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;
++ }
+
-+/* pkcs11f.h has all the information about the Cryptoki
-+ * function prototypes. */
-+#include "pkcs11f.h"
++ (void) check_new_rsa_key_pub(sp, rsa);
++ sp->opdata_rsa_pub = rsa;
+
-+#undef CK_NEED_ARG_LIST
-+#undef CK_PKCS11_FUNCTION_INFO
++ attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
++ attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
++ }
++ else if ((pubkey = fopen(pubkey_file, read_mode_flags)) != NULL)
++ {
++ pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL);
++ (void) fclose(pubkey);
++ }
+
++err:
++ if (sp != NULL)
++ pk11_return_session(sp, OP_RSA);
++ return (pkey);
++ }
+
-+/* ==============================================================
-+ * Define structed vector of entry points. A CK_FUNCTION_LIST
-+ * contains a CK_VERSION indicating a library's Cryptoki version
-+ * and then a whole slew of function pointers to the routines in
-+ * the library. This type was declared, but not defined, in
-+ * pkcs11t.h.
-+ * ==============================================================
++/*
++ * Create a private key object in the session from a given rsa structure.
++ * The *rsa_d_num pointer is non-NULL for RSA private keys.
+ */
++static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA *rsa,
++ RSA **key_ptr, BIGNUM **rsa_d_num, CK_SESSION_HANDLE session)
++ {
++ CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
+
-+#define CK_PKCS11_FUNCTION_INFO(name) \
-+ __PASTE(CK_,name) name;
-+
-+struct CK_FUNCTION_LIST {
-+
-+ CK_VERSION version; /* Cryptoki version */
++ if ((rsa->flags & RSA_FLAG_EXT_PKEY) == 0) {
++ PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_INCONSISTENT_KEY);
++ return (h_key);
++ }
++
++ h_key = (CK_OBJECT_HANDLE)RSA_get_ex_data(rsa, hndidx_rsa);
++ (void) pk11_active_add(h_key, OP_RSA);
++ if (key_ptr != NULL)
++ *key_ptr = rsa;
++ if (rsa_d_num != NULL)
++ {
++ if (rsa->d == NULL)
++ *rsa_d_num = NULL;
++ else if ((*rsa_d_num = BN_dup(rsa->d)) == NULL)
++ {
++ PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
++ return (h_key);
++ }
++ }
++ return (h_key);
++ }
+
-+/* Pile all the function pointers into the CK_FUNCTION_LIST. */
-+/* pkcs11f.h has all the information about the Cryptoki
-+ * function prototypes. */
-+#include "pkcs11f.h"
++/*
++ * 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_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.
++ */
++ 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))
++ {
++ /*
++ * 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_pub(sp, 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_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa)
++ {
++ /*
++ * Provide protection against RSA structure reuse by making the
++ * check for cache hit stronger. Comparing private exponent of RSA
++ * key with value cached in PK11_SESSION structure should
++ * be sufficient.
++ */
++ if ((sp->opdata_rsa_priv != rsa) ||
++ (BN_cmp(sp->opdata_rsa_d_num, rsa->d) != 0) ||
++ ((rsa->flags & RSA_FLAG_EXT_PKEY) != 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_rsa_object_priv(sp, TRUE);
++ return (0);
++ }
++ return (1);
++ }
+
-+#undef CK_PKCS11_FUNCTION_INFO
++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);
++ }
++ }
+
++#ifdef OPENSSL_SYS_WIN32
++char *getpassphrase(const char *prompt)
++ {
++ static char buf[128];
++ HANDLE h;
++ DWORD cc, mode;
++ int cnt;
+
-+#undef __PASTE
++ h = GetStdHandle(STD_INPUT_HANDLE);
++ fputs(prompt, stderr);
++ fflush(stderr);
++ fflush(stdout);
++ FlushConsoleInputBuffer(h);
++ GetConsoleMode(h, &mode);
++ SetConsoleMode(h, ENABLE_PROCESSED_INPUT);
+
-+#ifdef __cplusplus
-+}
-+#endif
++ for (cnt = 0; cnt < sizeof(buf) - 1; cnt++)
++ {
++ ReadFile(h, buf + cnt, 1, &cc, NULL);
++ if (buf[cnt] == '\r')
++ break;
++ fputc('*', stdout);
++ fflush(stderr);
++ fflush(stdout);
++ }
+
-+#endif
-Index: openssl/crypto/engine/pkcs11f.h
-diff -u /dev/null openssl/crypto/engine/pkcs11f.h:1.1.1.1
---- /dev/null Thu Dec 24 13:00:46 2009
-+++ openssl/crypto/engine/pkcs11f.h Wed Oct 24 23:27:09 2007
++ SetConsoleMode(h, mode);
++ buf[cnt] = '\0';
++ fputs("\n", stderr);
++ return buf;
++ }
++#endif /* OPENSSL_SYS_WIN32 */
++#endif /* OPENSSL_NO_HW_PK11SO */
++#endif /* OPENSSL_NO_HW_PK11 */
++#endif /* OPENSSL_NO_HW */
+Index: openssl-0.9.8s/crypto/engine/Makefile
+diff -Nur openssl-0.9.8s/crypto/engine/Makefile openssl-0.9.8s-patched/crypto/engine/Makefile
+--- openssl-0.9.8s/crypto/engine/Makefile 2009-09-27 07:04:32.000000000 -0700
++++ openssl-0.9.8s-patched/crypto/engine/Makefile 2012-01-11 12:03:30.031811760 -0800
+@@ -21,12 +21,14 @@
+ eng_table.c eng_pkey.c eng_fat.c eng_all.c \
+ tb_rsa.c tb_dsa.c tb_ecdsa.c tb_dh.c tb_ecdh.c tb_rand.c tb_store.c \
+ tb_cipher.c tb_digest.c \
+- eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c eng_padlock.c
++ eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c eng_padlock.c \
++ hw_pk11.c hw_pk11_pub.c hw_pk11so.c hw_pk11so_pub.c
+ LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \
+ eng_table.o eng_pkey.o eng_fat.o eng_all.o \
+ tb_rsa.o tb_dsa.o tb_ecdsa.o tb_dh.o tb_ecdh.o tb_rand.o tb_store.o \
+ tb_cipher.o tb_digest.o \
+- eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o eng_padlock.o
++ eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o eng_padlock.o \
++ hw_pk11.o hw_pk11_pub.o hw_pk11so.o hw_pk11so_pub.o
+
+ SRC= $(LIBSRC)
+
+@@ -288,6 +290,102 @@
+ eng_table.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
+ eng_table.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
+ eng_table.o: eng_table.c
++hw_pk11.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
++hw_pk11.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
++hw_pk11.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
++hw_pk11.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
++hw_pk11.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
++hw_pk11.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
++hw_pk11.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
++hw_pk11.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
++hw_pk11.o: ../../include/openssl/ui.h ../../include/openssl/err.h
++hw_pk11.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
++hw_pk11.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
++hw_pk11.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
++hw_pk11.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
++hw_pk11.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
++hw_pk11.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
++hw_pk11.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
++hw_pk11.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
++hw_pk11.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
++hw_pk11.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
++hw_pk11.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
++hw_pk11.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
++hw_pk11.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
++hw_pk11.o: ../../include/openssl/pem2.h ../cryptlib.h
++hw_pk11.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11.c
++hw_pk11_pub.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
++hw_pk11_pub.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
++hw_pk11_pub.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
++hw_pk11_pub.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
++hw_pk11_pub.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
++hw_pk11_pub.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
++hw_pk11_pub.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
++hw_pk11_pub.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
++hw_pk11_pub.o: ../../include/openssl/ui.h ../../include/openssl/err.h
++hw_pk11_pub.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
++hw_pk11_pub.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
++hw_pk11_pub.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
++hw_pk11_pub.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
++hw_pk11_pub.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
++hw_pk11_pub.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
++hw_pk11_pub.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
++hw_pk11_pub.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
++hw_pk11_pub.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
++hw_pk11_pub.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
++hw_pk11_pub.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
++hw_pk11_pub.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
++hw_pk11_pub.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
++hw_pk11_pub.o: ../../include/openssl/pem2.h ../cryptlib.h
++hw_pk11_pub.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11_pub.c
++hw_pk11so.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
++hw_pk11so.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
++hw_pk11so.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
++hw_pk11so.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
++hw_pk11so.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
++hw_pk11so.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
++hw_pk11so.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
++hw_pk11so.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
++hw_pk11so.o: ../../include/openssl/ui.h ../../include/openssl/err.h
++hw_pk11so.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
++hw_pk11so.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
++hw_pk11so.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
++hw_pk11so.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
++hw_pk11so.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
++hw_pk11so.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
++hw_pk11so.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
++hw_pk11so.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
++hw_pk11so.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
++hw_pk11so.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
++hw_pk11so.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
++hw_pk11so.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
++hw_pk11so.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
++hw_pk11so.o: ../../include/openssl/pem2.h ../cryptlib.h
++hw_pk11so.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11so.c
++hw_pk11so_pub.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
++hw_pk11so_pub.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
++hw_pk11so_pub.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
++hw_pk11so_pub.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
++hw_pk11so_pub.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
++hw_pk11so_pub.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
++hw_pk11so_pub.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
++hw_pk11so_pub.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
++hw_pk11so_pub.o: ../../include/openssl/ui.h ../../include/openssl/err.h
++hw_pk11so_pub.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
++hw_pk11so_pub.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
++hw_pk11so_pub.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
++hw_pk11so_pub.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
++hw_pk11so_pub.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
++hw_pk11so_pub.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
++hw_pk11so_pub.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
++hw_pk11so_pub.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
++hw_pk11so_pub.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
++hw_pk11so_pub.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
++hw_pk11so_pub.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
++hw_pk11so_pub.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
++hw_pk11so_pub.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
++hw_pk11so_pub.o: ../../include/openssl/pem2.h ../cryptlib.h
++hw_pk11so_pub.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11so_pub.c
+ tb_cipher.o: ../../e_os.h ../../include/openssl/asn1.h
+ tb_cipher.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
+ tb_cipher.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
+Index: openssl-0.9.8s/crypto/engine/pkcs11f.h
+diff -Nur openssl-0.9.8s/crypto/engine/pkcs11f.h openssl-0.9.8s-patched/crypto/engine/pkcs11f.h
+--- openssl-0.9.8s/crypto/engine/pkcs11f.h 1969-12-31 16:00:00.000000000 -0800
++++ openssl-0.9.8s-patched/crypto/engine/pkcs11f.h 2012-01-11 12:03:30.031811760 -0800
@@ -0,0 +1,912 @@
+/* pkcs11f.h include file for PKCS #11. */
-+/* $Revision: 1.2 $ */
++/* $Revision: 1.1 $ */
+
+/* License to copy and use this software is granted provided that it is
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
+#endif
+
+
-+/* C_WrapKey wraps (i.e., encrypts) a key. */
-+CK_PKCS11_FUNCTION_INFO(C_WrapKey)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */
-+ CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */
-+ CK_OBJECT_HANDLE hKey, /* key to be wrapped */
-+ CK_BYTE_PTR pWrappedKey, /* gets wrapped key */
-+ CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */
-+);
-+#endif
++/* C_WrapKey wraps (i.e., encrypts) a key. */
++CK_PKCS11_FUNCTION_INFO(C_WrapKey)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */
++ CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */
++ CK_OBJECT_HANDLE hKey, /* key to be wrapped */
++ CK_BYTE_PTR pWrappedKey, /* gets wrapped key */
++ CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */
++);
++#endif
++
++
++/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
++ * key object. */
++CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* session's handle */
++ CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */
++ CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */
++ CK_BYTE_PTR pWrappedKey, /* the wrapped key */
++ CK_ULONG ulWrappedKeyLen, /* wrapped key len */
++ CK_ATTRIBUTE_PTR pTemplate, /* new key template */
++ CK_ULONG ulAttributeCount, /* template length */
++ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
++);
++#endif
++
++
++/* C_DeriveKey derives a key from a base key, creating a new key
++ * object. */
++CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* session's handle */
++ CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */
++ CK_OBJECT_HANDLE hBaseKey, /* base key */
++ CK_ATTRIBUTE_PTR pTemplate, /* new key template */
++ CK_ULONG ulAttributeCount, /* template length */
++ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
++);
++#endif
++
++
++
++/* Random number generation */
++
++/* C_SeedRandom mixes additional seed material into the token's
++ * random number generator. */
++CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_BYTE_PTR pSeed, /* the seed material */
++ CK_ULONG ulSeedLen /* length of seed material */
++);
++#endif
++
++
++/* C_GenerateRandom generates random data. */
++CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession, /* the session's handle */
++ CK_BYTE_PTR RandomData, /* receives the random data */
++ CK_ULONG ulRandomLen /* # of bytes to generate */
++);
++#endif
++
++
++
++/* Parallel function management */
++
++/* C_GetFunctionStatus is a legacy function; it obtains an
++ * updated status of a function running in parallel with an
++ * application. */
++CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession /* the session's handle */
++);
++#endif
++
++
++/* C_CancelFunction is a legacy function; it cancels a function
++ * running in parallel. */
++CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_SESSION_HANDLE hSession /* the session's handle */
++);
++#endif
++
++
++
++/* Functions added in for Cryptoki Version 2.01 or later */
++
++/* C_WaitForSlotEvent waits for a slot event (token insertion,
++ * removal, etc.) to occur. */
++CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
++#ifdef CK_NEED_ARG_LIST
++(
++ CK_FLAGS flags, /* blocking/nonblocking flag */
++ CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */
++ CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */
++);
++#endif
+Index: openssl-0.9.8s/crypto/engine/pkcs11.h
+diff -Nur openssl-0.9.8s/crypto/engine/pkcs11.h openssl-0.9.8s-patched/crypto/engine/pkcs11.h
+--- openssl-0.9.8s/crypto/engine/pkcs11.h 1969-12-31 16:00:00.000000000 -0800
++++ openssl-0.9.8s-patched/crypto/engine/pkcs11.h 2012-01-11 12:03:30.031811760 -0800
+@@ -0,0 +1,299 @@
++/* pkcs11.h include file for PKCS #11. */
++/* $Revision: 1.1 $ */
++
++/* License to copy and use this software is granted provided that it is
++ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
++ * (Cryptoki)" in all material mentioning or referencing this software.
++
++ * License is also granted to make and use derivative works provided that
++ * such works are identified as "derived from the RSA Security Inc. PKCS #11
++ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
++ * referencing the derived work.
++
++ * RSA Security Inc. makes no representations concerning either the
++ * merchantability of this software or the suitability of this software for
++ * any particular purpose. It is provided "as is" without express or implied
++ * warranty of any kind.
++ */
++
++#ifndef _PKCS11_H_
++#define _PKCS11_H_ 1
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++/* Before including this file (pkcs11.h) (or pkcs11t.h by
++ * itself), 6 platform-specific macros must be defined. These
++ * macros are described below, and typical definitions for them
++ * are also given. Be advised that these definitions can depend
++ * on both the platform and the compiler used (and possibly also
++ * on whether a Cryptoki library is linked statically or
++ * dynamically).
++ *
++ * In addition to defining these 6 macros, the packing convention
++ * for Cryptoki structures should be set. The Cryptoki
++ * convention on packing is that structures should be 1-byte
++ * aligned.
++ *
++ * If you're using Microsoft Developer Studio 5.0 to produce
++ * Win32 stuff, this might be done by using the following
++ * preprocessor directive before including pkcs11.h or pkcs11t.h:
++ *
++ * #pragma pack(push, cryptoki, 1)
++ *
++ * and using the following preprocessor directive after including
++ * pkcs11.h or pkcs11t.h:
++ *
++ * #pragma pack(pop, cryptoki)
++ *
++ * If you're using an earlier version of Microsoft Developer
++ * Studio to produce Win16 stuff, this might be done by using
++ * the following preprocessor directive before including
++ * pkcs11.h or pkcs11t.h:
++ *
++ * #pragma pack(1)
++ *
++ * In a UNIX environment, you're on your own for this. You might
++ * not need to do (or be able to do!) anything.
++ *
++ *
++ * Now for the macros:
++ *
++ *
++ * 1. CK_PTR: The indirection string for making a pointer to an
++ * object. It can be used like this:
++ *
++ * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
++ *
++ * If you're using Microsoft Developer Studio 5.0 to produce
++ * Win32 stuff, it might be defined by:
++ *
++ * #define CK_PTR *
++ *
++ * If you're using an earlier version of Microsoft Developer
++ * Studio to produce Win16 stuff, it might be defined by:
++ *
++ * #define CK_PTR far *
++ *
++ * In a typical UNIX environment, it might be defined by:
++ *
++ * #define CK_PTR *
++ *
++ *
++ * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
++ * an exportable Cryptoki library function definition out of a
++ * return type and a function name. It should be used in the
++ * following fashion to define the exposed Cryptoki functions in
++ * a Cryptoki library:
++ *
++ * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
++ * CK_VOID_PTR pReserved
++ * )
++ * {
++ * ...
++ * }
++ *
++ * If you're using Microsoft Developer Studio 5.0 to define a
++ * function in a Win32 Cryptoki .dll, it might be defined by:
++ *
++ * #define CK_DEFINE_FUNCTION(returnType, name) \
++ * returnType __declspec(dllexport) name
++ *
++ * If you're using an earlier version of Microsoft Developer
++ * Studio to define a function in a Win16 Cryptoki .dll, it
++ * might be defined by:
++ *
++ * #define CK_DEFINE_FUNCTION(returnType, name) \
++ * returnType __export _far _pascal name
++ *
++ * In a UNIX environment, it might be defined by:
++ *
++ * #define CK_DEFINE_FUNCTION(returnType, name) \
++ * returnType name
++ *
++ *
++ * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
++ * an importable Cryptoki library function declaration out of a
++ * return type and a function name. It should be used in the
++ * following fashion:
++ *
++ * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
++ * CK_VOID_PTR pReserved
++ * );
++ *
++ * If you're using Microsoft Developer Studio 5.0 to declare a
++ * function in a Win32 Cryptoki .dll, it might be defined by:
++ *
++ * #define CK_DECLARE_FUNCTION(returnType, name) \
++ * returnType __declspec(dllimport) name
++ *
++ * If you're using an earlier version of Microsoft Developer
++ * Studio to declare a function in a Win16 Cryptoki .dll, it
++ * might be defined by:
++ *
++ * #define CK_DECLARE_FUNCTION(returnType, name) \
++ * returnType __export _far _pascal name
++ *
++ * In a UNIX environment, it might be defined by:
++ *
++ * #define CK_DECLARE_FUNCTION(returnType, name) \
++ * returnType name
++ *
++ *
++ * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
++ * which makes a Cryptoki API function pointer declaration or
++ * function pointer type declaration out of a return type and a
++ * function name. It should be used in the following fashion:
++ *
++ * // Define funcPtr to be a pointer to a Cryptoki API function
++ * // taking arguments args and returning CK_RV.
++ * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
++ *
++ * or
++ *
++ * // Define funcPtrType to be the type of a pointer to a
++ * // Cryptoki API function taking arguments args and returning
++ * // CK_RV, and then define funcPtr to be a variable of type
++ * // funcPtrType.
++ * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
++ * funcPtrType funcPtr;
++ *
++ * If you're using Microsoft Developer Studio 5.0 to access
++ * functions in a Win32 Cryptoki .dll, in might be defined by:
++ *
++ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
++ * returnType __declspec(dllimport) (* name)
++ *
++ * If you're using an earlier version of Microsoft Developer
++ * Studio to access functions in a Win16 Cryptoki .dll, it might
++ * be defined by:
++ *
++ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
++ * returnType __export _far _pascal (* name)
++ *
++ * In a UNIX environment, it might be defined by:
++ *
++ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
++ * returnType (* name)
++ *
++ *
++ * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
++ * a function pointer type for an application callback out of
++ * a return type for the callback and a name for the callback.
++ * It should be used in the following fashion:
++ *
++ * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
++ *
++ * to declare a function pointer, myCallback, to a callback
++ * which takes arguments args and returns a CK_RV. It can also
++ * be used like this:
++ *
++ * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
++ * myCallbackType myCallback;
++ *
++ * If you're using Microsoft Developer Studio 5.0 to do Win32
++ * Cryptoki development, it might be defined by:
++ *
++ * #define CK_CALLBACK_FUNCTION(returnType, name) \
++ * returnType (* name)
++ *
++ * If you're using an earlier version of Microsoft Developer
++ * Studio to do Win16 development, it might be defined by:
++ *
++ * #define CK_CALLBACK_FUNCTION(returnType, name) \
++ * returnType _far _pascal (* name)
++ *
++ * In a UNIX environment, it might be defined by:
++ *
++ * #define CK_CALLBACK_FUNCTION(returnType, name) \
++ * returnType (* name)
++ *
++ *
++ * 6. NULL_PTR: This macro is the value of a NULL pointer.
++ *
++ * In any ANSI/ISO C environment (and in many others as well),
++ * this should best be defined by
++ *
++ * #ifndef NULL_PTR
++ * #define NULL_PTR 0
++ * #endif
++ */
++
++
++/* All the various Cryptoki types and #define'd values are in the
++ * file pkcs11t.h. */
++#include "pkcs11t.h"
+
++#define __PASTE(x,y) x##y
+
-+/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
-+ * key object. */
-+CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* session's handle */
-+ CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */
-+ CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */
-+ CK_BYTE_PTR pWrappedKey, /* the wrapped key */
-+ CK_ULONG ulWrappedKeyLen, /* wrapped key len */
-+ CK_ATTRIBUTE_PTR pTemplate, /* new key template */
-+ CK_ULONG ulAttributeCount, /* template length */
-+ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
-+);
-+#endif
+
++/* ==============================================================
++ * Define the "extern" form of all the entry points.
++ * ==============================================================
++ */
+
-+/* C_DeriveKey derives a key from a base key, creating a new key
-+ * object. */
-+CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* session's handle */
-+ CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */
-+ CK_OBJECT_HANDLE hBaseKey, /* base key */
-+ CK_ATTRIBUTE_PTR pTemplate, /* new key template */
-+ CK_ULONG ulAttributeCount, /* template length */
-+ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
-+);
-+#endif
++#define CK_NEED_ARG_LIST 1
++#define CK_PKCS11_FUNCTION_INFO(name) \
++ extern CK_DECLARE_FUNCTION(CK_RV, name)
+
++/* pkcs11f.h has all the information about the Cryptoki
++ * function prototypes. */
++#include "pkcs11f.h"
+
++#undef CK_NEED_ARG_LIST
++#undef CK_PKCS11_FUNCTION_INFO
+
-+/* Random number generation */
+
-+/* C_SeedRandom mixes additional seed material into the token's
-+ * random number generator. */
-+CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_BYTE_PTR pSeed, /* the seed material */
-+ CK_ULONG ulSeedLen /* length of seed material */
-+);
-+#endif
++/* ==============================================================
++ * Define the typedef form of all the entry points. That is, for
++ * each Cryptoki function C_XXX, define a type CK_C_XXX which is
++ * a pointer to that kind of function.
++ * ==============================================================
++ */
+
++#define CK_NEED_ARG_LIST 1
++#define CK_PKCS11_FUNCTION_INFO(name) \
++ typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
+
-+/* C_GenerateRandom generates random data. */
-+CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession, /* the session's handle */
-+ CK_BYTE_PTR RandomData, /* receives the random data */
-+ CK_ULONG ulRandomLen /* # of bytes to generate */
-+);
-+#endif
++/* pkcs11f.h has all the information about the Cryptoki
++ * function prototypes. */
++#include "pkcs11f.h"
+
++#undef CK_NEED_ARG_LIST
++#undef CK_PKCS11_FUNCTION_INFO
+
+
-+/* Parallel function management */
++/* ==============================================================
++ * Define structed vector of entry points. A CK_FUNCTION_LIST
++ * contains a CK_VERSION indicating a library's Cryptoki version
++ * and then a whole slew of function pointers to the routines in
++ * the library. This type was declared, but not defined, in
++ * pkcs11t.h.
++ * ==============================================================
++ */
+
-+/* C_GetFunctionStatus is a legacy function; it obtains an
-+ * updated status of a function running in parallel with an
-+ * application. */
-+CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession /* the session's handle */
-+);
-+#endif
++#define CK_PKCS11_FUNCTION_INFO(name) \
++ __PASTE(CK_,name) name;
++
++struct CK_FUNCTION_LIST {
+
++ CK_VERSION version; /* Cryptoki version */
+
-+/* C_CancelFunction is a legacy function; it cancels a function
-+ * running in parallel. */
-+CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_SESSION_HANDLE hSession /* the session's handle */
-+);
-+#endif
++/* Pile all the function pointers into the CK_FUNCTION_LIST. */
++/* pkcs11f.h has all the information about the Cryptoki
++ * function prototypes. */
++#include "pkcs11f.h"
+
++};
+
++#undef CK_PKCS11_FUNCTION_INFO
+
-+/* Functions added in for Cryptoki Version 2.01 or later */
+
-+/* C_WaitForSlotEvent waits for a slot event (token insertion,
-+ * removal, etc.) to occur. */
-+CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
-+#ifdef CK_NEED_ARG_LIST
-+(
-+ CK_FLAGS flags, /* blocking/nonblocking flag */
-+ CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */
-+ CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */
-+);
++#undef __PASTE
++
++#ifdef __cplusplus
++}
++#endif
++
+#endif
-Index: openssl/crypto/engine/pkcs11t.h
-diff -u /dev/null openssl/crypto/engine/pkcs11t.h:1.2
---- /dev/null Thu Dec 24 13:00:46 2009
-+++ openssl/crypto/engine/pkcs11t.h Sat Aug 30 11:58:07 2008
+Index: openssl-0.9.8s/crypto/engine/pkcs11t.h
+diff -Nur openssl-0.9.8s/crypto/engine/pkcs11t.h openssl-0.9.8s-patched/crypto/engine/pkcs11t.h
+--- openssl-0.9.8s/crypto/engine/pkcs11t.h 1969-12-31 16:00:00.000000000 -0800
++++ openssl-0.9.8s-patched/crypto/engine/pkcs11t.h 2012-01-11 12:03:30.031811760 -0800
@@ -0,0 +1,1885 @@
+/* pkcs11t.h include file for PKCS #11. */
-+/* $Revision: 1.2 $ */
++/* $Revision: 1.1 $ */
+
+/* License to copy and use this software is granted provided that it is
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
+ CK_OBJECT_HANDLE publicKey;
+} CK_X9_42_MQV_DERIVE_PARAMS;
+
-+typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
++typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
++
++/* CK_KEA_DERIVE_PARAMS provides the parameters to the
++ * CKM_KEA_DERIVE mechanism */
++/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
++typedef struct CK_KEA_DERIVE_PARAMS {
++ CK_BBOOL isSender;
++ CK_ULONG ulRandomLen;
++ CK_BYTE_PTR pRandomA;
++ CK_BYTE_PTR pRandomB;
++ CK_ULONG ulPublicDataLen;
++ CK_BYTE_PTR pPublicData;
++} CK_KEA_DERIVE_PARAMS;
++
++typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
++
++
++/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
++ * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just
++ * holds the effective keysize */
++typedef CK_ULONG CK_RC2_PARAMS;
++
++typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
++
++
++/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
++ * mechanism */
++typedef struct CK_RC2_CBC_PARAMS {
++ /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
++ * v2.0 */
++ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
++
++ CK_BYTE iv[8]; /* IV for CBC mode */
++} CK_RC2_CBC_PARAMS;
++
++typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
++
++
++/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
++ * CKM_RC2_MAC_GENERAL mechanism */
++/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
++typedef struct CK_RC2_MAC_GENERAL_PARAMS {
++ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
++ CK_ULONG ulMacLength; /* Length of MAC in bytes */
++} CK_RC2_MAC_GENERAL_PARAMS;
++
++typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
++ CK_RC2_MAC_GENERAL_PARAMS_PTR;
++
++
++/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
++ * CKM_RC5_MAC mechanisms */
++/* CK_RC5_PARAMS is new for v2.0 */
++typedef struct CK_RC5_PARAMS {
++ CK_ULONG ulWordsize; /* wordsize in bits */
++ CK_ULONG ulRounds; /* number of rounds */
++} CK_RC5_PARAMS;
++
++typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
++
++
++/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
++ * mechanism */
++/* CK_RC5_CBC_PARAMS is new for v2.0 */
++typedef struct CK_RC5_CBC_PARAMS {
++ CK_ULONG ulWordsize; /* wordsize in bits */
++ CK_ULONG ulRounds; /* number of rounds */
++ CK_BYTE_PTR pIv; /* pointer to IV */
++ CK_ULONG ulIvLen; /* length of IV in bytes */
++} CK_RC5_CBC_PARAMS;
++
++typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
++
++
++/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
++ * CKM_RC5_MAC_GENERAL mechanism */
++/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
++typedef struct CK_RC5_MAC_GENERAL_PARAMS {
++ CK_ULONG ulWordsize; /* wordsize in bits */
++ CK_ULONG ulRounds; /* number of rounds */
++ CK_ULONG ulMacLength; /* Length of MAC in bytes */
++} CK_RC5_MAC_GENERAL_PARAMS;
++
++typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
++ CK_RC5_MAC_GENERAL_PARAMS_PTR;
++
++
++/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
++ * ciphers' MAC_GENERAL mechanisms. Its value is the length of
++ * the MAC */
++/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
++typedef CK_ULONG CK_MAC_GENERAL_PARAMS;
++
++typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
++
++/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
++typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
++ CK_BYTE iv[8];
++ CK_BYTE_PTR pData;
++ CK_ULONG length;
++} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
++
++typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
++
++typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
++ CK_BYTE iv[16];
++ CK_BYTE_PTR pData;
++ CK_ULONG length;
++} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
++
++typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
++
++/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
++ * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
++/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
++typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
++ CK_ULONG ulPasswordLen;
++ CK_BYTE_PTR pPassword;
++ CK_ULONG ulPublicDataLen;
++ CK_BYTE_PTR pPublicData;
++ CK_ULONG ulPAndGLen;
++ CK_ULONG ulQLen;
++ CK_ULONG ulRandomLen;
++ CK_BYTE_PTR pRandomA;
++ CK_BYTE_PTR pPrimeP;
++ CK_BYTE_PTR pBaseG;
++ CK_BYTE_PTR pSubprimeQ;
++} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
++
++typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
++ CK_SKIPJACK_PRIVATE_WRAP_PTR;
++
++
++/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
++ * CKM_SKIPJACK_RELAYX mechanism */
++/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
++typedef struct CK_SKIPJACK_RELAYX_PARAMS {
++ CK_ULONG ulOldWrappedXLen;
++ CK_BYTE_PTR pOldWrappedX;
++ CK_ULONG ulOldPasswordLen;
++ CK_BYTE_PTR pOldPassword;
++ CK_ULONG ulOldPublicDataLen;
++ CK_BYTE_PTR pOldPublicData;
++ CK_ULONG ulOldRandomLen;
++ CK_BYTE_PTR pOldRandomA;
++ CK_ULONG ulNewPasswordLen;
++ CK_BYTE_PTR pNewPassword;
++ CK_ULONG ulNewPublicDataLen;
++ CK_BYTE_PTR pNewPublicData;
++ CK_ULONG ulNewRandomLen;
++ CK_BYTE_PTR pNewRandomA;
++} CK_SKIPJACK_RELAYX_PARAMS;
++
++typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
++ CK_SKIPJACK_RELAYX_PARAMS_PTR;
++
++
++typedef struct CK_PBE_PARAMS {
++ CK_BYTE_PTR pInitVector;
++ CK_UTF8CHAR_PTR pPassword;
++ CK_ULONG ulPasswordLen;
++ CK_BYTE_PTR pSalt;
++ CK_ULONG ulSaltLen;
++ CK_ULONG ulIteration;
++} CK_PBE_PARAMS;
++
++typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
++
++
++/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
++ * CKM_KEY_WRAP_SET_OAEP mechanism */
++/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
++typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
++ CK_BYTE bBC; /* block contents byte */
++ CK_BYTE_PTR pX; /* extra data */
++ CK_ULONG ulXLen; /* length of extra data in bytes */
++} CK_KEY_WRAP_SET_OAEP_PARAMS;
++
++typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
++ CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
++
++
++typedef struct CK_SSL3_RANDOM_DATA {
++ CK_BYTE_PTR pClientRandom;
++ CK_ULONG ulClientRandomLen;
++ CK_BYTE_PTR pServerRandom;
++ CK_ULONG ulServerRandomLen;
++} CK_SSL3_RANDOM_DATA;
++
++
++typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
++ CK_SSL3_RANDOM_DATA RandomInfo;
++ CK_VERSION_PTR pVersion;
++} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
++
++typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
++ CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
++
++
++typedef struct CK_SSL3_KEY_MAT_OUT {
++ CK_OBJECT_HANDLE hClientMacSecret;
++ CK_OBJECT_HANDLE hServerMacSecret;
++ CK_OBJECT_HANDLE hClientKey;
++ CK_OBJECT_HANDLE hServerKey;
++ CK_BYTE_PTR pIVClient;
++ CK_BYTE_PTR pIVServer;
++} CK_SSL3_KEY_MAT_OUT;
++
++typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
++
++
++typedef struct CK_SSL3_KEY_MAT_PARAMS {
++ CK_ULONG ulMacSizeInBits;
++ CK_ULONG ulKeySizeInBits;
++ CK_ULONG ulIVSizeInBits;
++ CK_BBOOL bIsExport;
++ CK_SSL3_RANDOM_DATA RandomInfo;
++ CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
++} CK_SSL3_KEY_MAT_PARAMS;
++
++typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
++
++/* CK_TLS_PRF_PARAMS is new for version 2.20 */
++typedef struct CK_TLS_PRF_PARAMS {
++ CK_BYTE_PTR pSeed;
++ CK_ULONG ulSeedLen;
++ CK_BYTE_PTR pLabel;
++ CK_ULONG ulLabelLen;
++ CK_BYTE_PTR pOutput;
++ CK_ULONG_PTR pulOutputLen;
++} CK_TLS_PRF_PARAMS;
++
++typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
++
++/* WTLS is new for version 2.20 */
++typedef struct CK_WTLS_RANDOM_DATA {
++ CK_BYTE_PTR pClientRandom;
++ CK_ULONG ulClientRandomLen;
++ CK_BYTE_PTR pServerRandom;
++ CK_ULONG ulServerRandomLen;
++} CK_WTLS_RANDOM_DATA;
++
++typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
++
++typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
++ CK_MECHANISM_TYPE DigestMechanism;
++ CK_WTLS_RANDOM_DATA RandomInfo;
++ CK_BYTE_PTR pVersion;
++} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
++
++typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
++ CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
++
++typedef struct CK_WTLS_PRF_PARAMS {
++ CK_MECHANISM_TYPE DigestMechanism;
++ CK_BYTE_PTR pSeed;
++ CK_ULONG ulSeedLen;
++ CK_BYTE_PTR pLabel;
++ CK_ULONG ulLabelLen;
++ CK_BYTE_PTR pOutput;
++ CK_ULONG_PTR pulOutputLen;
++} CK_WTLS_PRF_PARAMS;
+
-+/* CK_KEA_DERIVE_PARAMS provides the parameters to the
-+ * CKM_KEA_DERIVE mechanism */
-+/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
-+typedef struct CK_KEA_DERIVE_PARAMS {
-+ CK_BBOOL isSender;
-+ CK_ULONG ulRandomLen;
-+ CK_BYTE_PTR pRandomA;
-+ CK_BYTE_PTR pRandomB;
-+ CK_ULONG ulPublicDataLen;
-+ CK_BYTE_PTR pPublicData;
-+} CK_KEA_DERIVE_PARAMS;
++typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
+
-+typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
++typedef struct CK_WTLS_KEY_MAT_OUT {
++ CK_OBJECT_HANDLE hMacSecret;
++ CK_OBJECT_HANDLE hKey;
++ CK_BYTE_PTR pIV;
++} CK_WTLS_KEY_MAT_OUT;
+
++typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
+
-+/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
-+ * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just
-+ * holds the effective keysize */
-+typedef CK_ULONG CK_RC2_PARAMS;
++typedef struct CK_WTLS_KEY_MAT_PARAMS {
++ CK_MECHANISM_TYPE DigestMechanism;
++ CK_ULONG ulMacSizeInBits;
++ CK_ULONG ulKeySizeInBits;
++ CK_ULONG ulIVSizeInBits;
++ CK_ULONG ulSequenceNumber;
++ CK_BBOOL bIsExport;
++ CK_WTLS_RANDOM_DATA RandomInfo;
++ CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
++} CK_WTLS_KEY_MAT_PARAMS;
+
-+typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
++typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
+
++/* CMS is new for version 2.20 */
++typedef struct CK_CMS_SIG_PARAMS {
++ CK_OBJECT_HANDLE certificateHandle;
++ CK_MECHANISM_PTR pSigningMechanism;
++ CK_MECHANISM_PTR pDigestMechanism;
++ CK_UTF8CHAR_PTR pContentType;
++ CK_BYTE_PTR pRequestedAttributes;
++ CK_ULONG ulRequestedAttributesLen;
++ CK_BYTE_PTR pRequiredAttributes;
++ CK_ULONG ulRequiredAttributesLen;
++} CK_CMS_SIG_PARAMS;
+
-+/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
-+ * mechanism */
-+typedef struct CK_RC2_CBC_PARAMS {
-+ /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
-+ * v2.0 */
-+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
++typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
+
-+ CK_BYTE iv[8]; /* IV for CBC mode */
-+} CK_RC2_CBC_PARAMS;
++typedef struct CK_KEY_DERIVATION_STRING_DATA {
++ CK_BYTE_PTR pData;
++ CK_ULONG ulLen;
++} CK_KEY_DERIVATION_STRING_DATA;
+
-+typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
++typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
++ CK_KEY_DERIVATION_STRING_DATA_PTR;
+
+
-+/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
-+ * CKM_RC2_MAC_GENERAL mechanism */
-+/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
-+typedef struct CK_RC2_MAC_GENERAL_PARAMS {
-+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
-+ CK_ULONG ulMacLength; /* Length of MAC in bytes */
-+} CK_RC2_MAC_GENERAL_PARAMS;
++/* The CK_EXTRACT_PARAMS is used for the
++ * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit
++ * of the base key should be used as the first bit of the
++ * derived key */
++/* CK_EXTRACT_PARAMS is new for v2.0 */
++typedef CK_ULONG CK_EXTRACT_PARAMS;
+
-+typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
-+ CK_RC2_MAC_GENERAL_PARAMS_PTR;
++typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
+
++/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
++ * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
++ * indicate the Pseudo-Random Function (PRF) used to generate
++ * key bits using PKCS #5 PBKDF2. */
++typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
+
-+/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
-+ * CKM_RC5_MAC mechanisms */
-+/* CK_RC5_PARAMS is new for v2.0 */
-+typedef struct CK_RC5_PARAMS {
-+ CK_ULONG ulWordsize; /* wordsize in bits */
-+ CK_ULONG ulRounds; /* number of rounds */
-+} CK_RC5_PARAMS;
++typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
+
-+typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
++/* The following PRFs are defined in PKCS #5 v2.0. */
++#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
+
+
-+/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
-+ * mechanism */
-+/* CK_RC5_CBC_PARAMS is new for v2.0 */
-+typedef struct CK_RC5_CBC_PARAMS {
-+ CK_ULONG ulWordsize; /* wordsize in bits */
-+ CK_ULONG ulRounds; /* number of rounds */
-+ CK_BYTE_PTR pIv; /* pointer to IV */
-+ CK_ULONG ulIvLen; /* length of IV in bytes */
-+} CK_RC5_CBC_PARAMS;
++/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
++ * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
++ * source of the salt value when deriving a key using PKCS #5
++ * PBKDF2. */
++typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
+
-+typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
++typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
+
++/* The following salt value sources are defined in PKCS #5 v2.0. */
++#define CKZ_SALT_SPECIFIED 0x00000001
+
-+/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
-+ * CKM_RC5_MAC_GENERAL mechanism */
-+/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
-+typedef struct CK_RC5_MAC_GENERAL_PARAMS {
-+ CK_ULONG ulWordsize; /* wordsize in bits */
-+ CK_ULONG ulRounds; /* number of rounds */
-+ CK_ULONG ulMacLength; /* Length of MAC in bytes */
-+} CK_RC5_MAC_GENERAL_PARAMS;
++/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
++ * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
++ * parameters to the CKM_PKCS5_PBKD2 mechanism. */
++typedef struct CK_PKCS5_PBKD2_PARAMS {
++ CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
++ CK_VOID_PTR pSaltSourceData;
++ CK_ULONG ulSaltSourceDataLen;
++ CK_ULONG iterations;
++ CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
++ CK_VOID_PTR pPrfData;
++ CK_ULONG ulPrfDataLen;
++ CK_UTF8CHAR_PTR pPassword;
++ CK_ULONG_PTR ulPasswordLen;
++} CK_PKCS5_PBKD2_PARAMS;
+
-+typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
-+ CK_RC5_MAC_GENERAL_PARAMS_PTR;
++typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
+
++/* All CK_OTP structs are new for PKCS #11 v2.20 amendment 3 */
+
-+/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
-+ * ciphers' MAC_GENERAL mechanisms. Its value is the length of
-+ * the MAC */
-+/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
-+typedef CK_ULONG CK_MAC_GENERAL_PARAMS;
++typedef CK_ULONG CK_OTP_PARAM_TYPE;
++typedef CK_OTP_PARAM_TYPE CK_PARAM_TYPE; /* B/w compatibility */
+
-+typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
++typedef struct CK_OTP_PARAM {
++ CK_OTP_PARAM_TYPE type;
++ CK_VOID_PTR pValue;
++ CK_ULONG ulValueLen;
++} CK_OTP_PARAM;
+
-+/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
-+typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
-+ CK_BYTE iv[8];
-+ CK_BYTE_PTR pData;
-+ CK_ULONG length;
-+} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
++typedef CK_OTP_PARAM CK_PTR CK_OTP_PARAM_PTR;
+
-+typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
++typedef struct CK_OTP_PARAMS {
++ CK_OTP_PARAM_PTR pParams;
++ CK_ULONG ulCount;
++} CK_OTP_PARAMS;
+
-+typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
-+ CK_BYTE iv[16];
-+ CK_BYTE_PTR pData;
-+ CK_ULONG length;
-+} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
++typedef CK_OTP_PARAMS CK_PTR CK_OTP_PARAMS_PTR;
+
-+typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
++typedef struct CK_OTP_SIGNATURE_INFO {
++ CK_OTP_PARAM_PTR pParams;
++ CK_ULONG ulCount;
++} CK_OTP_SIGNATURE_INFO;
+
-+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
-+ * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
-+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
-+typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
-+ CK_ULONG ulPasswordLen;
-+ CK_BYTE_PTR pPassword;
-+ CK_ULONG ulPublicDataLen;
-+ CK_BYTE_PTR pPublicData;
-+ CK_ULONG ulPAndGLen;
-+ CK_ULONG ulQLen;
-+ CK_ULONG ulRandomLen;
-+ CK_BYTE_PTR pRandomA;
-+ CK_BYTE_PTR pPrimeP;
-+ CK_BYTE_PTR pBaseG;
-+ CK_BYTE_PTR pSubprimeQ;
-+} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
++typedef CK_OTP_SIGNATURE_INFO CK_PTR CK_OTP_SIGNATURE_INFO_PTR;
+
-+typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
-+ CK_SKIPJACK_PRIVATE_WRAP_PTR;
++/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */
++#define CK_OTP_VALUE 0
++#define CK_OTP_PIN 1
++#define CK_OTP_CHALLENGE 2
++#define CK_OTP_TIME 3
++#define CK_OTP_COUNTER 4
++#define CK_OTP_FLAGS 5
++#define CK_OTP_OUTPUT_LENGTH 6
++#define CK_OTP_OUTPUT_FORMAT 7
+
++/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */
++#define CKF_NEXT_OTP 0x00000001
++#define CKF_EXCLUDE_TIME 0x00000002
++#define CKF_EXCLUDE_COUNTER 0x00000004
++#define CKF_EXCLUDE_CHALLENGE 0x00000008
++#define CKF_EXCLUDE_PIN 0x00000010
++#define CKF_USER_FRIENDLY_OTP 0x00000020
+
-+/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
-+ * CKM_SKIPJACK_RELAYX mechanism */
-+/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
-+typedef struct CK_SKIPJACK_RELAYX_PARAMS {
-+ CK_ULONG ulOldWrappedXLen;
-+ CK_BYTE_PTR pOldWrappedX;
-+ CK_ULONG ulOldPasswordLen;
-+ CK_BYTE_PTR pOldPassword;
-+ CK_ULONG ulOldPublicDataLen;
-+ CK_BYTE_PTR pOldPublicData;
-+ CK_ULONG ulOldRandomLen;
-+ CK_BYTE_PTR pOldRandomA;
-+ CK_ULONG ulNewPasswordLen;
-+ CK_BYTE_PTR pNewPassword;
-+ CK_ULONG ulNewPublicDataLen;
-+ CK_BYTE_PTR pNewPublicData;
-+ CK_ULONG ulNewRandomLen;
-+ CK_BYTE_PTR pNewRandomA;
-+} CK_SKIPJACK_RELAYX_PARAMS;
++/* CK_KIP_PARAMS is new for PKCS #11 v2.20 amendment 2 */
++typedef struct CK_KIP_PARAMS {
++ CK_MECHANISM_PTR pMechanism;
++ CK_OBJECT_HANDLE hKey;
++ CK_BYTE_PTR pSeed;
++ CK_ULONG ulSeedLen;
++} CK_KIP_PARAMS;
+
-+typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
-+ CK_SKIPJACK_RELAYX_PARAMS_PTR;
++typedef CK_KIP_PARAMS CK_PTR CK_KIP_PARAMS_PTR;
++
++/* CK_AES_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
++typedef struct CK_AES_CTR_PARAMS {
++ CK_ULONG ulCounterBits;
++ CK_BYTE cb[16];
++} CK_AES_CTR_PARAMS;
+
++typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR;
+
-+typedef struct CK_PBE_PARAMS {
-+ CK_BYTE_PTR pInitVector;
-+ CK_UTF8CHAR_PTR pPassword;
-+ CK_ULONG ulPasswordLen;
-+ CK_BYTE_PTR pSalt;
-+ CK_ULONG ulSaltLen;
-+ CK_ULONG ulIteration;
-+} CK_PBE_PARAMS;
++/* CK_CAMELLIA_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
++typedef struct CK_CAMELLIA_CTR_PARAMS {
++ CK_ULONG ulCounterBits;
++ CK_BYTE cb[16];
++} CK_CAMELLIA_CTR_PARAMS;
+
-+typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
++typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR;
+
++/* CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
++typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS {
++ CK_BYTE iv[16];
++ CK_BYTE_PTR pData;
++ CK_ULONG length;
++} CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS;
+
-+/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
-+ * CKM_KEY_WRAP_SET_OAEP mechanism */
-+/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
-+typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
-+ CK_BYTE bBC; /* block contents byte */
-+ CK_BYTE_PTR pX; /* extra data */
-+ CK_ULONG ulXLen; /* length of extra data in bytes */
-+} CK_KEY_WRAP_SET_OAEP_PARAMS;
++typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
-+typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
-+ CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
++/* CK_ARIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
++typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS {
++ CK_BYTE iv[16];
++ CK_BYTE_PTR pData;
++ CK_ULONG length;
++} CK_ARIA_CBC_ENCRYPT_DATA_PARAMS;
+
++typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
-+typedef struct CK_SSL3_RANDOM_DATA {
-+ CK_BYTE_PTR pClientRandom;
-+ CK_ULONG ulClientRandomLen;
-+ CK_BYTE_PTR pServerRandom;
-+ CK_ULONG ulServerRandomLen;
-+} CK_SSL3_RANDOM_DATA;
++#endif
+Index: openssl-0.9.8s/crypto/opensslconf.h
+diff -Nur openssl-0.9.8s/crypto/opensslconf.h openssl-0.9.8s-patched/crypto/opensslconf.h
+--- openssl-0.9.8s/crypto/opensslconf.h 2012-01-04 11:25:23.000000000 -0800
++++ openssl-0.9.8s-patched/crypto/opensslconf.h 2012-01-11 12:03:39.131840413 -0800
+@@ -38,6 +38,9 @@
+
+ #endif /* OPENSSL_DOING_MAKEDEPEND */
+
++#ifndef OPENSSL_THREADS
++# define OPENSSL_THREADS
++#endif
+ #ifndef OPENSSL_NO_DYNAMIC_ENGINE
+ # define OPENSSL_NO_DYNAMIC_ENGINE
+ #endif
+@@ -79,6 +82,10 @@
+ # endif
+ #endif
+
++#define OPENSSL_CPUID_OBJ
+
++#define OPENSSL_CPUID_OBJ
+
-+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
-+ CK_SSL3_RANDOM_DATA RandomInfo;
-+ CK_VERSION_PTR pVersion;
-+} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
+ /* crypto/opensslconf.h.in */
+
+ #ifdef OPENSSL_DOING_MAKEDEPEND
+@@ -140,7 +147,7 @@
+ * This enables code handling data aligned at natural CPU word
+ * boundary. See crypto/rc4/rc4_enc.c for further details.
+ */
+-#undef RC4_CHUNK
++#define RC4_CHUNK unsigned long
+ #endif
+ #endif
+
+@@ -148,7 +155,7 @@
+ /* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
+ * %20 speed up (longs are 8 bytes, int's are 4). */
+ #ifndef DES_LONG
+-#define DES_LONG unsigned long
++#define DES_LONG unsigned int
+ #endif
+ #endif
+
+@@ -162,9 +169,9 @@
+ /* The prime number generation stuff may not work when
+ * EIGHT_BIT but I don't care since I've only used this mode
+ * for debuging the bignum libraries */
+-#undef SIXTY_FOUR_BIT_LONG
++#define SIXTY_FOUR_BIT_LONG
+ #undef SIXTY_FOUR_BIT
+-#define THIRTY_TWO_BIT
++#undef THIRTY_TWO_BIT
+ #undef SIXTEEN_BIT
+ #undef EIGHT_BIT
+ #endif
+@@ -178,7 +185,7 @@
+
+ #if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
+ #define CONFIG_HEADER_BF_LOCL_H
+-#undef BF_PTR
++#define BF_PTR2
+ #endif /* HEADER_BF_LOCL_H */
+
+ #if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
+@@ -208,7 +215,7 @@
+ /* Unroll the inner loop, this sometimes helps, sometimes hinders.
+ * Very mucy CPU dependant */
+ #ifndef DES_UNROLL
+-#undef DES_UNROLL
++#define DES_UNROLL
+ #endif
+
+ /* These default values were supplied by
+Index: openssl-0.9.8s/Makefile.org
+diff -Nur openssl-0.9.8s/Makefile.org openssl-0.9.8s-patched/Makefile.org
+--- openssl-0.9.8s/Makefile.org 2010-01-27 08:06:36.000000000 -0800
++++ openssl-0.9.8s-patched/Makefile.org 2012-01-11 12:03:39.131840413 -0800
+@@ -26,6 +26,9 @@
+ INSTALL_PREFIX=
+ INSTALLTOP=/usr/local/ssl
+
++# You must set this through --pk11-libname configure option.
++PK11_LIB_LOCATION=
+
-+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
-+ CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
+ # Do not edit this manually. Use Configure --openssldir=DIR do change this!
+ OPENSSLDIR=/usr/local/ssl
+
+Index: openssl-0.9.8s/README.pkcs11
+diff -Nur openssl-0.9.8s/README.pkcs11 openssl-0.9.8s-patched/README.pkcs11
+--- openssl-0.9.8s/README.pkcs11 1969-12-31 16:00:00.000000000 -0800
++++ openssl-0.9.8s-patched/README.pkcs11 2012-01-11 12:03:39.131840413 -0800
+@@ -0,0 +1,247 @@
++ISC modified
++============
++
++The PKCS#11 engine exists in two flavors, crypto-accelerator and
++sign-only. The first one is from the Solaris patch and uses the
++PKCS#11 device for all crypto operations it supports. The second
++is a stripped down version which provides only the useful
++function (i.e., signature with a RSA private key in the device
++protected key store and key loading).
+
++As a hint PKCS#11 boards should use the crypto-accelerator flavor,
++external PKCS#11 devices the sign-only. SCA 6000 is an example
++of the first, AEP Keyper of the second.
+
-+typedef struct CK_SSL3_KEY_MAT_OUT {
-+ CK_OBJECT_HANDLE hClientMacSecret;
-+ CK_OBJECT_HANDLE hServerMacSecret;
-+ CK_OBJECT_HANDLE hClientKey;
-+ CK_OBJECT_HANDLE hServerKey;
-+ CK_BYTE_PTR pIVClient;
-+ CK_BYTE_PTR pIVServer;
-+} CK_SSL3_KEY_MAT_OUT;
++Note it is mandatory to set a pk11-flavor (and only one) in
++config/Configure.
+
-+typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
++PKCS#11 engine support for OpenSSL 0.9.8j
++=========================================
+
++[March 11, 2009]
+
-+typedef struct CK_SSL3_KEY_MAT_PARAMS {
-+ CK_ULONG ulMacSizeInBits;
-+ CK_ULONG ulKeySizeInBits;
-+ CK_ULONG ulIVSizeInBits;
-+ CK_BBOOL bIsExport;
-+ CK_SSL3_RANDOM_DATA RandomInfo;
-+ CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
-+} CK_SSL3_KEY_MAT_PARAMS;
++Contents:
+
-+typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
++Overview
++Revisions of the patch for 0.9.8 branch
++FAQs
++Feedback
+
-+/* CK_TLS_PRF_PARAMS is new for version 2.20 */
-+typedef struct CK_TLS_PRF_PARAMS {
-+ CK_BYTE_PTR pSeed;
-+ CK_ULONG ulSeedLen;
-+ CK_BYTE_PTR pLabel;
-+ CK_ULONG ulLabelLen;
-+ CK_BYTE_PTR pOutput;
-+ CK_ULONG_PTR pulOutputLen;
-+} CK_TLS_PRF_PARAMS;
++Overview
++========
+
-+typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
++This patch containing code available in OpenSolaris adds support for PKCS#11
++engine into OpenSSL and implements PKCS#11 v2.20. It is to be applied against
++OpenSSL 0.9.8j source code distribution as shipped by OpenSSL.Org. Your system
++must provide PKCS#11 backend otherwise the patch is useless. You provide the
++PKCS#11 library name during the build configuration phase, see below.
+
-+/* WTLS is new for version 2.20 */
-+typedef struct CK_WTLS_RANDOM_DATA {
-+ CK_BYTE_PTR pClientRandom;
-+ CK_ULONG ulClientRandomLen;
-+ CK_BYTE_PTR pServerRandom;
-+ CK_ULONG ulServerRandomLen;
-+} CK_WTLS_RANDOM_DATA;
++Patch can be applied like this:
+
-+typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
++ # NOTE: use gtar if on Solaris
++ tar xfzv openssl-0.9.8j.tar.gz
++ # now download the patch to the current directory
++ # ...
++ cd openssl-0.9.8j
++ # NOTE: must use gpatch if on Solaris (is part of the system)
++ patch -p1 < path-to/pkcs11_engine-0.9.8j.patch.2009-03-11
+
-+typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
-+ CK_MECHANISM_TYPE DigestMechanism;
-+ CK_WTLS_RANDOM_DATA RandomInfo;
-+ CK_BYTE_PTR pVersion;
-+} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
++It is designed to support pure acceleration for RSA, DSA, DH and all the
++symetric ciphers and message digest algorithms that PKCS#11 and OpenSSL share
++except for missing support for patented algorithms MDC2, RC3, RC5 and IDEA.
+
-+typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
-+ CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
++According to the PKCS#11 providers installed on your machine, it can support
++following mechanisms:
+
-+typedef struct CK_WTLS_PRF_PARAMS {
-+ CK_MECHANISM_TYPE DigestMechanism;
-+ CK_BYTE_PTR pSeed;
-+ CK_ULONG ulSeedLen;
-+ CK_BYTE_PTR pLabel;
-+ CK_ULONG ulLabelLen;
-+ CK_BYTE_PTR pOutput;
-+ CK_ULONG_PTR pulOutputLen;
-+} CK_WTLS_PRF_PARAMS;
++ RSA, DSA, DH, RAND, DES-CBC, DES-EDE3-CBC, DES-ECB, DES-EDE3, RC4,
++ AES-128-CBC, AES-192-CBC, AES-256-CBC, AES-128-ECB, AES-192-ECB,
++ AES-256-ECB, AES-128-CTR, AES-192-CTR, AES-256-CTR, MD5, SHA1, SHA224,
++ SHA256, SHA384, SHA512
+
-+typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
++Note that for AES counter mode the application must provide their own EVP
++functions since OpenSSL doesn't support counter mode through EVP yet. You may
++see OpenSSH source code (cipher.c) to get the idea how to do that. SunSSH is an
++example of code that uses the PKCS#11 engine and deals with the fork-safety
++problem (see engine.c and packet.c files if interested).
+
-+typedef struct CK_WTLS_KEY_MAT_OUT {
-+ CK_OBJECT_HANDLE hMacSecret;
-+ CK_OBJECT_HANDLE hKey;
-+ CK_BYTE_PTR pIV;
-+} CK_WTLS_KEY_MAT_OUT;
+++------------------------------------------------------------------------------+
++| NOTE: this patch version does NOT contain experimental code for accessing |
++| RSA keys stored in PKCS#11 key stores by reference. Some problems were found |
++| (thanks to all who wrote me!) and due to my ENOTIME problem I may address |
++| those issues in a future version of the patch that will have that code back, |
++| hopefully fixed. |
+++------------------------------------------------------------------------------+
+
-+typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
++You must provide the location of PKCS#11 library in your system to the
++configure script. You will be instructed to do that when you try to run the
++config script:
+
-+typedef struct CK_WTLS_KEY_MAT_PARAMS {
-+ CK_MECHANISM_TYPE DigestMechanism;
-+ CK_ULONG ulMacSizeInBits;
-+ CK_ULONG ulKeySizeInBits;
-+ CK_ULONG ulIVSizeInBits;
-+ CK_ULONG ulSequenceNumber;
-+ CK_BBOOL bIsExport;
-+ CK_WTLS_RANDOM_DATA RandomInfo;
-+ CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
-+} CK_WTLS_KEY_MAT_PARAMS;
++ $ ./config
++ Operating system: i86pc-whatever-solaris2
++ Configuring for solaris-x86-cc
++ You must set --pk11-libname for PKCS#11 library.
++ See README.pkcs11 for more information.
+
-+typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
++Taking openCryptoki project on Linux AMD64 box as an example, you would run
++configure script like this:
+
-+/* CMS is new for version 2.20 */
-+typedef struct CK_CMS_SIG_PARAMS {
-+ CK_OBJECT_HANDLE certificateHandle;
-+ CK_MECHANISM_PTR pSigningMechanism;
-+ CK_MECHANISM_PTR pDigestMechanism;
-+ CK_UTF8CHAR_PTR pContentType;
-+ CK_BYTE_PTR pRequestedAttributes;
-+ CK_ULONG ulRequestedAttributesLen;
-+ CK_BYTE_PTR pRequiredAttributes;
-+ CK_ULONG ulRequiredAttributesLen;
-+} CK_CMS_SIG_PARAMS;
++ ./config --pk11-libname=/usr/lib64/pkcs11/PKCS11_API.so
+
-+typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
++To check whether newly built openssl really supports PKCS#11 it's enough to run
++"apps/openssl engine" and look for "(pkcs11) PKCS #11 engine support" in the
++output. If you see no PKCS#11 engine support check that the built openssl binary
++and the PKCS#11 library from --pk11-libname don't conflict on 32/64 bits.
+
-+typedef struct CK_KEY_DERIVATION_STRING_DATA {
-+ CK_BYTE_PTR pData;
-+ CK_ULONG ulLen;
-+} CK_KEY_DERIVATION_STRING_DATA;
++This patch was tested on Solaris against PKCS#11 engine available from Solaris
++Cryptographic Framework (Solaris 10 and OpenSolaris) and also on Linux using
++PKCS#11 libraries from openCryptoki project (see openCryptoki website
++http://sourceforge.net/projects/opencryptoki for more information). Some Linux
++distributions even ship those libraries with the system. The patch should work
++on any system that is supported by OpenSSL itself and has functional PKCS#11
++library.
+
-+typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
-+ CK_KEY_DERIVATION_STRING_DATA_PTR;
++The patch contains "RSA Security Inc. PKCS #11 Cryptographic Token Interface
++(Cryptoki)" - files cryptoki.h, pkcs11.h, pkcs11f.h and pkcs11t.h which are
++copyrighted by RSA Security Inc., see pkcs11.h for more information.
+
++Other added/modified code in this patch is copyrighted by Sun Microsystems,
++Inc. and is released under the OpenSSL license (see LICENSE file for more
++information).
+
-+/* The CK_EXTRACT_PARAMS is used for the
-+ * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit
-+ * of the base key should be used as the first bit of the
-+ * derived key */
-+/* CK_EXTRACT_PARAMS is new for v2.0 */
-+typedef CK_ULONG CK_EXTRACT_PARAMS;
++Revisions of the patch for 0.9.8 branch
++=======================================
+
-+typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
++2009-03-11
++- adjusted for OpenSSL version 0.9.8j
+
-+/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
-+ * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
-+ * indicate the Pseudo-Random Function (PRF) used to generate
-+ * key bits using PKCS #5 PBKDF2. */
-+typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
++- README.pkcs11 moved out of the patch, and is shipped together with it in a
++ tarball instead so that it can be read before the patch is applied.
+
-+typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
++- fixed bugs:
+
-+/* The following PRFs are defined in PKCS #5 v2.0. */
-+#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
++ 6804216 pkcs#11 engine should support a key length range for RC4
++ 6734038 Apache SSL web server using the pkcs11 engine fails to start if
++ meta slot is disabled
+
++2008-12-02
++- fixed bugs and RFEs (most of the work done by Vladimir Kotal)
+
-+/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
-+ * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
-+ * source of the salt value when deriving a key using PKCS #5
-+ * PBKDF2. */
-+typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
++ 6723504 more granular locking in PKCS#11 engine
++ 6667128 CRYPTO_LOCK_PK11_ENGINE assumption does not hold true
++ 6710420 PKCS#11 engine source should be lint clean
++ 6747327 PKCS#11 engine atfork handlers need to be aware of guys who take
++ it seriously
++ 6746712 PKCS#11 engine source code should be cstyle clean
++ 6731380 return codes of several functions are not checked in the PKCS#11
++ engine code
++ 6746735 PKCS#11 engine should use extended FILE space API
++ 6734038 Apache SSL web server using the pkcs11 engine fails to start if
++ meta slot is disabled
+
-+typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
++2008-08-01
++- fixed bug
+
-+/* The following salt value sources are defined in PKCS #5 v2.0. */
-+#define CKZ_SALT_SPECIFIED 0x00000001
++ 6731839 OpenSSL PKCS#11 engine no longer uses n2cp for symmetric ciphers
++ and digests
+
-+/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
-+ * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
-+ * parameters to the CKM_PKCS5_PBKD2 mechanism. */
-+typedef struct CK_PKCS5_PBKD2_PARAMS {
-+ CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
-+ CK_VOID_PTR pSaltSourceData;
-+ CK_ULONG ulSaltSourceDataLen;
-+ CK_ULONG iterations;
-+ CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
-+ CK_VOID_PTR pPrfData;
-+ CK_ULONG ulPrfDataLen;
-+ CK_UTF8CHAR_PTR pPassword;
-+ CK_ULONG_PTR ulPasswordLen;
-+} CK_PKCS5_PBKD2_PARAMS;
++- Solaris specific code for slot selection made automatic
+
-+typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
++2008-07-29
++- update the patch to OpenSSL 0.9.8h version
++- pkcs11t.h updated to the latest version:
+
-+/* All CK_OTP structs are new for PKCS #11 v2.20 amendment 3 */
++ 6545665 make CKM_AES_CTR available to non-kernel users
+
-+typedef CK_ULONG CK_OTP_PARAM_TYPE;
-+typedef CK_OTP_PARAM_TYPE CK_PARAM_TYPE; /* B/w compatibility */
++- fixed bugs in the engine code:
+
-+typedef struct CK_OTP_PARAM {
-+ CK_OTP_PARAM_TYPE type;
-+ CK_VOID_PTR pValue;
-+ CK_ULONG ulValueLen;
-+} CK_OTP_PARAM;
++ 6602801 PK11_SESSION cache has to employ reference counting scheme for
++ asymmetric key operations
++ 6605538 pkcs11 functions C_FindObjects[{Init,Final}]() not called
++ atomically
++ 6607307 pkcs#11 engine can't read RSA private keys
++ 6652362 pk11_RSA_finish() is cutting corners
++ 6662112 pk11_destroy_{rsa,dsa,dh}_key_objects() use locking in
++ suboptimal way
++ 6666625 pk11_destroy_{rsa,dsa,dh}_key_objects() should be more
++ resilient to destroy failures
++ 6667273 OpenSSL engine should not use free() but OPENSSL_free()
++ 6670363 PKCS#11 engine fails to reuse existing symmetric keys
++ 6678135 memory corruption in pk11_DH_generate_key() in pkcs#11 engine
++ 6678503 DSA signature conversion in pk11_dsa_do_verify() ignores size
++ of big numbers leading to failures
++ 6706562 pk11_DH_compute_key() returns 0 in case of failure instead of
++ -1
++ 6706622 pk11_load_{pub,priv}key create corrupted RSA key references
++ 6707129 return values from BN_new() in pk11_DH_generate_key() are not
++ checked
++ 6707274 DSA/RSA/DH PKCS#11 engine operations need to be resistant to
++ structure reuse
++ 6707782 OpenSSL PKCS#11 engine pretends to be aware of
++ OPENSSL_NO_{RSA,DSA,DH}
++ defines but fails miserably
++ 6709966 make check_new_*() to return values to indicate cache hit/miss
++ 6705200 pk11_dh struct initialization in PKCS#11 engine is missing
++ generate_params parameter
++ 6709513 PKCS#11 engine sets IV length even for ECB modes
++ 6728296 buffer length not initialized for C_(En|De)crypt_Final() in the
++ PKCS#11 engine
++ 6728871 PKCS#11 engine must reset global_session in pk11_finish()
+
-+typedef CK_OTP_PARAM CK_PTR CK_OTP_PARAM_PTR;
++- new features and enhancements:
+
-+typedef struct CK_OTP_PARAMS {
-+ CK_OTP_PARAM_PTR pParams;
-+ CK_ULONG ulCount;
-+} CK_OTP_PARAMS;
++ 6562155 OpenSSL pkcs#11 engine needs support for SHA224/256/384/512
++ 6685012 OpenSSL pkcs#11 engine needs support for new cipher modes
++ 6725903 OpenSSL PKCS#11 engine shouldn't use soft token for symmetric
++ ciphers and digests
+
-+typedef CK_OTP_PARAMS CK_PTR CK_OTP_PARAMS_PTR;
++2007-10-15
++- update for 0.9.8f version
++- update for "6607670 teach pkcs#11 engine how to use keys be reference"
+
-+typedef struct CK_OTP_SIGNATURE_INFO {
-+ CK_OTP_PARAM_PTR pParams;
-+ CK_ULONG ulCount;
-+} CK_OTP_SIGNATURE_INFO;
++2007-10-02
++- draft for "6607670 teach pkcs#11 engine how to use keys be reference"
++- draft for "6607307 pkcs#11 engine can't read RSA private keys"
+
-+typedef CK_OTP_SIGNATURE_INFO CK_PTR CK_OTP_SIGNATURE_INFO_PTR;
++2007-09-26
++- 6375348 Using pkcs11 as the SSLCryptoDevice with Apache/OpenSSL causes
++ significant performance drop
++- 6573196 memory is leaked when OpenSSL is used with PKCS#11 engine
+
-+/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */
-+#define CK_OTP_VALUE 0
-+#define CK_OTP_PIN 1
-+#define CK_OTP_CHALLENGE 2
-+#define CK_OTP_TIME 3
-+#define CK_OTP_COUNTER 4
-+#define CK_OTP_FLAGS 5
-+#define CK_OTP_OUTPUT_LENGTH 6
-+#define CK_OTP_OUTPUT_FORMAT 7
++2007-05-25
++- 6558630 race in OpenSSL pkcs11 engine when using symetric block ciphers
+
-+/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */
-+#define CKF_NEXT_OTP 0x00000001
-+#define CKF_EXCLUDE_TIME 0x00000002
-+#define CKF_EXCLUDE_COUNTER 0x00000004
-+#define CKF_EXCLUDE_CHALLENGE 0x00000008
-+#define CKF_EXCLUDE_PIN 0x00000010
-+#define CKF_USER_FRIENDLY_OTP 0x00000020
++2007-05-19
++- initial patch for 0.9.8e using latest OpenSolaris code
+
-+/* CK_KIP_PARAMS is new for PKCS #11 v2.20 amendment 2 */
-+typedef struct CK_KIP_PARAMS {
-+ CK_MECHANISM_PTR pMechanism;
-+ CK_OBJECT_HANDLE hKey;
-+ CK_BYTE_PTR pSeed;
-+ CK_ULONG ulSeedLen;
-+} CK_KIP_PARAMS;
++FAQs
++====
+
-+typedef CK_KIP_PARAMS CK_PTR CK_KIP_PARAMS_PTR;
++(1) my build failed on Linux distro with this error:
+
-+/* CK_AES_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
-+typedef struct CK_AES_CTR_PARAMS {
-+ CK_ULONG ulCounterBits;
-+ CK_BYTE cb[16];
-+} CK_AES_CTR_PARAMS;
++../libcrypto.a(hw_pk11.o): In function `pk11_library_init':
++hw_pk11.c:(.text+0x20f5): undefined reference to `pthread_atfork'
+
-+typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR;
++ - don't use "no-threads" when configuring
++ - if you didn't then OpenSSL failed to create a threaded library by
++ default. You may manually edit Configure and try again. Look for the
++ architecture that Configure printed, for example:
+
-+/* CK_CAMELLIA_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
-+typedef struct CK_CAMELLIA_CTR_PARAMS {
-+ CK_ULONG ulCounterBits;
-+ CK_BYTE cb[16];
-+} CK_CAMELLIA_CTR_PARAMS;
++Configured for linux-elf.
+
-+typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR;
++ - then edit Configure, find string "linux-elf" (inluding the quotes),
++ and add flags to support threads to the 4th column of the 2nd string.
++ If you build with GCC then adding "-pthread" should be enough. With
++ "linux-elf" as an example, you would add " -pthread" right after
++ "-D_REENTRANT", like this:
+
-+/* CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
-+typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS {
-+ CK_BYTE iv[16];
-+ CK_BYTE_PTR pData;
-+ CK_ULONG length;
-+} CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS;
++....-O3 -fomit-frame-pointer -Wall::-D_REENTRANT -pthread::-ldl:.....
+
-+typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
-+/* CK_ARIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
-+typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS {
-+ CK_BYTE iv[16];
-+ CK_BYTE_PTR pData;
-+ CK_ULONG length;
-+} CK_ARIA_CBC_ENCRYPT_DATA_PARAMS;
++Feedback
++========
+
-+typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
++Please send feedback to security-discuss@opensolaris.org. The patch was
++created by Jan.Pechanec@Sun.COM from code available in OpenSolaris.
+
-+#endif
-Index: openssl/util/libeay.num
-diff -u openssl/util/libeay.num:1.1.3.1 openssl/util/libeay.num:1.6
---- openssl/util/libeay.num:1.1.3.1 Mon Feb 2 00:27:56 2009
-+++ openssl/util/libeay.num Mon Oct 5 13:17:03 2009
-@@ -3725,3 +3725,5 @@
- JPAKE_STEP3A_init 4111 EXIST::FUNCTION:JPAKE
- ERR_load_JPAKE_strings 4112 EXIST::FUNCTION:JPAKE
- JPAKE_STEP2_init 4113 EXIST::FUNCTION:JPAKE
-+ENGINE_load_pk11ca 4114 EXIST::FUNCTION:HW_PKCS11CA,ENGINE
-+ENGINE_load_pk11so 4114 EXIST::FUNCTION:HW_PKCS11SO,ENGINE
-Index: openssl/util/mk1mf.pl
-diff -u openssl/util/mk1mf.pl:1.1.3.1 openssl/util/mk1mf.pl:1.7
---- openssl/util/mk1mf.pl:1.1.3.1 Tue Dec 2 23:50:21 2008
-+++ openssl/util/mk1mf.pl Mon Oct 5 13:17:05 2009
++Latest version should be always available on http://blogs.sun.com/janp.
++
+Index: openssl-0.9.8s/util/libeay.num
+diff -Nur openssl-0.9.8s/util/libeay.num openssl-0.9.8s-patched/util/libeay.num
+--- openssl-0.9.8s/util/libeay.num 2010-03-25 05:17:16.000000000 -0700
++++ openssl-0.9.8s-patched/util/libeay.num 2012-01-11 12:03:39.141837845 -0800
+@@ -3728,3 +3728,5 @@
+ pqueue_size 4114 EXIST::FUNCTION:
+ OPENSSL_uni2asc 4115 EXIST:NETWARE:FUNCTION:
+ OPENSSL_asc2uni 4116 EXIST:NETWARE:FUNCTION:
++ENGINE_load_pk11ca 4117 EXIST::FUNCTION:HW_PKCS11CA,ENGINE
++ENGINE_load_pk11so 4117 EXIST::FUNCTION:HW_PKCS11SO,ENGINE
+Index: openssl-0.9.8s/util/mk1mf.pl
+diff -Nur openssl-0.9.8s/util/mk1mf.pl openssl-0.9.8s-patched/util/mk1mf.pl
+--- openssl-0.9.8s/util/mk1mf.pl 2009-09-20 05:46:42.000000000 -0700
++++ openssl-0.9.8s-patched/util/mk1mf.pl 2012-01-11 12:03:39.141837845 -0800
@@ -87,6 +87,8 @@
no-ecdh - No ECDH
no-engine - No engine
if ($key eq "LIBZLIB")
{ $zlib_lib = "$val" if $val ne "";}
-@@ -1300,6 +1307,8 @@
+@@ -1301,6 +1308,8 @@
"no-ecdh" => \$no_ecdh,
"no-engine" => \$no_engine,
"no-hw" => \$no_hw,
"just-ssl" =>
[\$no_rc2, \$no_idea, \$no_des, \$no_bf, \$no_cast,
\$no_md2, \$no_sha, \$no_mdc2, \$no_dsa, \$no_dh,
-Index: openssl/util/mkdef.pl
-diff -u openssl/util/mkdef.pl:1.1.3.1 openssl/util/mkdef.pl:1.5
---- openssl/util/mkdef.pl:1.1.3.1 Mon Nov 24 16:14:15 2008
-+++ openssl/util/mkdef.pl Mon Oct 5 13:17:05 2009
+Index: openssl-0.9.8s/util/mkdef.pl
+diff -Nur openssl-0.9.8s/util/mkdef.pl openssl-0.9.8s-patched/util/mkdef.pl
+--- openssl-0.9.8s/util/mkdef.pl 2010-03-25 05:17:17.000000000 -0700
++++ openssl-0.9.8s-patched/util/mkdef.pl 2012-01-11 12:03:39.141837845 -0800
@@ -93,7 +93,7 @@
# External "algorithms"
"FP_API", "STDIO", "SOCK", "KRB5", "DGRAM",
}
-@@ -1138,6 +1141,8 @@
+@@ -1155,6 +1158,8 @@
if ($keyword eq "KRB5" && $no_krb5) { return 0; }
if ($keyword eq "ENGINE" && $no_engine) { return 0; }
if ($keyword eq "HW" && $no_hw) { return 0; }
if ($keyword eq "FP_API" && $no_fp_api) { return 0; }
if ($keyword eq "STATIC_ENGINE" && $no_static_engine) { return 0; }
if ($keyword eq "GMP" && $no_gmp) { return 0; }
-Index: openssl/util/pl/VC-32.pl
-diff -u openssl/util/pl/VC-32.pl:1.1.3.1 openssl/util/pl/VC-32.pl:1.5
---- openssl/util/pl/VC-32.pl:1.1.3.1 Mon Mar 9 12:14:08 2009
-+++ openssl/util/pl/VC-32.pl Fri Sep 4 10:43:23 2009
-@@ -113,7 +113,7 @@
+Index: openssl-0.9.8s/util/pl/VC-32.pl
+diff -Nur openssl-0.9.8s/util/pl/VC-32.pl openssl-0.9.8s-patched/util/pl/VC-32.pl
+--- openssl-0.9.8s/util/pl/VC-32.pl 2010-05-27 06:16:28.000000000 -0700
++++ openssl-0.9.8s-patched/util/pl/VC-32.pl 2012-01-11 12:03:39.141837845 -0800
+@@ -117,7 +117,7 @@
my $f = $shlib || $fips ?' /MD':' /MT';
$lib_cflag='/Zl' if (!$shlib); # remove /DEFAULTLIBs from static lib
$opt_cflags=$f.' /Ox /O2 /Ob2';