]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
rebase pkcs11 patch to openssl 0.9.8s
authorEvan Hunt <each@isc.org>
Wed, 11 Jan 2012 23:43:45 +0000 (23:43 +0000)
committerEvan Hunt <each@isc.org>
Wed, 11 Jan 2012 23:43:45 +0000 (23:43 +0000)
bin/pkcs11/openssl-0.9.8s-patch [moved from bin/pkcs11/openssl-0.9.8l-patch with 98% similarity]

similarity index 98%
rename from bin/pkcs11/openssl-0.9.8l-patch
rename to bin/pkcs11/openssl-0.9.8s-patch
index f410f468f193f2debee49e5d2537b14513488fdd..1ea4059795c755d4d7059119ea9ccb77e69606e3 100644 (file)
@@ -1,7 +1,7 @@
-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.
@@ -24,7 +24,7 @@ diff -u openssl/Configure:1.1.3.1 openssl/Configure:1.7
  # --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)",
@@ -33,16 +33,16 @@ diff -u openssl/Configure:1.1.3.1 openssl/Configure:1.7
  "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++;
  
@@ -51,9 +51,9 @@ diff -u openssl/Configure:1.1.3.1 openssl/Configure:1.7
 +my $pk11_flavor="";
 +
  my $prefix="";
+ my $libdir="";
  my $openssldir="";
- my $exe_ext="";
-@@ -812,6 +822,14 @@
+@@ -828,6 +838,14 @@
                                {
                                $flags.=$_." ";
                                }
@@ -68,7 +68,7 @@ diff -u openssl/Configure:1.1.3.1 openssl/Configure:1.7
                        elsif (/^--prefix=(.*)$/)
                                {
                                $prefix=$1;
-@@ -943,6 +961,22 @@
+@@ -963,6 +981,22 @@
        exit 0;
  }
  
@@ -91,7 +91,7 @@ diff -u openssl/Configure:1.1.3.1 openssl/Configure:1.7
  if ($target =~ m/^CygWin32(-.*)$/) {
        $target = "Cygwin".$1;
  }
-@@ -1057,6 +1091,25 @@
+@@ -1078,6 +1112,25 @@
        print "\n";
        }
  
@@ -117,7 +117,7 @@ diff -u openssl/Configure:1.1.3.1 openssl/Configure:1.7
  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;       }
  
@@ -126,7 +126,7 @@ diff -u openssl/Configure:1.1.3.1 openssl/Configure:1.7
  # 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/;
@@ -134,1835 +134,1374 @@ diff -u openssl/Configure:1.1.3.1 openssl/Configure:1.7
        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;
 +
@@ -4700,31 +4239,64 @@ diff -u /dev/null openssl/crypto/engine/hw_pk11.c:1.26
 +#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.
@@ -4964,10 +4536,10 @@ diff -u /dev/null openssl/crypto/engine/hw_pk11_err.c:1.4
 +      (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.
@@ -5371,10 +4943,10 @@ diff -u /dev/null openssl/crypto/engine/hw_pk11_err.h:1.9
 +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.
@@ -8516,43 +8088,10 @@ diff -u /dev/null openssl/crypto/engine/hw_pk11_pub.c:1.32
 +#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.
@@ -10172,10 +9711,10 @@ diff -u /dev/null openssl/crypto/engine/hw_pk11so.c:1.2
 +#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 */
 +
@@ -10205,10 +9744,10 @@ diff -u /dev/null openssl/crypto/engine/hw_pk11so.h:1.2
 +#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.
@@ -10948,478 +10487,298 @@ diff -u /dev/null openssl/crypto/engine/hw_pk11so_pub.c:1.2
 +              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
@@ -12221,122 +11580,426 @@ diff -u /dev/null openssl/crypto/engine/pkcs11f.h:1.1.1.1
 +#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
@@ -13772,468 +13435,807 @@ diff -u /dev/null openssl/crypto/engine/pkcs11t.h:1.2
 +  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
@@ -14262,7 +14264,7 @@ diff -u openssl/util/mk1mf.pl:1.1.3.1 openssl/util/mk1mf.pl:1.7
        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,
@@ -14271,10 +14273,10 @@ diff -u openssl/util/mk1mf.pl:1.1.3.1 openssl/util/mk1mf.pl:1.7
                "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",
@@ -14301,7 +14303,7 @@ diff -u openssl/util/mkdef.pl:1.1.3.1 openssl/util/mkdef.pl:1.5
        }
  
  
-@@ -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; }
@@ -14310,11 +14312,11 @@ diff -u openssl/util/mkdef.pl:1.1.3.1 openssl/util/mkdef.pl:1.5
                        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';