1Index: openssl/Configure
2diff -u openssl/Configure:1.8.6.1.4.1.2.1 openssl/Configure:1.8.2.2
3--- openssl/Configure:1.8.6.1.4.1.2.1	Thu Jul  3 12:12:31 2014
4+++ openssl/Configure	Thu Jul  3 12:31:57 2014
5@@ -12,7 +12,7 @@
6
7 # see INSTALL for instructions.
8
9-my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [experimental-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [enable-montasm] [no-asm] [no-dso] [no-krb5] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
10+my $usage="Usage: Configure --pk11-libname=PK11_LIB_LOCATION --pk11-flavor=FLAVOR [no-<cipher> ...] [enable-<cipher> ...] [experimental-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [enable-montasm] [no-asm] [no-dso] [no-krb5] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
11
12 # Options:
13 #
14@@ -25,6 +25,12 @@
15 #               default).  This needn't be set in advance, you can
16 #               just as well use "make INSTALL_PREFIX=/whatever install".
17 #
18+# --pk11-libname  PKCS#11 library name.
19+#               (No default)
20+#
21+# --pk11-flavor either crypto-accelerator or sign-only
22+#               (No default)
23+#
24 # --with-krb5-dir  Declare where Kerberos 5 lives.  The libraries are expected
25 #		to live in the subdirectory lib/ and the header files in
26 #		include/.  A value is required.
27@@ -336,7 +342,7 @@
28 "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)",
29 #### IA-32 targets...
30 "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)",
31-"linux-elf",	"gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
32+"linux-elf",	"gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT -pthread::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
33 "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}",
34 ####
35 "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)",
36@@ -344,7 +350,7 @@
37 "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)",
38 "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)",
39 "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)",
40-"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)",
41+"linux-x86_64",	"gcc:-m64 -DL_ENDIAN -DTERMIO -O3 -Wall -DMD32_REG_T=int::-D_REENTRANT -pthread::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_UNROLL:${x86_64_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
42 #### SPARC Linux setups
43 # Ray Miller <ray.miller@computing-services.oxford.ac.uk> has patiently
44 # assisted with debugging of following two configs.
45@@ -591,6 +597,10 @@
46 my $idx_ranlib = $idx++;
47 my $idx_arflags = $idx++;
48
49+# PKCS#11 engine patch
50+my $pk11_libname="";
51+my $pk11_flavor="";
52+
53 my $prefix="";
54 my $libdir="";
55 my $openssldir="";
56@@ -829,6 +839,14 @@
57 				{
58 				$flags.=$_." ";
59 				}
60+			elsif (/^--pk11-libname=(.*)$/)
61+				{
62+				$pk11_libname=$1;
63+				}
64+			elsif (/^--pk11-flavor=(.*)$/)
65+				{
66+				$pk11_flavor=$1;
67+				}
68 			elsif (/^--prefix=(.*)$/)
69 				{
70 				$prefix=$1;
71@@ -964,6 +982,22 @@
72 	exit 0;
73 }
74
75+if (! $pk11_libname)
76+        {
77+        print STDERR "You must set --pk11-libname for PKCS#11 library.\n";
78+        print STDERR "See README.pkcs11 for more information.\n";
79+        exit 1;
80+        }
81+
82+if (! $pk11_flavor
83+    || !($pk11_flavor eq "crypto-accelerator" || $pk11_flavor eq "sign-only"))
84+	{
85+	print STDERR "You must set --pk11-flavor.\n";
86+	print STDERR "Choices are crypto-accelerator and sign-only.\n";
87+	print STDERR "See README.pkcs11 for more information.\n";
88+	exit 1;
89+	}
90+
91 if ($target =~ m/^CygWin32(-.*)$/) {
92 	$target = "Cygwin".$1;
93 }
94@@ -1079,6 +1113,25 @@
95 	print "\n";
96 	}
97
98+if ($pk11_flavor eq "crypto-accelerator")
99+	{
100+	$openssl_other_defines .= "#define OPENSSL_NO_HW_PKCS11SO\n";
101+	$default_depflags .= " -DOPENSSL_NO_HW_PKCS11SO";
102+	$depflags .= " -DOPENSSL_NO_HW_PKCS11SO";
103+	$options .= " no-hw-pkcs11so";
104+	print "    no-hw-pkcs11so  [pk11-flavor]";
105+	print " OPENSSL_NO_HW_PKCS11SO\n";
106+	}
107+else
108+	{
109+	$openssl_other_defines .= "#define OPENSSL_NO_HW_PKCS11CA\n";
110+	$default_depflags .= " -DOPENSSL_NO_HW_PKCS11CA";
111+	$depflags .= " -DOPENSSL_NO_HW_PKCS11CA";
112+	$options .= " no-hw-pkcs11ca";
113+	print "    no-hw-pkcs11ca  [pk11-flavor]";
114+	print " OPENSSL_NO_HW_PKCS11CA\n";
115+}
116+
117 my $IsMK1MF=scalar grep /^$target$/,@MK1MF_Builds;
118
119 $IsMK1MF=1 if ($target eq "mingw" && $^O ne "cygwin" && !is_msys());
120@@ -1130,6 +1183,8 @@
121 if ($flags ne "")	{ $cflags="$flags$cflags"; }
122 else			{ $no_user_cflags=1;       }
123
124+$cflags="-DPK11_LIB_LOCATION=\"$pk11_libname\" $cflags";
125+
126 # Kerberos settings.  The flavor must be provided from outside, either through
127 # the script "config" or manually.
128 if (!$no_krb5)
129@@ -1493,6 +1548,7 @@
130 	s/^VERSION=.*/VERSION=$version/;
131 	s/^MAJOR=.*/MAJOR=$major/;
132 	s/^MINOR=.*/MINOR=$minor/;
133+	s/^PK11_LIB_LOCATION=.*/PK11_LIB_LOCATION=$pk11_libname/;
134 	s/^SHLIB_VERSION_NUMBER=.*/SHLIB_VERSION_NUMBER=$shlib_version_number/;
135 	s/^SHLIB_VERSION_HISTORY=.*/SHLIB_VERSION_HISTORY=$shlib_version_history/;
136 	s/^SHLIB_MAJOR=.*/SHLIB_MAJOR=$shlib_major/;
137Index: openssl/Makefile.org
138diff -u openssl/Makefile.org:1.4.6.1.6.1 openssl/Makefile.org:1.4.2.1
139--- openssl/Makefile.org:1.4.6.1.6.1	Thu Jul  3 12:12:31 2014
140+++ openssl/Makefile.org	Thu Jul  3 12:31:58 2014
141@@ -26,6 +26,9 @@
142 INSTALL_PREFIX=
143 INSTALLTOP=/usr/local/ssl
144
145+# You must set this through --pk11-libname configure option.
146+PK11_LIB_LOCATION=
147+
148 # Do not edit this manually. Use Configure --openssldir=DIR do change this!
149 OPENSSLDIR=/usr/local/ssl
150
151Index: openssl/README.pkcs11
152diff -u /dev/null openssl/README.pkcs11:1.6.4.2
153--- /dev/null	Fri Jan  2 13:56:40 2015
154+++ openssl/README.pkcs11	Fri Oct  4 14:45:25 2013
155@@ -0,0 +1,266 @@
156+ISC modified
157+============
158+
159+The previous key naming scheme was kept for backward compatibility.
160+
161+The PKCS#11 engine exists in two flavors, crypto-accelerator and
162+sign-only. The first one is from the Solaris patch and uses the
163+PKCS#11 device for all crypto operations it supports. The second
164+is a stripped down version which provides only the useful
165+function (i.e., signature with a RSA private key in the device
166+protected key store and key loading).
167+
168+As a hint PKCS#11 boards should use the crypto-accelerator flavor,
169+external PKCS#11 devices the sign-only. SCA 6000 is an example
170+of the first, AEP Keyper of the second.
171+
172+Note it is mandatory to set a pk11-flavor (and only one) in
173+config/Configure.
174+
175+It is highly recommended to compile in (vs. as a DSO) the engine.
176+The way to configure this is system dependent, on Unixes it is no-shared
177+(and is in general the default), on WIN32 it is enable-static-engine
178+(and still enable to build the OpenSSL libraries as DLLs).
179+
180+PKCS#11 engine support for OpenSSL 0.9.8l
181+=========================================
182+
183+[Nov 19, 2009]
184+
185+Contents:
186+
187+Overview
188+Revisions of the patch for 0.9.8 branch
189+FAQs
190+Feedback
191+
192+Overview
193+========
194+
195+This patch containing code available in OpenSolaris adds support for PKCS#11
196+engine into OpenSSL and implements PKCS#11 v2.20. It is to be applied against
197+OpenSSL 0.9.8l source code distribution as shipped by OpenSSL.Org. Your system
198+must provide PKCS#11 backend otherwise the patch is useless. You provide the
199+PKCS#11 library name during the build configuration phase, see below.
200+
201+Patch can be applied like this:
202+
203+	# NOTE: use gtar if on Solaris
204+	tar xfzv openssl-0.9.8l.tar.gz
205+	# now download the patch to the current directory
206+	# ...
207+	cd openssl-0.9.8l
208+	# NOTE: must use gpatch if on Solaris (is part of the system)
209+	patch -p1 < path-to/pkcs11_engine-0.9.8l.patch.2009-11-19
210+
211+It is designed to support pure acceleration for RSA, DSA, DH and all the
212+symetric ciphers and message digest algorithms that PKCS#11 and OpenSSL share
213+except for missing support for patented algorithms MDC2, RC3, RC5 and IDEA.
214+
215+According to the PKCS#11 providers installed on your machine, it can support
216+following mechanisms:
217+
218+	RSA, DSA, DH, RAND, DES-CBC, DES-EDE3-CBC, DES-ECB, DES-EDE3, RC4,
219+	AES-128-CBC, AES-192-CBC, AES-256-CBC, AES-128-ECB, AES-192-ECB,
220+	AES-256-ECB, AES-128-CTR, AES-192-CTR, AES-256-CTR, MD5, SHA1, SHA224,
221+	SHA256, SHA384, SHA512
222+
223+Note that for AES counter mode the application must provide their own EVP
224+functions since OpenSSL doesn't support counter mode through EVP yet. You may
225+see OpenSSH source code (cipher.c) to get the idea how to do that. SunSSH is an
226+example of code that uses the PKCS#11 engine and deals with the fork-safety
227+problem (see engine.c and packet.c files if interested).
228+
229+You must provide the location of PKCS#11 library in your system to the
230+configure script. You will be instructed to do that when you try to run the
231+config script:
232+
233+	$ ./config
234+	Operating system: i86pc-whatever-solaris2
235+	Configuring for solaris-x86-cc
236+	You must set --pk11-libname for PKCS#11 library.
237+	See README.pkcs11 for more information.
238+
239+Taking openCryptoki project on Linux AMD64 box as an example, you would run
240+configure script like this:
241+
242+	./config --pk11-libname=/usr/lib64/pkcs11/PKCS11_API.so
243+
244+To check whether newly built openssl really supports PKCS#11 it's enough to run
245+"apps/openssl engine" and look for "(pkcs11) PKCS #11 engine support" in the
246+output. If you see no PKCS#11 engine support check that the built openssl binary
247+and the PKCS#11 library from --pk11-libname don't conflict on 32/64 bits.
248+
249+The patch, during various phases of development, was tested on Solaris against
250+PKCS#11 engine available from Solaris Cryptographic Framework (Solaris 10 and
251+OpenSolaris) and also on Linux using PKCS#11 libraries from openCryptoki project
252+(see openCryptoki website http://sourceforge.net/projects/opencryptoki for more
253+information). Some Linux distributions even ship those libraries with the
254+system. The patch should work on any system that is supported by OpenSSL itself
255+and has functional PKCS#11 library.
256+
257+The patch contains "RSA Security Inc. PKCS #11 Cryptographic Token Interface
258+(Cryptoki)" - files cryptoki.h, pkcs11.h, pkcs11f.h and pkcs11t.h which are
259+copyrighted by RSA Security Inc., see pkcs11.h for more information.
260+
261+Other added/modified code in this patch is copyrighted by Sun Microsystems,
262+Inc. and is released under the OpenSSL license (see LICENSE file for more
263+information).
264+
265+Revisions of the patch for 0.9.8 branch
266+=======================================
267+
268+2009-11-19
269+- adjusted for OpenSSL version 0.9.8l
270+
271+- bugs and RFEs:
272+
273+	6479874 OpenSSL should support RSA key by reference/hardware keystores
274+	6896677 PKCS#11 engine's hw_pk11_err.h needs to be split
275+	6732677 make check to trigger Solaris specific code automatic in the
276+		PKCS#11 engine
277+
278+2009-03-11
279+- adjusted for OpenSSL version 0.9.8j
280+
281+- README.pkcs11 moved out of the patch, and is shipped together with it in a
282+  tarball instead so that it can be read before the patch is applied.
283+
284+- fixed bugs:
285+
286+	6804216 pkcs#11 engine should support a key length range for RC4
287+	6734038 Apache SSL web server using the pkcs11 engine fails to start if
288+		meta slot is disabled
289+
290+2008-12-02
291+- fixed bugs and RFEs (most of the work done by Vladimir Kotal)
292+
293+	6723504 more granular locking in PKCS#11 engine
294+	6667128 CRYPTO_LOCK_PK11_ENGINE assumption does not hold true
295+	6710420 PKCS#11 engine source should be lint clean
296+	6747327 PKCS#11 engine atfork handlers need to be aware of guys who take
297+		it seriously
298+	6746712 PKCS#11 engine source code should be cstyle clean
299+	6731380 return codes of several functions are not checked in the PKCS#11
300+		engine code
301+	6746735 PKCS#11 engine should use extended FILE space API
302+	6734038 Apache SSL web server using the pkcs11 engine fails to start if
303+		meta slot is disabled
304+
305+2008-08-01
306+- fixed bug
307+
308+	6731839 OpenSSL PKCS#11 engine no longer uses n2cp for symmetric ciphers
309+		and digests
310+
311+- Solaris specific code for slot selection made automatic
312+
313+2008-07-29
314+- update the patch to OpenSSL 0.9.8h version
315+- pkcs11t.h updated to the latest version:
316+
317+	6545665 make CKM_AES_CTR available to non-kernel users
318+
319+- fixed bugs in the engine code:
320+
321+	6602801 PK11_SESSION cache has to employ reference counting scheme for
322+		asymmetric key operations
323+	6605538 pkcs11 functions C_FindObjects[{Init,Final}]() not called
324+		atomically
325+	6607307 pkcs#11 engine can't read RSA private keys
326+	6652362 pk11_RSA_finish() is cutting corners
327+	6662112 pk11_destroy_{rsa,dsa,dh}_key_objects() use locking in
328+		suboptimal way
329+	6666625 pk11_destroy_{rsa,dsa,dh}_key_objects() should be more
330+		resilient to destroy failures
331+	6667273 OpenSSL engine should not use free() but OPENSSL_free()
332+	6670363 PKCS#11 engine fails to reuse existing symmetric keys
333+	6678135 memory corruption in pk11_DH_generate_key() in pkcs#11 engine
334+	6678503 DSA signature conversion in pk11_dsa_do_verify() ignores size
335+		of big numbers leading to failures
336+	6706562 pk11_DH_compute_key() returns 0 in case of failure instead of
337+		-1
338+	6706622 pk11_load_{pub,priv}key create corrupted RSA key references
339+	6707129 return values from BN_new() in pk11_DH_generate_key() are not
340+		checked
341+	6707274 DSA/RSA/DH PKCS#11 engine operations need to be resistant to
342+		structure reuse
343+	6707782 OpenSSL PKCS#11 engine pretends to be aware of
344+		OPENSSL_NO_{RSA,DSA,DH}
345+	defines but fails miserably
346+	6709966 make check_new_*() to return values to indicate cache hit/miss
347+	6705200 pk11_dh struct initialization in PKCS#11 engine is missing
348+		generate_params parameter
349+	6709513 PKCS#11 engine sets IV length even for ECB modes
350+	6728296 buffer length not initialized for C_(En|De)crypt_Final() in the
351+		PKCS#11 engine
352+	6728871 PKCS#11 engine must reset global_session in pk11_finish()
353+
354+- new features and enhancements:
355+
356+	6562155 OpenSSL pkcs#11 engine needs support for SHA224/256/384/512
357+	6685012 OpenSSL pkcs#11 engine needs support for new cipher modes
358+	6725903 OpenSSL PKCS#11 engine shouldn't use soft token for symmetric
359+		ciphers and digests
360+
361+2007-10-15
362+- update for 0.9.8f version
363+- update for "6607670 teach pkcs#11 engine how to use keys be reference"
364+
365+2007-10-02
366+- draft for "6607670 teach pkcs#11 engine how to use keys be reference"
367+- draft for "6607307 pkcs#11 engine can't read RSA private keys"
368+
369+2007-09-26
370+- 6375348 Using pkcs11 as the SSLCryptoDevice with Apache/OpenSSL causes
371+	  significant performance drop
372+- 6573196 memory is leaked when OpenSSL is used with PKCS#11 engine
373+
374+2007-05-25
375+- 6558630 race in OpenSSL pkcs11 engine when using symetric block ciphers
376+
377+2007-05-19
378+- initial patch for 0.9.8e using latest OpenSolaris code
379+
380+FAQs
381+====
382+
383+(1) my build failed on Linux distro with this error:
384+
385+../libcrypto.a(hw_pk11.o): In function `pk11_library_init':
386+hw_pk11.c:(.text+0x20f5): undefined reference to `pthread_atfork'
387+
388+Answer:
389+
390+	- don't use "no-threads" when configuring
391+	- if you didn't then OpenSSL failed to create a threaded library by
392+	  default. You may manually edit Configure and try again. Look for the
393+	  architecture that Configure printed, for example:
394+
395+Configured for linux-elf.
396+
397+	- then edit Configure, find string "linux-elf" (inluding the quotes),
398+	  and add flags to support threads to the 4th column of the 2nd string.
399+	  If you build with GCC then adding "-pthread" should be enough. With
400+	  "linux-elf" as an example, you would add " -pthread" right after
401+	  "-D_REENTRANT", like this:
402+
403+....-O3 -fomit-frame-pointer -Wall::-D_REENTRANT -pthread::-ldl:.....
404+
405+(2) I'm using MinGW/MSYS environment and get undeclared reference error for
406+pthread_atfork() function when trying to build OpenSSL with the patch.
407+
408+Answer:
409+
410+	Sorry, pthread_atfork() is not implemented in the current pthread-win32
411+	(as of Nov 2009). You can not use the patch there.
412+
413+
414+Feedback
415+========
416+
417+Please send feedback to security-discuss@opensolaris.org. The patch was
418+created by Jan.Pechanec@Sun.COM from code available in OpenSolaris.
419+
420+Latest version should be always available on http://blogs.sun.com/janp.
421+
422Index: openssl/crypto/opensslconf.h
423diff -u openssl/crypto/opensslconf.h:1.5.10.1 openssl/crypto/opensslconf.h:1.5
424--- openssl/crypto/opensslconf.h:1.5.10.1	Sun Jan 15 15:45:34 2012
425+++ openssl/crypto/opensslconf.h	Fri Sep  4 10:43:21 2009
426@@ -38,6 +38,9 @@
427
428 #endif /* OPENSSL_DOING_MAKEDEPEND */
429
430+#ifndef OPENSSL_THREADS
431+# define OPENSSL_THREADS
432+#endif
433 #ifndef OPENSSL_NO_DYNAMIC_ENGINE
434 # define OPENSSL_NO_DYNAMIC_ENGINE
435 #endif
436@@ -79,6 +82,8 @@
437 # endif
438 #endif
439
440+#define OPENSSL_CPUID_OBJ
441+
442 /* crypto/opensslconf.h.in */
443
444 #ifdef OPENSSL_DOING_MAKEDEPEND
445@@ -140,7 +145,7 @@
446  * This enables code handling data aligned at natural CPU word
447  * boundary. See crypto/rc4/rc4_enc.c for further details.
448  */
449-#undef RC4_CHUNK
450+#define RC4_CHUNK unsigned long
451 #endif
452 #endif
453
454@@ -148,7 +153,7 @@
455 /* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
456  * %20 speed up (longs are 8 bytes, int's are 4). */
457 #ifndef DES_LONG
458-#define DES_LONG unsigned long
459+#define DES_LONG unsigned int
460 #endif
461 #endif
462
463@@ -162,9 +167,9 @@
464 /* The prime number generation stuff may not work when
465  * EIGHT_BIT but I don't care since I've only used this mode
466  * for debuging the bignum libraries */
467-#undef SIXTY_FOUR_BIT_LONG
468+#define SIXTY_FOUR_BIT_LONG
469 #undef SIXTY_FOUR_BIT
470-#define THIRTY_TWO_BIT
471+#undef THIRTY_TWO_BIT
472 #undef SIXTEEN_BIT
473 #undef EIGHT_BIT
474 #endif
475@@ -178,7 +183,7 @@
476
477 #if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
478 #define CONFIG_HEADER_BF_LOCL_H
479-#undef BF_PTR
480+#define BF_PTR2
481 #endif /* HEADER_BF_LOCL_H */
482
483 #if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
484@@ -208,7 +213,7 @@
485 /* Unroll the inner loop, this sometimes helps, sometimes hinders.
486  * Very mucy CPU dependant */
487 #ifndef DES_UNROLL
488-#undef DES_UNROLL
489+#define DES_UNROLL
490 #endif
491
492 /* These default values were supplied by
493Index: openssl/crypto/bio/bss_file.c
494diff -u openssl/crypto/bio/bss_file.c:1.5.6.1 openssl/crypto/bio/bss_file.c:1.5
495--- openssl/crypto/bio/bss_file.c:1.5.6.1	Sun Jan 15 15:45:35 2012
496+++ openssl/crypto/bio/bss_file.c	Mon Jun 13 14:25:17 2011
497@@ -125,7 +125,7 @@
498 		{
499 		SYSerr(SYS_F_FOPEN,get_last_sys_error());
500 		ERR_add_error_data(5,"fopen('",filename,"','",mode,"')");
501-		if (errno == ENOENT)
502+		if ((errno == ENOENT) || ((*mode == 'r') && (errno == EACCES)))
503 			BIOerr(BIO_F_BIO_NEW_FILE,BIO_R_NO_SUCH_FILE);
504 		else
505 			BIOerr(BIO_F_BIO_NEW_FILE,ERR_R_SYS_LIB);
506Index: openssl/crypto/engine/Makefile
507diff -u openssl/crypto/engine/Makefile:1.6.6.1 openssl/crypto/engine/Makefile:1.6
508--- openssl/crypto/engine/Makefile:1.6.6.1	Sun Jan 15 15:45:35 2012
509+++ openssl/crypto/engine/Makefile	Mon Jun 13 14:25:19 2011
510@@ -21,12 +21,14 @@
511 	eng_table.c eng_pkey.c eng_fat.c eng_all.c \
512 	tb_rsa.c tb_dsa.c tb_ecdsa.c tb_dh.c tb_ecdh.c tb_rand.c tb_store.c \
513 	tb_cipher.c tb_digest.c \
514-	eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c eng_padlock.c
515+	eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c eng_padlock.c \
516+	hw_pk11.c hw_pk11_pub.c hw_pk11so.c hw_pk11so_pub.c
517 LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \
518 	eng_table.o eng_pkey.o eng_fat.o eng_all.o \
519 	tb_rsa.o tb_dsa.o tb_ecdsa.o tb_dh.o tb_ecdh.o tb_rand.o tb_store.o \
520 	tb_cipher.o tb_digest.o \
521-	eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o eng_padlock.o
522+	eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o eng_padlock.o \
523+	hw_pk11.o hw_pk11_pub.o hw_pk11so.o hw_pk11so_pub.o
524
525 SRC= $(LIBSRC)
526
527@@ -288,6 +290,102 @@
528 eng_table.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
529 eng_table.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
530 eng_table.o: eng_table.c
531+hw_pk11.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
532+hw_pk11.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
533+hw_pk11.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
534+hw_pk11.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
535+hw_pk11.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
536+hw_pk11.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
537+hw_pk11.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
538+hw_pk11.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
539+hw_pk11.o: ../../include/openssl/ui.h ../../include/openssl/err.h
540+hw_pk11.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
541+hw_pk11.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
542+hw_pk11.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
543+hw_pk11.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
544+hw_pk11.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
545+hw_pk11.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
546+hw_pk11.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
547+hw_pk11.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
548+hw_pk11.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
549+hw_pk11.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
550+hw_pk11.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
551+hw_pk11.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
552+hw_pk11.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
553+hw_pk11.o: ../../include/openssl/pem2.h ../cryptlib.h
554+hw_pk11.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11.c
555+hw_pk11_pub.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
556+hw_pk11_pub.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
557+hw_pk11_pub.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
558+hw_pk11_pub.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
559+hw_pk11_pub.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
560+hw_pk11_pub.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
561+hw_pk11_pub.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
562+hw_pk11_pub.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
563+hw_pk11_pub.o: ../../include/openssl/ui.h ../../include/openssl/err.h
564+hw_pk11_pub.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
565+hw_pk11_pub.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
566+hw_pk11_pub.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
567+hw_pk11_pub.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
568+hw_pk11_pub.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
569+hw_pk11_pub.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
570+hw_pk11_pub.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
571+hw_pk11_pub.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
572+hw_pk11_pub.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
573+hw_pk11_pub.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
574+hw_pk11_pub.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
575+hw_pk11_pub.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
576+hw_pk11_pub.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
577+hw_pk11_pub.o: ../../include/openssl/pem2.h ../cryptlib.h
578+hw_pk11_pub.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11_pub.c
579+hw_pk11so.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
580+hw_pk11so.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
581+hw_pk11so.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
582+hw_pk11so.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
583+hw_pk11so.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
584+hw_pk11so.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
585+hw_pk11so.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
586+hw_pk11so.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
587+hw_pk11so.o: ../../include/openssl/ui.h ../../include/openssl/err.h
588+hw_pk11so.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
589+hw_pk11so.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
590+hw_pk11so.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
591+hw_pk11so.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
592+hw_pk11so.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
593+hw_pk11so.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
594+hw_pk11so.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
595+hw_pk11so.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
596+hw_pk11so.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
597+hw_pk11so.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
598+hw_pk11so.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
599+hw_pk11so.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
600+hw_pk11so.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
601+hw_pk11so.o: ../../include/openssl/pem2.h ../cryptlib.h
602+hw_pk11so.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11so.c
603+hw_pk11so_pub.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
604+hw_pk11so_pub.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
605+hw_pk11so_pub.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
606+hw_pk11so_pub.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
607+hw_pk11so_pub.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
608+hw_pk11so_pub.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
609+hw_pk11so_pub.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
610+hw_pk11so_pub.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
611+hw_pk11so_pub.o: ../../include/openssl/ui.h ../../include/openssl/err.h
612+hw_pk11so_pub.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
613+hw_pk11so_pub.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
614+hw_pk11so_pub.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
615+hw_pk11so_pub.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
616+hw_pk11so_pub.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
617+hw_pk11so_pub.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
618+hw_pk11so_pub.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
619+hw_pk11so_pub.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
620+hw_pk11so_pub.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
621+hw_pk11so_pub.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
622+hw_pk11so_pub.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
623+hw_pk11so_pub.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
624+hw_pk11so_pub.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
625+hw_pk11so_pub.o: ../../include/openssl/pem2.h ../cryptlib.h
626+hw_pk11so_pub.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11so_pub.c
627 tb_cipher.o: ../../e_os.h ../../include/openssl/asn1.h
628 tb_cipher.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
629 tb_cipher.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
630Index: openssl/crypto/engine/cryptoki.h
631diff -u /dev/null openssl/crypto/engine/cryptoki.h:1.4
632--- /dev/null	Fri Jan  2 13:56:40 2015
633+++ openssl/crypto/engine/cryptoki.h	Thu Dec 18 00:14:12 2008
634@@ -0,0 +1,103 @@
635+/*
636+ * CDDL HEADER START
637+ *
638+ * The contents of this file are subject to the terms of the
639+ * Common Development and Distribution License, Version 1.0 only
640+ * (the "License").  You may not use this file except in compliance
641+ * with the License.
642+ *
643+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
644+ * or http://www.opensolaris.org/os/licensing.
645+ * See the License for the specific language governing permissions
646+ * and limitations under the License.
647+ *
648+ * When distributing Covered Code, include this CDDL HEADER in each
649+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
650+ * If applicable, add the following below this CDDL HEADER, with the
651+ * fields enclosed by brackets "[]" replaced with your own identifying
652+ * information: Portions Copyright [yyyy] [name of copyright owner]
653+ *
654+ * CDDL HEADER END
655+ */
656+/*
657+ * Copyright 2003 Sun Microsystems, Inc.   All rights reserved.
658+ * Use is subject to license terms.
659+ */
660+
661+#ifndef	_CRYPTOKI_H
662+#define	_CRYPTOKI_H
663+
664+/* ident	"@(#)cryptoki.h	1.2	05/06/08 SMI" */
665+
666+#ifdef	__cplusplus
667+extern "C" {
668+#endif
669+
670+#ifndef	CK_PTR
671+#define	CK_PTR *
672+#endif
673+
674+#ifndef CK_DEFINE_FUNCTION
675+#define	CK_DEFINE_FUNCTION(returnType, name) returnType name
676+#endif
677+
678+#ifndef CK_DECLARE_FUNCTION
679+#define	CK_DECLARE_FUNCTION(returnType, name) returnType name
680+#endif
681+
682+#ifndef CK_DECLARE_FUNCTION_POINTER
683+#define	CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
684+#endif
685+
686+#ifndef CK_CALLBACK_FUNCTION
687+#define	CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
688+#endif
689+
690+#ifndef NULL_PTR
691+#include <unistd.h>	/* For NULL */
692+#define	NULL_PTR NULL
693+#endif
694+
695+/*
696+ * pkcs11t.h defines TRUE and FALSE in a way that upsets lint
697+ */
698+#ifndef	CK_DISABLE_TRUE_FALSE
699+#define	CK_DISABLE_TRUE_FALSE
700+#ifndef	TRUE
701+#define	TRUE	1
702+#endif /* TRUE */
703+#ifndef	FALSE
704+#define	FALSE	0
705+#endif /* FALSE */
706+#endif /* CK_DISABLE_TRUE_FALSE */
707+
708+#undef CK_PKCS11_FUNCTION_INFO
709+
710+#include "pkcs11.h"
711+
712+/* Solaris specific functions */
713+
714+#include <stdlib.h>
715+
716+/*
717+ * SUNW_C_GetMechSession will initialize the framework and do all
718+ * the necessary PKCS#11 calls to create a session capable of
719+ * providing operations on the requested mechanism
720+ */
721+CK_RV SUNW_C_GetMechSession(CK_MECHANISM_TYPE mech,
722+    CK_SESSION_HANDLE_PTR hSession);
723+
724+/*
725+ * SUNW_C_KeyToObject will create a secret key object for the given
726+ * mechanism from the rawkey data.
727+ */
728+CK_RV SUNW_C_KeyToObject(CK_SESSION_HANDLE hSession,
729+    CK_MECHANISM_TYPE mech, const void *rawkey, size_t rawkey_len,
730+    CK_OBJECT_HANDLE_PTR obj);
731+
732+
733+#ifdef	__cplusplus
734+}
735+#endif
736+
737+#endif	/* _CRYPTOKI_H */
738Index: openssl/crypto/engine/eng_all.c
739diff -u openssl/crypto/engine/eng_all.c:1.4.6.1.6.1 openssl/crypto/engine/eng_all.c:1.4.2.1
740--- openssl/crypto/engine/eng_all.c:1.4.6.1.6.1	Thu Jul  3 12:12:33 2014
741+++ openssl/crypto/engine/eng_all.c	Thu Jul  3 12:31:59 2014
742@@ -110,6 +110,14 @@
743 #if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
744 	ENGINE_load_cryptodev();
745 #endif
746+#ifndef OPENSSL_NO_HW_PKCS11
747+#ifndef OPENSSL_NO_HW_PKCS11CA
748+	ENGINE_load_pk11ca();
749+#endif
750+#ifndef OPENSSL_NO_HW_PKCS11SO
751+	ENGINE_load_pk11so();
752+#endif
753+#endif
754 #endif
755 	}
756
757Index: openssl/crypto/engine/engine.h
758diff -u openssl/crypto/engine/engine.h:1.4.6.1.6.1 openssl/crypto/engine/engine.h:1.4.2.1
759--- openssl/crypto/engine/engine.h:1.4.6.1.6.1	Thu Jul  3 12:12:33 2014
760+++ openssl/crypto/engine/engine.h	Thu Jul  3 12:32:00 2014
761@@ -344,6 +344,12 @@
762 void ENGINE_load_cryptodev(void);
763 void ENGINE_load_padlock(void);
764 void ENGINE_load_builtin_engines(void);
765+#ifndef OPENSSL_NO_HW_PKCS11CA
766+void ENGINE_load_pk11ca(void);
767+#endif
768+#ifndef OPENSSL_NO_HW_PKCS11SO
769+void ENGINE_load_pk11so(void);
770+#endif
771
772 /* Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation
773  * "registry" handling. */
774Index: openssl/crypto/engine/hw_pk11.c
775diff -u /dev/null openssl/crypto/engine/hw_pk11.c:1.26.4.4
776--- /dev/null	Fri Jan  2 13:56:40 2015
777+++ openssl/crypto/engine/hw_pk11.c	Fri Oct  4 14:45:25 2013
778@@ -0,0 +1,4116 @@
779+/*
780+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
781+ * Use is subject to license terms.
782+ */
783+
784+/* crypto/engine/hw_pk11.c */
785+/*
786+ * This product includes software developed by the OpenSSL Project for
787+ * use in the OpenSSL Toolkit (http://www.openssl.org/).
788+ *
789+ * This project also referenced hw_pkcs11-0.9.7b.patch written by
790+ * Afchine Madjlessi.
791+ */
792+/*
793+ * ====================================================================
794+ * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
795+ *
796+ * Redistribution and use in source and binary forms, with or without
797+ * modification, are permitted provided that the following conditions
798+ * are met:
799+ *
800+ * 1. Redistributions of source code must retain the above copyright
801+ *    notice, this list of conditions and the following disclaimer.
802+ *
803+ * 2. Redistributions in binary form must reproduce the above copyright
804+ *    notice, this list of conditions and the following disclaimer in
805+ *    the documentation and/or other materials provided with the
806+ *    distribution.
807+ *
808+ * 3. All advertising materials mentioning features or use of this
809+ *    software must display the following acknowledgment:
810+ *    "This product includes software developed by the OpenSSL Project
811+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
812+ *
813+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
814+ *    endorse or promote products derived from this software without
815+ *    prior written permission. For written permission, please contact
816+ *    licensing@OpenSSL.org.
817+ *
818+ * 5. Products derived from this software may not be called "OpenSSL"
819+ *    nor may "OpenSSL" appear in their names without prior written
820+ *    permission of the OpenSSL Project.
821+ *
822+ * 6. Redistributions of any form whatsoever must retain the following
823+ *    acknowledgment:
824+ *    "This product includes software developed by the OpenSSL Project
825+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
826+ *
827+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
828+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
829+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
830+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
831+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
832+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
833+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
834+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
835+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
836+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
837+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
838+ * OF THE POSSIBILITY OF SUCH DAMAGE.
839+ * ====================================================================
840+ *
841+ * This product includes cryptographic software written by Eric Young
842+ * (eay@cryptsoft.com).  This product includes software written by Tim
843+ * Hudson (tjh@cryptsoft.com).
844+ *
845+ */
846+
847+#include <stdio.h>
848+#include <stdlib.h>
849+#include <string.h>
850+#include <sys/types.h>
851+
852+#include <openssl/e_os2.h>
853+#include <openssl/crypto.h>
854+#include <cryptlib.h>
855+#include <openssl/engine.h>
856+#include <openssl/dso.h>
857+#include <openssl/err.h>
858+#include <openssl/bn.h>
859+#include <openssl/md5.h>
860+#include <openssl/pem.h>
861+#ifndef OPENSSL_NO_RSA
862+#include <openssl/rsa.h>
863+#endif
864+#ifndef OPENSSL_NO_DSA
865+#include <openssl/dsa.h>
866+#endif
867+#ifndef OPENSSL_NO_DH
868+#include <openssl/dh.h>
869+#endif
870+#include <openssl/rand.h>
871+#include <openssl/objects.h>
872+#include <openssl/x509.h>
873+#include <openssl/aes.h>
874+#include <openssl/des.h>
875+
876+#ifdef OPENSSL_SYS_WIN32
877+typedef int pid_t;
878+#define getpid() GetCurrentProcessId()
879+#define NOPTHREADS
880+#ifndef NULL_PTR
881+#define NULL_PTR NULL
882+#endif
883+#define CK_DEFINE_FUNCTION(returnType, name) \
884+	returnType __declspec(dllexport) name
885+#define CK_DECLARE_FUNCTION(returnType, name) \
886+	returnType __declspec(dllimport) name
887+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
888+	returnType __declspec(dllimport) (* name)
889+#else
890+#include <signal.h>
891+#include <unistd.h>
892+#include <dlfcn.h>
893+#endif
894+
895+/* Debug mutexes */
896+/*#undef DEBUG_MUTEX */
897+#define DEBUG_MUTEX
898+
899+#ifndef NOPTHREADS
900+/* for pthread error check on Linuxes */
901+#ifdef DEBUG_MUTEX
902+#define __USE_UNIX98
903+#endif
904+#include <pthread.h>
905+#endif
906+
907+#ifndef OPENSSL_NO_HW
908+#ifndef OPENSSL_NO_HW_PK11
909+#ifndef OPENSSL_NO_HW_PK11CA
910+
911+/* label for debug messages printed on stderr */
912+#define	PK11_DBG	"PKCS#11 ENGINE DEBUG"
913+/* prints a lot of debug messages on stderr about slot selection process */
914+/* #undef	DEBUG_SLOT_SELECTION */
915+/*
916+ * Solaris specific code. See comment at check_hw_mechanisms() for more
917+ * information.
918+ */
919+#if defined(__SVR4) && defined(__sun)
920+#undef	SOLARIS_HW_SLOT_SELECTION
921+#endif
922+
923+/*
924+ * AES counter mode is not supported in the OpenSSL EVP API yet and neither
925+ * there are official OIDs for mechanisms based on this mode. With our changes,
926+ * an application can define its own EVP calls for AES counter mode and then
927+ * it can make use of hardware acceleration through this engine. However, it's
928+ * better if we keep AES CTR support code under ifdef's.
929+ */
930+#define	SOLARIS_AES_CTR
931+
932+#ifdef OPENSSL_SYS_WIN32
933+#pragma pack(push, cryptoki, 1)
934+#include "cryptoki.h"
935+#include "pkcs11.h"
936+#pragma pack(pop, cryptoki)
937+#else
938+#include "cryptoki.h"
939+#include "pkcs11.h"
940+#endif
941+#include "hw_pk11ca.h"
942+#include "hw_pk11_err.c"
943+
944+#ifdef	SOLARIS_AES_CTR
945+/*
946+ * NIDs for AES counter mode that will be defined during the engine
947+ * initialization.
948+ */
949+static int NID_aes_128_ctr = NID_undef;
950+static int NID_aes_192_ctr = NID_undef;
951+static int NID_aes_256_ctr = NID_undef;
952+#endif	/* SOLARIS_AES_CTR */
953+
954+/*
955+ * We use this lock to prevent multiple C_Login()s, guard getpassphrase(),
956+ * uri_struct manipulation, and static token info. All of that is used by the
957+ * RSA keys by reference feature.
958+ */
959+#ifndef NOPTHREADS
960+pthread_mutex_t *token_lock;
961+#endif
962+
963+#ifdef	SOLARIS_HW_SLOT_SELECTION
964+/*
965+ * Tables for symmetric ciphers and digest mechs found in the pkcs11_kernel
966+ * library. See comment at check_hw_mechanisms() for more information.
967+ */
968+static int *hw_cnids;
969+static int *hw_dnids;
970+#endif	/* SOLARIS_HW_SLOT_SELECTION */
971+
972+/* PKCS#11 session caches and their locks for all operation types */
973+static PK11_CACHE session_cache[OP_MAX];
974+
975+/*
976+ * We cache the flags so that we do not have to run C_GetTokenInfo() again when
977+ * logging into the token.
978+ */
979+CK_FLAGS pubkey_token_flags;
980+
981+/*
982+ * As stated in v2.20, 11.7 Object Management Function, in section for
983+ * C_FindObjectsInit(), at most one search operation may be active at a given
984+ * time in a given session. Therefore, C_Find{,Init,Final}Objects() should be
985+ * grouped together to form one atomic search operation. This is already
986+ * ensured by the property of unique PKCS#11 session handle used for each
987+ * PK11_SESSION object.
988+ *
989+ * This is however not the biggest concern - maintaining consistency of the
990+ * underlying object store is more important. The same section of the spec also
991+ * says that one thread can be in the middle of a search operation while another
992+ * thread destroys the object matching the search template which would result in
993+ * invalid handle returned from the search operation.
994+ *
995+ * Hence, the following locks are used for both protection of the object stores.
996+ * They are also used for active list protection.
997+ */
998+#ifndef NOPTHREADS
999+pthread_mutex_t *find_lock[OP_MAX] = { NULL };
1000+#endif
1001+
1002+/*
1003+ * lists of asymmetric key handles which are active (referenced by at least one
1004+ * PK11_SESSION structure, either held by a thread or present in free_session
1005+ * list) for given algorithm type
1006+ */
1007+PK11_active *active_list[OP_MAX] = { NULL };
1008+
1009+/*
1010+ * Create all secret key objects in a global session so that they are available
1011+ * to use for other sessions. These other sessions may be opened or closed
1012+ * without losing the secret key objects.
1013+ */
1014+static CK_SESSION_HANDLE	global_session = CK_INVALID_HANDLE;
1015+
1016+/* ENGINE level stuff */
1017+static int pk11_init(ENGINE *e);
1018+static int pk11_library_init(ENGINE *e);
1019+static int pk11_finish(ENGINE *e);
1020+static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
1021+static int pk11_destroy(ENGINE *e);
1022+
1023+/* RAND stuff */
1024+static void pk11_rand_seed(const void *buf, int num);
1025+static void pk11_rand_add(const void *buf, int num, double add_entropy);
1026+static void pk11_rand_cleanup(void);
1027+static int pk11_rand_bytes(unsigned char *buf, int num);
1028+static int pk11_rand_status(void);
1029+
1030+/* These functions are also used in other files */
1031+PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
1032+void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
1033+
1034+/* active list manipulation functions used in this file */
1035+extern int pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type);
1036+extern void pk11_free_active_list(PK11_OPTYPE type);
1037+
1038+#ifndef OPENSSL_NO_RSA
1039+int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
1040+int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
1041+int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
1042+#endif
1043+#ifndef OPENSSL_NO_DSA
1044+int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
1045+int pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
1046+int pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
1047+#endif
1048+#ifndef OPENSSL_NO_DH
1049+int pk11_destroy_dh_key_objects(PK11_SESSION *session);
1050+int pk11_destroy_dh_object(PK11_SESSION *session, CK_BBOOL uselock);
1051+#endif
1052+
1053+/* Local helper functions */
1054+static int pk11_free_all_sessions(void);
1055+static int pk11_free_session_list(PK11_OPTYPE optype);
1056+static int pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype);
1057+static int pk11_destroy_cipher_key_objects(PK11_SESSION *session);
1058+static int pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
1059+	CK_BBOOL persistent);
1060+static const char *get_PK11_LIBNAME(void);
1061+static void free_PK11_LIBNAME(void);
1062+static long set_PK11_LIBNAME(const char *name);
1063+
1064+/* Symmetric cipher and digest support functions */
1065+static int cipher_nid_to_pk11(int nid);
1066+#ifdef	SOLARIS_AES_CTR
1067+static int pk11_add_NID(char *sn, char *ln);
1068+static int pk11_add_aes_ctr_NIDs(void);
1069+#endif	/* SOLARIS_AES_CTR */
1070+static int pk11_usable_ciphers(const int **nids);
1071+static int pk11_usable_digests(const int **nids);
1072+static int pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
1073+	const unsigned char *iv, int enc);
1074+static int pk11_cipher_final(PK11_SESSION *sp);
1075+#if OPENSSL_VERSION_NUMBER < 0x10000000L
1076+static int pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
1077+	const unsigned char *in, unsigned int inl);
1078+#else
1079+static int pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
1080+	const unsigned char *in, size_t inl);
1081+#endif
1082+static int pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx);
1083+static int pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
1084+	const int **nids, int nid);
1085+static int pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
1086+	const int **nids, int nid);
1087+static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
1088+	const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp);
1089+static int check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key,
1090+	int key_len);
1091+static int md_nid_to_pk11(int nid);
1092+static int pk11_digest_init(EVP_MD_CTX *ctx);
1093+static int pk11_digest_update(EVP_MD_CTX *ctx, const void *data,
1094+	size_t count);
1095+static int pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md);
1096+static int pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);
1097+static int pk11_digest_cleanup(EVP_MD_CTX *ctx);
1098+
1099+static int pk11_choose_slots(int *any_slot_found);
1100+static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
1101+    CK_SLOT_ID current_slot, int *current_slot_n_cipher,
1102+    int *local_cipher_nids);
1103+static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
1104+    CK_SLOT_ID current_slot, int *current_slot_n_digest,
1105+    int *local_digest_nids);
1106+static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR, int slot_id,
1107+    CK_MECHANISM_TYPE mech, int *current_slot_n_cipher, int *local_cipher_nids,
1108+    int id);
1109+static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
1110+    CK_MECHANISM_TYPE mech, int *current_slot_n_digest, int *local_digest_nids,
1111+    int id);
1112+
1113+static int pk11_init_all_locks(void);
1114+static void pk11_free_all_locks(void);
1115+
1116+#ifdef	SOLARIS_HW_SLOT_SELECTION
1117+static int check_hw_mechanisms(void);
1118+static int nid_in_table(int nid, int *nid_table);
1119+#endif	/* SOLARIS_HW_SLOT_SELECTION */
1120+
1121+/* Index for the supported ciphers */
1122+enum pk11_cipher_id {
1123+	PK11_DES_CBC,
1124+	PK11_DES3_CBC,
1125+	PK11_DES_ECB,
1126+	PK11_DES3_ECB,
1127+	PK11_RC4,
1128+	PK11_AES_128_CBC,
1129+	PK11_AES_192_CBC,
1130+	PK11_AES_256_CBC,
1131+	PK11_AES_128_ECB,
1132+	PK11_AES_192_ECB,
1133+	PK11_AES_256_ECB,
1134+	PK11_BLOWFISH_CBC,
1135+#ifdef	SOLARIS_AES_CTR
1136+	PK11_AES_128_CTR,
1137+	PK11_AES_192_CTR,
1138+	PK11_AES_256_CTR,
1139+#endif	/* SOLARIS_AES_CTR */
1140+	PK11_CIPHER_MAX
1141+};
1142+
1143+/* Index for the supported digests */
1144+enum pk11_digest_id {
1145+	PK11_MD5,
1146+	PK11_SHA1,
1147+	PK11_SHA224,
1148+	PK11_SHA256,
1149+	PK11_SHA384,
1150+	PK11_SHA512,
1151+	PK11_DIGEST_MAX
1152+};
1153+
1154+#define	TRY_OBJ_DESTROY(sp, obj_hdl, retval, uselock, alg_type, priv)	\
1155+	{								\
1156+	if (uselock)							\
1157+		LOCK_OBJSTORE(alg_type);				\
1158+	if (pk11_active_delete(obj_hdl, alg_type) == 1)			\
1159+		{							\
1160+		  retval = pk11_destroy_object(sp->session, obj_hdl,	\
1161+		  priv ? sp->priv_persistent : sp->pub_persistent);	\
1162+		}							\
1163+	if (uselock)							\
1164+		UNLOCK_OBJSTORE(alg_type);				\
1165+	}
1166+
1167+static int cipher_nids[PK11_CIPHER_MAX];
1168+static int digest_nids[PK11_DIGEST_MAX];
1169+static int cipher_count		= 0;
1170+static int digest_count		= 0;
1171+static CK_BBOOL pk11_have_rsa	= CK_FALSE;
1172+static CK_BBOOL pk11_have_recover = CK_FALSE;
1173+static CK_BBOOL pk11_have_dsa	= CK_FALSE;
1174+static CK_BBOOL pk11_have_dh	= CK_FALSE;
1175+static CK_BBOOL pk11_have_random = CK_FALSE;
1176+
1177+typedef struct PK11_CIPHER_st
1178+	{
1179+	enum pk11_cipher_id	id;
1180+	int			nid;
1181+	int			iv_len;
1182+	int			min_key_len;
1183+	int			max_key_len;
1184+	CK_KEY_TYPE		key_type;
1185+	CK_MECHANISM_TYPE	mech_type;
1186+	} PK11_CIPHER;
1187+
1188+static PK11_CIPHER ciphers[] =
1189+	{
1190+	{ PK11_DES_CBC,		NID_des_cbc,		8,	 8,   8,
1191+		CKK_DES,	CKM_DES_CBC, },
1192+	{ PK11_DES3_CBC,	NID_des_ede3_cbc,	8,	24,  24,
1193+		CKK_DES3,	CKM_DES3_CBC, },
1194+	{ PK11_DES_ECB,		NID_des_ecb,		0,	 8,   8,
1195+		CKK_DES,	CKM_DES_ECB, },
1196+	{ PK11_DES3_ECB,	NID_des_ede3_ecb,	0,	24,  24,
1197+		CKK_DES3,	CKM_DES3_ECB, },
1198+	{ PK11_RC4,		NID_rc4,		0,	16, 256,
1199+		CKK_RC4,	CKM_RC4, },
1200+	{ PK11_AES_128_CBC,	NID_aes_128_cbc,	16,	16,  16,
1201+		CKK_AES,	CKM_AES_CBC, },
1202+	{ PK11_AES_192_CBC,	NID_aes_192_cbc,	16,	24,  24,
1203+		CKK_AES,	CKM_AES_CBC, },
1204+	{ PK11_AES_256_CBC,	NID_aes_256_cbc,	16,	32,  32,
1205+		CKK_AES,	CKM_AES_CBC, },
1206+	{ PK11_AES_128_ECB,	NID_aes_128_ecb,	0,	16,  16,
1207+		CKK_AES,	CKM_AES_ECB, },
1208+	{ PK11_AES_192_ECB,	NID_aes_192_ecb,	0,	24,  24,
1209+		CKK_AES,	CKM_AES_ECB, },
1210+	{ PK11_AES_256_ECB,	NID_aes_256_ecb,	0,	32,  32,
1211+		CKK_AES,	CKM_AES_ECB, },
1212+	{ PK11_BLOWFISH_CBC,	NID_bf_cbc,		8,	16,  16,
1213+		CKK_BLOWFISH,	CKM_BLOWFISH_CBC, },
1214+#ifdef	SOLARIS_AES_CTR
1215+	/* we don't know the correct NIDs until the engine is initialized */
1216+	{ PK11_AES_128_CTR,	NID_undef,		16,	16,  16,
1217+		CKK_AES,	CKM_AES_CTR, },
1218+	{ PK11_AES_192_CTR,	NID_undef,		16,	24,  24,
1219+		CKK_AES,	CKM_AES_CTR, },
1220+	{ PK11_AES_256_CTR,	NID_undef,		16,	32,  32,
1221+		CKK_AES,	CKM_AES_CTR, },
1222+#endif	/* SOLARIS_AES_CTR */
1223+	};
1224+
1225+typedef struct PK11_DIGEST_st
1226+	{
1227+	enum pk11_digest_id	id;
1228+	int			nid;
1229+	CK_MECHANISM_TYPE	mech_type;
1230+	} PK11_DIGEST;
1231+
1232+static PK11_DIGEST digests[] =
1233+	{
1234+	{PK11_MD5,	NID_md5,	CKM_MD5, },
1235+	{PK11_SHA1,	NID_sha1,	CKM_SHA_1, },
1236+	{PK11_SHA224,	NID_sha224,	CKM_SHA224, },
1237+	{PK11_SHA256,	NID_sha256,	CKM_SHA256, },
1238+	{PK11_SHA384,	NID_sha384,	CKM_SHA384, },
1239+	{PK11_SHA512,	NID_sha512,	CKM_SHA512, },
1240+	{0,		NID_undef,	0xFFFF, },
1241+	};
1242+
1243+/*
1244+ * Structure to be used for the cipher_data/md_data in
1245+ * EVP_CIPHER_CTX/EVP_MD_CTX structures in order to use the same pk11
1246+ * session in multiple cipher_update calls
1247+ */
1248+typedef struct PK11_CIPHER_STATE_st
1249+	{
1250+	PK11_SESSION	*sp;
1251+	} PK11_CIPHER_STATE;
1252+
1253+
1254+/*
1255+ * libcrypto EVP stuff - this is how we get wired to EVP so the engine gets
1256+ * called when libcrypto requests a cipher NID.
1257+ *
1258+ * Note how the PK11_CIPHER_STATE is used here.
1259+ */
1260+
1261+/* DES CBC EVP */
1262+static const EVP_CIPHER pk11_des_cbc =
1263+	{
1264+	NID_des_cbc,
1265+	8, 8, 8,
1266+	EVP_CIPH_CBC_MODE,
1267+	pk11_cipher_init,
1268+	pk11_cipher_do_cipher,
1269+	pk11_cipher_cleanup,
1270+	sizeof (PK11_CIPHER_STATE),
1271+	EVP_CIPHER_set_asn1_iv,
1272+	EVP_CIPHER_get_asn1_iv,
1273+	NULL
1274+	};
1275+
1276+/* 3DES CBC EVP */
1277+static const EVP_CIPHER pk11_3des_cbc =
1278+	{
1279+	NID_des_ede3_cbc,
1280+	8, 24, 8,
1281+	EVP_CIPH_CBC_MODE,
1282+	pk11_cipher_init,
1283+	pk11_cipher_do_cipher,
1284+	pk11_cipher_cleanup,
1285+	sizeof (PK11_CIPHER_STATE),
1286+	EVP_CIPHER_set_asn1_iv,
1287+	EVP_CIPHER_get_asn1_iv,
1288+	NULL
1289+	};
1290+
1291+/*
1292+ * ECB modes don't use an Initial Vector so that's why set_asn1_parameters and
1293+ * get_asn1_parameters fields are set to NULL.
1294+ */
1295+static const EVP_CIPHER pk11_des_ecb =
1296+	{
1297+	NID_des_ecb,
1298+	8, 8, 8,
1299+	EVP_CIPH_ECB_MODE,
1300+	pk11_cipher_init,
1301+	pk11_cipher_do_cipher,
1302+	pk11_cipher_cleanup,
1303+	sizeof (PK11_CIPHER_STATE),
1304+	NULL,
1305+	NULL,
1306+	NULL
1307+	};
1308+
1309+static const EVP_CIPHER pk11_3des_ecb =
1310+	{
1311+	NID_des_ede3_ecb,
1312+	8, 24, 8,
1313+	EVP_CIPH_ECB_MODE,
1314+	pk11_cipher_init,
1315+	pk11_cipher_do_cipher,
1316+	pk11_cipher_cleanup,
1317+	sizeof (PK11_CIPHER_STATE),
1318+	NULL,
1319+	NULL,
1320+	NULL
1321+	};
1322+
1323+
1324+static const EVP_CIPHER pk11_aes_128_cbc =
1325+	{
1326+	NID_aes_128_cbc,
1327+	16, 16, 16,
1328+	EVP_CIPH_CBC_MODE,
1329+	pk11_cipher_init,
1330+	pk11_cipher_do_cipher,
1331+	pk11_cipher_cleanup,
1332+	sizeof (PK11_CIPHER_STATE),
1333+	EVP_CIPHER_set_asn1_iv,
1334+	EVP_CIPHER_get_asn1_iv,
1335+	NULL
1336+	};
1337+
1338+static const EVP_CIPHER pk11_aes_192_cbc =
1339+	{
1340+	NID_aes_192_cbc,
1341+	16, 24, 16,
1342+	EVP_CIPH_CBC_MODE,
1343+	pk11_cipher_init,
1344+	pk11_cipher_do_cipher,
1345+	pk11_cipher_cleanup,
1346+	sizeof (PK11_CIPHER_STATE),
1347+	EVP_CIPHER_set_asn1_iv,
1348+	EVP_CIPHER_get_asn1_iv,
1349+	NULL
1350+	};
1351+
1352+static const EVP_CIPHER pk11_aes_256_cbc =
1353+	{
1354+	NID_aes_256_cbc,
1355+	16, 32, 16,
1356+	EVP_CIPH_CBC_MODE,
1357+	pk11_cipher_init,
1358+	pk11_cipher_do_cipher,
1359+	pk11_cipher_cleanup,
1360+	sizeof (PK11_CIPHER_STATE),
1361+	EVP_CIPHER_set_asn1_iv,
1362+	EVP_CIPHER_get_asn1_iv,
1363+	NULL
1364+	};
1365+
1366+/*
1367+ * ECB modes don't use IV so that's why set_asn1_parameters and
1368+ * get_asn1_parameters are set to NULL.
1369+ */
1370+static const EVP_CIPHER pk11_aes_128_ecb =
1371+	{
1372+	NID_aes_128_ecb,
1373+	16, 16, 0,
1374+	EVP_CIPH_ECB_MODE,
1375+	pk11_cipher_init,
1376+	pk11_cipher_do_cipher,
1377+	pk11_cipher_cleanup,
1378+	sizeof (PK11_CIPHER_STATE),
1379+	NULL,
1380+	NULL,
1381+	NULL
1382+	};
1383+
1384+static const EVP_CIPHER pk11_aes_192_ecb =
1385+	{
1386+	NID_aes_192_ecb,
1387+	16, 24, 0,
1388+	EVP_CIPH_ECB_MODE,
1389+	pk11_cipher_init,
1390+	pk11_cipher_do_cipher,
1391+	pk11_cipher_cleanup,
1392+	sizeof (PK11_CIPHER_STATE),
1393+	NULL,
1394+	NULL,
1395+	NULL
1396+	};
1397+
1398+static const EVP_CIPHER pk11_aes_256_ecb =
1399+	{
1400+	NID_aes_256_ecb,
1401+	16, 32, 0,
1402+	EVP_CIPH_ECB_MODE,
1403+	pk11_cipher_init,
1404+	pk11_cipher_do_cipher,
1405+	pk11_cipher_cleanup,
1406+	sizeof (PK11_CIPHER_STATE),
1407+	NULL,
1408+	NULL,
1409+	NULL
1410+	};
1411+
1412+#ifdef	SOLARIS_AES_CTR
1413+/*
1414+ * NID_undef's will be changed to the AES counter mode NIDs as soon they are
1415+ * created in pk11_library_init(). Note that the need to change these structures
1416+ * is the reason why we don't define them with the const keyword.
1417+ */
1418+static EVP_CIPHER pk11_aes_128_ctr =
1419+	{
1420+	NID_undef,
1421+	16, 16, 16,
1422+	EVP_CIPH_CBC_MODE,
1423+	pk11_cipher_init,
1424+	pk11_cipher_do_cipher,
1425+	pk11_cipher_cleanup,
1426+	sizeof (PK11_CIPHER_STATE),
1427+	EVP_CIPHER_set_asn1_iv,
1428+	EVP_CIPHER_get_asn1_iv,
1429+	NULL
1430+	};
1431+
1432+static EVP_CIPHER pk11_aes_192_ctr =
1433+	{
1434+	NID_undef,
1435+	16, 24, 16,
1436+	EVP_CIPH_CBC_MODE,
1437+	pk11_cipher_init,
1438+	pk11_cipher_do_cipher,
1439+	pk11_cipher_cleanup,
1440+	sizeof (PK11_CIPHER_STATE),
1441+	EVP_CIPHER_set_asn1_iv,
1442+	EVP_CIPHER_get_asn1_iv,
1443+	NULL
1444+	};
1445+
1446+static EVP_CIPHER pk11_aes_256_ctr =
1447+	{
1448+	NID_undef,
1449+	16, 32, 16,
1450+	EVP_CIPH_CBC_MODE,
1451+	pk11_cipher_init,
1452+	pk11_cipher_do_cipher,
1453+	pk11_cipher_cleanup,
1454+	sizeof (PK11_CIPHER_STATE),
1455+	EVP_CIPHER_set_asn1_iv,
1456+	EVP_CIPHER_get_asn1_iv,
1457+	NULL
1458+	};
1459+#endif	/* SOLARIS_AES_CTR */
1460+
1461+static const EVP_CIPHER pk11_bf_cbc =
1462+	{
1463+	NID_bf_cbc,
1464+	8, 16, 8,
1465+	EVP_CIPH_VARIABLE_LENGTH,
1466+	pk11_cipher_init,
1467+	pk11_cipher_do_cipher,
1468+	pk11_cipher_cleanup,
1469+	sizeof (PK11_CIPHER_STATE),
1470+	EVP_CIPHER_set_asn1_iv,
1471+	EVP_CIPHER_get_asn1_iv,
1472+	NULL
1473+	};
1474+
1475+static const EVP_CIPHER pk11_rc4 =
1476+	{
1477+	NID_rc4,
1478+	1, 16, 0,
1479+	EVP_CIPH_VARIABLE_LENGTH,
1480+	pk11_cipher_init,
1481+	pk11_cipher_do_cipher,
1482+	pk11_cipher_cleanup,
1483+	sizeof (PK11_CIPHER_STATE),
1484+	NULL,
1485+	NULL,
1486+	NULL
1487+	};
1488+
1489+static const EVP_MD pk11_md5 =
1490+	{
1491+	NID_md5,
1492+	NID_md5WithRSAEncryption,
1493+	MD5_DIGEST_LENGTH,
1494+	0,
1495+	pk11_digest_init,
1496+	pk11_digest_update,
1497+	pk11_digest_final,
1498+	pk11_digest_copy,
1499+	pk11_digest_cleanup,
1500+	EVP_PKEY_RSA_method,
1501+	MD5_CBLOCK,
1502+	sizeof (PK11_CIPHER_STATE),
1503+	};
1504+
1505+static const EVP_MD pk11_sha1 =
1506+	{
1507+	NID_sha1,
1508+	NID_sha1WithRSAEncryption,
1509+	SHA_DIGEST_LENGTH,
1510+	0,
1511+	pk11_digest_init,
1512+	pk11_digest_update,
1513+	pk11_digest_final,
1514+	pk11_digest_copy,
1515+	pk11_digest_cleanup,
1516+	EVP_PKEY_RSA_method,
1517+	SHA_CBLOCK,
1518+	sizeof (PK11_CIPHER_STATE),
1519+	};
1520+
1521+static const EVP_MD pk11_sha224 =
1522+	{
1523+	NID_sha224,
1524+	NID_sha224WithRSAEncryption,
1525+	SHA224_DIGEST_LENGTH,
1526+	0,
1527+	pk11_digest_init,
1528+	pk11_digest_update,
1529+	pk11_digest_final,
1530+	pk11_digest_copy,
1531+	pk11_digest_cleanup,
1532+	EVP_PKEY_RSA_method,
1533+	/* SHA-224 uses the same cblock size as SHA-256 */
1534+	SHA256_CBLOCK,
1535+	sizeof (PK11_CIPHER_STATE),
1536+	};
1537+
1538+static const EVP_MD pk11_sha256 =
1539+	{
1540+	NID_sha256,
1541+	NID_sha256WithRSAEncryption,
1542+	SHA256_DIGEST_LENGTH,
1543+	0,
1544+	pk11_digest_init,
1545+	pk11_digest_update,
1546+	pk11_digest_final,
1547+	pk11_digest_copy,
1548+	pk11_digest_cleanup,
1549+	EVP_PKEY_RSA_method,
1550+	SHA256_CBLOCK,
1551+	sizeof (PK11_CIPHER_STATE),
1552+	};
1553+
1554+static const EVP_MD pk11_sha384 =
1555+	{
1556+	NID_sha384,
1557+	NID_sha384WithRSAEncryption,
1558+	SHA384_DIGEST_LENGTH,
1559+	0,
1560+	pk11_digest_init,
1561+	pk11_digest_update,
1562+	pk11_digest_final,
1563+	pk11_digest_copy,
1564+	pk11_digest_cleanup,
1565+	EVP_PKEY_RSA_method,
1566+	/* SHA-384 uses the same cblock size as SHA-512 */
1567+	SHA512_CBLOCK,
1568+	sizeof (PK11_CIPHER_STATE),
1569+	};
1570+
1571+static const EVP_MD pk11_sha512 =
1572+	{
1573+	NID_sha512,
1574+	NID_sha512WithRSAEncryption,
1575+	SHA512_DIGEST_LENGTH,
1576+	0,
1577+	pk11_digest_init,
1578+	pk11_digest_update,
1579+	pk11_digest_final,
1580+	pk11_digest_copy,
1581+	pk11_digest_cleanup,
1582+	EVP_PKEY_RSA_method,
1583+	SHA512_CBLOCK,
1584+	sizeof (PK11_CIPHER_STATE),
1585+	};
1586+
1587+/*
1588+ * Initialization function. Sets up various PKCS#11 library components.
1589+ * The definitions for control commands specific to this engine
1590+ */
1591+#define PK11_CMD_SO_PATH		ENGINE_CMD_BASE
1592+#define PK11_CMD_PIN			(ENGINE_CMD_BASE+1)
1593+#define PK11_CMD_SLOT			(ENGINE_CMD_BASE+2)
1594+static const ENGINE_CMD_DEFN pk11_cmd_defns[] =
1595+	{
1596+		{
1597+		PK11_CMD_SO_PATH,
1598+		"SO_PATH",
1599+		"Specifies the path to the 'pkcs#11' shared library",
1600+		ENGINE_CMD_FLAG_STRING
1601+		},
1602+		{
1603+		PK11_CMD_PIN,
1604+		"PIN",
1605+		"Specifies the pin code",
1606+		ENGINE_CMD_FLAG_STRING
1607+		},
1608+		{
1609+		PK11_CMD_SLOT,
1610+		"SLOT",
1611+		"Specifies the slot (default is auto select)",
1612+		ENGINE_CMD_FLAG_NUMERIC,
1613+		},
1614+		{0, NULL, NULL, 0}
1615+	};
1616+
1617+
1618+static RAND_METHOD pk11_random =
1619+	{
1620+	pk11_rand_seed,
1621+	pk11_rand_bytes,
1622+	pk11_rand_cleanup,
1623+	pk11_rand_add,
1624+	pk11_rand_bytes,
1625+	pk11_rand_status
1626+	};
1627+
1628+
1629+/* Constants used when creating the ENGINE */
1630+#ifdef OPENSSL_NO_HW_PK11SO
1631+#error "can't load both crypto-accelerator and sign-only PKCS#11 engines"
1632+#endif
1633+static const char *engine_pk11_id = "pkcs11";
1634+static const char *engine_pk11_name =
1635+	"PKCS #11 engine support (crypto accelerator)";
1636+
1637+CK_FUNCTION_LIST_PTR pFuncList = NULL;
1638+static const char PK11_GET_FUNCTION_LIST[] = "C_GetFunctionList";
1639+
1640+/*
1641+ * This is a static string constant for the DSO file name and the function
1642+ * symbol names to bind to. We set it in the Configure script based on whether
1643+ * this is 32 or 64 bit build.
1644+ */
1645+static const char def_PK11_LIBNAME[] = PK11_LIB_LOCATION;
1646+
1647+static CK_BBOOL mytrue = TRUE;
1648+static CK_BBOOL myfalse = FALSE;
1649+/* Needed in hw_pk11_pub.c as well so that's why it is not static. */
1650+CK_SLOT_ID pubkey_SLOTID = 0;
1651+static CK_SLOT_ID rand_SLOTID = 0;
1652+static CK_SLOT_ID SLOTID = 0;
1653+char *pk11_pin = NULL;
1654+static CK_BBOOL pk11_library_initialized = FALSE;
1655+static CK_BBOOL pk11_atfork_initialized = FALSE;
1656+static int pk11_pid = 0;
1657+
1658+static DSO *pk11_dso = NULL;
1659+
1660+/* allocate and initialize all locks used by the engine itself */
1661+static int pk11_init_all_locks(void)
1662+	{
1663+#ifndef NOPTHREADS
1664+	int type;
1665+	pthread_mutexattr_t attr;
1666+
1667+	if (pthread_mutexattr_init(&attr) != 0)
1668+	{
1669+		PK11err(PK11_F_INIT_ALL_LOCKS, 100);
1670+		return (0);
1671+	}
1672+
1673+#ifdef DEBUG_MUTEX
1674+	if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0)
1675+	{
1676+		PK11err(PK11_F_INIT_ALL_LOCKS, 101);
1677+		return (0);
1678+	}
1679+#endif
1680+
1681+	if ((token_lock = OPENSSL_malloc(sizeof (pthread_mutex_t))) == NULL)
1682+		goto malloc_err;
1683+	(void) pthread_mutex_init(token_lock, &attr);
1684+
1685+#ifndef OPENSSL_NO_RSA
1686+	find_lock[OP_RSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
1687+	if (find_lock[OP_RSA] == NULL)
1688+		goto malloc_err;
1689+	(void) pthread_mutex_init(find_lock[OP_RSA], &attr);
1690+#endif /* OPENSSL_NO_RSA */
1691+
1692+#ifndef OPENSSL_NO_DSA
1693+	find_lock[OP_DSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
1694+	if (find_lock[OP_DSA] == NULL)
1695+		goto malloc_err;
1696+	(void) pthread_mutex_init(find_lock[OP_DSA], &attr);
1697+#endif /* OPENSSL_NO_DSA */
1698+
1699+#ifndef OPENSSL_NO_DH
1700+	find_lock[OP_DH] = OPENSSL_malloc(sizeof (pthread_mutex_t));
1701+	if (find_lock[OP_DH] == NULL)
1702+		goto malloc_err;
1703+	(void) pthread_mutex_init(find_lock[OP_DH], &attr);
1704+#endif /* OPENSSL_NO_DH */
1705+
1706+	for (type = 0; type < OP_MAX; type++)
1707+		{
1708+		session_cache[type].lock =
1709+		    OPENSSL_malloc(sizeof (pthread_mutex_t));
1710+		if (session_cache[type].lock == NULL)
1711+			goto malloc_err;
1712+		(void) pthread_mutex_init(session_cache[type].lock, &attr);
1713+		}
1714+
1715+	return (1);
1716+
1717+malloc_err:
1718+	pk11_free_all_locks();
1719+	PK11err(PK11_F_INIT_ALL_LOCKS, PK11_R_MALLOC_FAILURE);
1720+	return (0);
1721+#else
1722+	return (1);
1723+#endif
1724+	}
1725+
1726+static void pk11_free_all_locks(void)
1727+	{
1728+#ifndef NOPTHREADS
1729+	int type;
1730+
1731+	if (token_lock != NULL)
1732+		{
1733+		(void) pthread_mutex_destroy(token_lock);
1734+		OPENSSL_free(token_lock);
1735+		token_lock = NULL;
1736+		}
1737+
1738+#ifndef OPENSSL_NO_RSA
1739+	if (find_lock[OP_RSA] != NULL)
1740+		{
1741+		(void) pthread_mutex_destroy(find_lock[OP_RSA]);
1742+		OPENSSL_free(find_lock[OP_RSA]);
1743+		find_lock[OP_RSA] = NULL;
1744+		}
1745+#endif /* OPENSSL_NO_RSA */
1746+#ifndef OPENSSL_NO_DSA
1747+	if (find_lock[OP_DSA] != NULL)
1748+		{
1749+		(void) pthread_mutex_destroy(find_lock[OP_DSA]);
1750+		OPENSSL_free(find_lock[OP_DSA]);
1751+		find_lock[OP_DSA] = NULL;
1752+		}
1753+#endif /* OPENSSL_NO_DSA */
1754+#ifndef OPENSSL_NO_DH
1755+	if (find_lock[OP_DH] != NULL)
1756+		{
1757+		(void) pthread_mutex_destroy(find_lock[OP_DH]);
1758+		OPENSSL_free(find_lock[OP_DH]);
1759+		find_lock[OP_DH] = NULL;
1760+		}
1761+#endif /* OPENSSL_NO_DH */
1762+
1763+	for (type = 0; type < OP_MAX; type++)
1764+		{
1765+		if (session_cache[type].lock != NULL)
1766+			{
1767+			(void) pthread_mutex_destroy(session_cache[type].lock);
1768+			OPENSSL_free(session_cache[type].lock);
1769+			session_cache[type].lock = NULL;
1770+			}
1771+		}
1772+#endif
1773+	}
1774+
1775+/*
1776+ * This internal function is used by ENGINE_pk11() and "dynamic" ENGINE support.
1777+ */
1778+static int bind_pk11(ENGINE *e)
1779+	{
1780+#ifndef OPENSSL_NO_RSA
1781+	const RSA_METHOD *rsa = NULL;
1782+	RSA_METHOD *pk11_rsa = PK11_RSA();
1783+#endif	/* OPENSSL_NO_RSA */
1784+	if (!pk11_library_initialized)
1785+		if (!pk11_library_init(e))
1786+			return (0);
1787+
1788+	if (!ENGINE_set_id(e, engine_pk11_id) ||
1789+	    !ENGINE_set_name(e, engine_pk11_name) ||
1790+	    !ENGINE_set_ciphers(e, pk11_engine_ciphers) ||
1791+	    !ENGINE_set_digests(e, pk11_engine_digests))
1792+		return (0);
1793+#ifndef OPENSSL_NO_RSA
1794+	if (pk11_have_rsa == CK_TRUE)
1795+		{
1796+		if (!ENGINE_set_RSA(e, PK11_RSA()) ||
1797+		    !ENGINE_set_load_privkey_function(e, pk11_load_privkey) ||
1798+		    !ENGINE_set_load_pubkey_function(e, pk11_load_pubkey))
1799+			return (0);
1800+#ifdef	DEBUG_SLOT_SELECTION
1801+		fprintf(stderr, "%s: registered RSA\n", PK11_DBG);
1802+#endif	/* DEBUG_SLOT_SELECTION */
1803+		}
1804+#endif	/* OPENSSL_NO_RSA */
1805+#ifndef OPENSSL_NO_DSA
1806+	if (pk11_have_dsa == CK_TRUE)
1807+		{
1808+		if (!ENGINE_set_DSA(e, PK11_DSA()))
1809+			return (0);
1810+#ifdef	DEBUG_SLOT_SELECTION
1811+		fprintf(stderr, "%s: registered DSA\n", PK11_DBG);
1812+#endif	/* DEBUG_SLOT_SELECTION */
1813+		}
1814+#endif	/* OPENSSL_NO_DSA */
1815+#ifndef OPENSSL_NO_DH
1816+	if (pk11_have_dh == CK_TRUE)
1817+		{
1818+		if (!ENGINE_set_DH(e, PK11_DH()))
1819+			return (0);
1820+#ifdef	DEBUG_SLOT_SELECTION
1821+		fprintf(stderr, "%s: registered DH\n", PK11_DBG);
1822+#endif	/* DEBUG_SLOT_SELECTION */
1823+		}
1824+#endif	/* OPENSSL_NO_DH */
1825+	if (pk11_have_random)
1826+		{
1827+		if (!ENGINE_set_RAND(e, &pk11_random))
1828+			return (0);
1829+#ifdef	DEBUG_SLOT_SELECTION
1830+		fprintf(stderr, "%s: registered random\n", PK11_DBG);
1831+#endif	/* DEBUG_SLOT_SELECTION */
1832+		}
1833+	if (!ENGINE_set_init_function(e, pk11_init) ||
1834+	    !ENGINE_set_destroy_function(e, pk11_destroy) ||
1835+	    !ENGINE_set_finish_function(e, pk11_finish) ||
1836+	    !ENGINE_set_ctrl_function(e, pk11_ctrl) ||
1837+	    !ENGINE_set_cmd_defns(e, pk11_cmd_defns))
1838+		return (0);
1839+
1840+/*
1841+ * Apache calls OpenSSL function RSA_blinding_on() once during startup
1842+ * which in turn calls bn_mod_exp. Since we do not implement bn_mod_exp
1843+ * here, we wire it back to the OpenSSL software implementation.
1844+ * Since it is used only once, performance is not a concern.
1845+ */
1846+#ifndef OPENSSL_NO_RSA
1847+	rsa = RSA_PKCS1_SSLeay();
1848+	pk11_rsa->rsa_mod_exp = rsa->rsa_mod_exp;
1849+	pk11_rsa->bn_mod_exp = rsa->bn_mod_exp;
1850+	if (pk11_have_recover != CK_TRUE)
1851+		pk11_rsa->rsa_pub_dec = rsa->rsa_pub_dec;
1852+#endif	/* OPENSSL_NO_RSA */
1853+
1854+	/* Ensure the pk11 error handling is set up */
1855+	ERR_load_pk11_strings();
1856+
1857+	return (1);
1858+	}
1859+
1860+/* Dynamic engine support is disabled at a higher level for Solaris */
1861+#ifdef	ENGINE_DYNAMIC_SUPPORT
1862+#error  "dynamic engine not supported"
1863+static int bind_helper(ENGINE *e, const char *id)
1864+	{
1865+	if (id && (strcmp(id, engine_pk11_id) != 0))
1866+		return (0);
1867+
1868+	if (!bind_pk11(e))
1869+		return (0);
1870+
1871+	return (1);
1872+	}
1873+
1874+IMPLEMENT_DYNAMIC_CHECK_FN()
1875+IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
1876+
1877+#else
1878+static ENGINE *engine_pk11(void)
1879+	{
1880+	ENGINE *ret = ENGINE_new();
1881+
1882+	if (!ret)
1883+		return (NULL);
1884+
1885+	if (!bind_pk11(ret))
1886+		{
1887+		ENGINE_free(ret);
1888+		return (NULL);
1889+		}
1890+
1891+	return (ret);
1892+	}
1893+
1894+void
1895+ENGINE_load_pk11(void)
1896+	{
1897+	ENGINE *e_pk11 = NULL;
1898+
1899+	/*
1900+	 * Do not use dynamic PKCS#11 library on Solaris due to
1901+	 * security reasons. We will link it in statically.
1902+	 */
1903+	/* Attempt to load PKCS#11 library */
1904+	if (!pk11_dso)
1905+		pk11_dso = DSO_load(NULL, get_PK11_LIBNAME(), NULL, 0);
1906+
1907+	if (pk11_dso == NULL)
1908+		{
1909+		PK11err(PK11_F_LOAD, PK11_R_DSO_FAILURE);
1910+		return;
1911+		}
1912+
1913+	e_pk11 = engine_pk11();
1914+	if (!e_pk11)
1915+		{
1916+		DSO_free(pk11_dso);
1917+		pk11_dso = NULL;
1918+		return;
1919+		}
1920+
1921+	/*
1922+	 * At this point, the pk11 shared library is either dynamically
1923+	 * loaded or statically linked in. So, initialize the pk11
1924+	 * library before calling ENGINE_set_default since the latter
1925+	 * needs cipher and digest algorithm information
1926+	 */
1927+	if (!pk11_library_init(e_pk11))
1928+		{
1929+		DSO_free(pk11_dso);
1930+		pk11_dso = NULL;
1931+		ENGINE_free(e_pk11);
1932+		return;
1933+		}
1934+
1935+	ENGINE_add(e_pk11);
1936+
1937+	ENGINE_free(e_pk11);
1938+	ERR_clear_error();
1939+	}
1940+#endif	/* ENGINE_DYNAMIC_SUPPORT */
1941+
1942+/*
1943+ * These are the static string constants for the DSO file name and
1944+ * the function symbol names to bind to.
1945+ */
1946+static const char *PK11_LIBNAME = NULL;
1947+
1948+static const char *get_PK11_LIBNAME(void)
1949+	{
1950+	if (PK11_LIBNAME)
1951+		return (PK11_LIBNAME);
1952+
1953+	return (def_PK11_LIBNAME);
1954+	}
1955+
1956+static void free_PK11_LIBNAME(void)
1957+	{
1958+	if (PK11_LIBNAME)
1959+		OPENSSL_free((void*)PK11_LIBNAME);
1960+
1961+	PK11_LIBNAME = NULL;
1962+	}
1963+
1964+static long set_PK11_LIBNAME(const char *name)
1965+	{
1966+	free_PK11_LIBNAME();
1967+
1968+	return ((PK11_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
1969+	}
1970+
1971+/* acquire all engine specific mutexes before fork */
1972+static void pk11_fork_prepare(void)
1973+	{
1974+#ifndef NOPTHREADS
1975+	int i;
1976+
1977+	if (!pk11_library_initialized)
1978+		return;
1979+
1980+	LOCK_OBJSTORE(OP_RSA);
1981+	LOCK_OBJSTORE(OP_DSA);
1982+	LOCK_OBJSTORE(OP_DH);
1983+	OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
1984+	for (i = 0; i < OP_MAX; i++)
1985+		{
1986+		OPENSSL_assert(pthread_mutex_lock(session_cache[i].lock) == 0);
1987+		}
1988+#endif
1989+	}
1990+
1991+/* release all engine specific mutexes */
1992+static void pk11_fork_parent(void)
1993+	{
1994+#ifndef NOPTHREADS
1995+	int i;
1996+
1997+	if (!pk11_library_initialized)
1998+		return;
1999+
2000+	for (i = OP_MAX - 1; i >= 0; i--)
2001+		{
2002+		OPENSSL_assert(pthread_mutex_unlock(session_cache[i].lock) == 0);
2003+		}
2004+	UNLOCK_OBJSTORE(OP_DH);
2005+	UNLOCK_OBJSTORE(OP_DSA);
2006+	UNLOCK_OBJSTORE(OP_RSA);
2007+	OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
2008+#endif
2009+	}
2010+
2011+/*
2012+ * same situation as in parent - we need to unlock all locks to make them
2013+ * accessible to all threads.
2014+ */
2015+static void pk11_fork_child(void)
2016+	{
2017+#ifndef NOPTHREADS
2018+	int i;
2019+
2020+	if (!pk11_library_initialized)
2021+		return;
2022+
2023+	for (i = OP_MAX - 1; i >= 0; i--)
2024+		{
2025+		OPENSSL_assert(pthread_mutex_unlock(session_cache[i].lock) == 0);
2026+		}
2027+	UNLOCK_OBJSTORE(OP_DH);
2028+	UNLOCK_OBJSTORE(OP_DSA);
2029+	UNLOCK_OBJSTORE(OP_RSA);
2030+	OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
2031+#endif
2032+	}
2033+
2034+/* Initialization function for the pk11 engine */
2035+static int pk11_init(ENGINE *e)
2036+{
2037+	return (pk11_library_init(e));
2038+}
2039+
2040+static CK_C_INITIALIZE_ARGS pk11_init_args =
2041+	{
2042+	NULL_PTR,		/* CreateMutex */
2043+	NULL_PTR,		/* DestroyMutex */
2044+	NULL_PTR,		/* LockMutex */
2045+	NULL_PTR,		/* UnlockMutex */
2046+	CKF_OS_LOCKING_OK,	/* flags */
2047+	NULL_PTR,		/* pReserved */
2048+	};
2049+
2050+/*
2051+ * Initialization function. Sets up various PKCS#11 library components.
2052+ * It selects a slot based on predefined critiera. In the process, it also
2053+ * count how many ciphers and digests to support. Since the cipher and
2054+ * digest information is needed when setting default engine, this function
2055+ * needs to be called before calling ENGINE_set_default.
2056+ */
2057+/* ARGSUSED */
2058+static int pk11_library_init(ENGINE *e)
2059+	{
2060+	CK_C_GetFunctionList p;
2061+	CK_RV rv = CKR_OK;
2062+	CK_INFO info;
2063+	CK_ULONG ul_state_len;
2064+	int any_slot_found;
2065+	int i;
2066+#ifndef OPENSSL_SYS_WIN32
2067+	struct sigaction sigint_act, sigterm_act, sighup_act;
2068+#endif
2069+
2070+	/*
2071+	 * pk11_library_initialized is set to 0 in pk11_finish() which
2072+	 * is called from ENGINE_finish(). However, if there is still
2073+	 * at least one existing functional reference to the engine
2074+	 * (see engine(3) for more information), pk11_finish() is
2075+	 * skipped. For example, this can happen if an application
2076+	 * forgets to clear one cipher context. In case of a fork()
2077+	 * when the application is finishing the engine so that it can
2078+	 * be reinitialized in the child, forgotten functional
2079+	 * reference causes pk11_library_initialized to stay 1. In
2080+	 * that case we need the PID check so that we properly
2081+	 * initialize the engine again.
2082+	 */
2083+	if (pk11_library_initialized)
2084+		{
2085+		if (pk11_pid == getpid())
2086+			{
2087+			return (1);
2088+			}
2089+		else
2090+			{
2091+			global_session = CK_INVALID_HANDLE;
2092+			/*
2093+			 * free the locks first to prevent memory leak in case
2094+			 * the application calls fork() without finishing the
2095+			 * engine first.
2096+			 */
2097+			pk11_free_all_locks();
2098+			}
2099+		}
2100+
2101+	if (pk11_dso == NULL)
2102+		{
2103+		PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
2104+		goto err;
2105+		}
2106+
2107+#ifdef	SOLARIS_AES_CTR
2108+	/*
2109+	 * We must do this before we start working with slots since we need all
2110+	 * NIDs there.
2111+	 */
2112+	if (pk11_add_aes_ctr_NIDs() == 0)
2113+		goto err;
2114+#endif	/* SOLARIS_AES_CTR */
2115+
2116+#ifdef	SOLARIS_HW_SLOT_SELECTION
2117+	if (check_hw_mechanisms() == 0)
2118+		goto err;
2119+#endif	/* SOLARIS_HW_SLOT_SELECTION */
2120+
2121+	/* get the C_GetFunctionList function from the loaded library */
2122+	p = (CK_C_GetFunctionList)DSO_bind_func(pk11_dso,
2123+		PK11_GET_FUNCTION_LIST);
2124+	if (!p)
2125+		{
2126+		PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
2127+		goto err;
2128+		}
2129+
2130+	/* get the full function list from the loaded library */
2131+	rv = p(&pFuncList);
2132+	if (rv != CKR_OK)
2133+		{
2134+		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE, rv);
2135+		goto err;
2136+		}
2137+
2138+#ifndef OPENSSL_SYS_WIN32
2139+	/* Not all PKCS#11 library are signal safe! */
2140+
2141+	(void) memset(&sigint_act, 0, sizeof(sigint_act));
2142+	(void) memset(&sigterm_act, 0, sizeof(sigterm_act));
2143+	(void) memset(&sighup_act, 0, sizeof(sighup_act));
2144+	(void) sigaction(SIGINT, NULL, &sigint_act);
2145+	(void) sigaction(SIGTERM, NULL, &sigterm_act);
2146+	(void) sigaction(SIGHUP, NULL, &sighup_act);
2147+#endif
2148+	rv = pFuncList->C_Initialize((CK_VOID_PTR)&pk11_init_args);
2149+#ifndef OPENSSL_SYS_WIN32
2150+	(void) sigaction(SIGINT, &sigint_act, NULL);
2151+	(void) sigaction(SIGTERM, &sigterm_act, NULL);
2152+	(void) sigaction(SIGHUP, &sighup_act, NULL);
2153+#endif
2154+	if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
2155+		{
2156+		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_INITIALIZE, rv);
2157+		goto err;
2158+		}
2159+
2160+	rv = pFuncList->C_GetInfo(&info);
2161+	if (rv != CKR_OK)
2162+		{
2163+		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_GETINFO, rv);
2164+		goto err;
2165+		}
2166+
2167+	if (pk11_choose_slots(&any_slot_found) == 0)
2168+		goto err;
2169+
2170+	/*
2171+	 * The library we use, set in def_PK11_LIBNAME, may not offer any
2172+	 * slot(s). In that case, we must not proceed but we must not return an
2173+	 * error. The reason is that applications that try to set up the PKCS#11
2174+	 * engine don't exit on error during the engine initialization just
2175+	 * because no slot was present.
2176+	 */
2177+	if (any_slot_found == 0)
2178+		return (1);
2179+
2180+	if (global_session == CK_INVALID_HANDLE)
2181+		{
2182+		/* Open the global_session for the new process */
2183+		rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
2184+			NULL_PTR, NULL_PTR, &global_session);
2185+		if (rv != CKR_OK)
2186+			{
2187+			PK11err_add_data(PK11_F_LIBRARY_INIT,
2188+			    PK11_R_OPENSESSION, rv);
2189+			goto err;
2190+			}
2191+		}
2192+
2193+	/*
2194+	 * Disable digest if C_GetOperationState is not supported since
2195+	 * this function is required by OpenSSL digest copy function
2196+	 */
2197+	/* Keyper fails to return CKR_FUNCTION_NOT_SUPPORTED */
2198+	if (pFuncList->C_GetOperationState(global_session, NULL, &ul_state_len)
2199+			!= CKR_OK) {
2200+#ifdef	DEBUG_SLOT_SELECTION
2201+		fprintf(stderr, "%s: C_GetOperationState() not supported, "
2202+		    "setting digest_count to 0\n", PK11_DBG);
2203+#endif	/* DEBUG_SLOT_SELECTION */
2204+		digest_count = 0;
2205+	}
2206+
2207+	pk11_library_initialized = TRUE;
2208+	pk11_pid = getpid();
2209+	/*
2210+	 * if initialization of the locks fails pk11_init_all_locks()
2211+	 * will do the cleanup.
2212+	 */
2213+	if (!pk11_init_all_locks())
2214+		goto err;
2215+	for (i = 0; i < OP_MAX; i++)
2216+		session_cache[i].head = NULL;
2217+	/*
2218+	 * initialize active lists. We only use active lists
2219+	 * for asymmetric ciphers.
2220+	 */
2221+	for (i = 0; i < OP_MAX; i++)
2222+		active_list[i] = NULL;
2223+
2224+#ifndef NOPTHREADS
2225+	if (!pk11_atfork_initialized)
2226+		{
2227+		if (pthread_atfork(pk11_fork_prepare, pk11_fork_parent,
2228+		    pk11_fork_child) != 0)
2229+			{
2230+			PK11err(PK11_F_LIBRARY_INIT, PK11_R_ATFORK_FAILED);
2231+			goto err;
2232+			}
2233+		pk11_atfork_initialized = TRUE;
2234+		}
2235+#endif
2236+
2237+	return (1);
2238+
2239+err:
2240+	return (0);
2241+	}
2242+
2243+/* Destructor (complements the "ENGINE_pk11()" constructor) */
2244+/* ARGSUSED */
2245+static int pk11_destroy(ENGINE *e)
2246+	{
2247+	free_PK11_LIBNAME();
2248+	ERR_unload_pk11_strings();
2249+	if (pk11_pin) {
2250+		memset(pk11_pin, 0, strlen(pk11_pin));
2251+		OPENSSL_free((void*)pk11_pin);
2252+	}
2253+	pk11_pin = NULL;
2254+	return (1);
2255+	}
2256+
2257+/*
2258+ * Termination function to clean up the session, the token, and the pk11
2259+ * library.
2260+ */
2261+/* ARGSUSED */
2262+static int pk11_finish(ENGINE *e)
2263+	{
2264+	int i;
2265+
2266+	if (pk11_pin) {
2267+		memset(pk11_pin, 0, strlen(pk11_pin));
2268+		OPENSSL_free((void*)pk11_pin);
2269+	}
2270+	pk11_pin = NULL;
2271+
2272+	if (pk11_dso == NULL)
2273+		{
2274+		PK11err(PK11_F_FINISH, PK11_R_NOT_LOADED);
2275+		goto err;
2276+		}
2277+
2278+	OPENSSL_assert(pFuncList != NULL);
2279+
2280+	if (pk11_free_all_sessions() == 0)
2281+		goto err;
2282+
2283+	/* free all active lists */
2284+	for (i = 0; i < OP_MAX; i++)
2285+		pk11_free_active_list(i);
2286+
2287+	pFuncList->C_CloseSession(global_session);
2288+	global_session = CK_INVALID_HANDLE;
2289+
2290+	/*
2291+	 * Since we are part of a library (libcrypto.so), calling this function
2292+	 * may have side-effects.
2293+	 */
2294+#if 0
2295+	pFuncList->C_Finalize(NULL);
2296+#endif
2297+
2298+	if (!DSO_free(pk11_dso))
2299+		{
2300+		PK11err(PK11_F_FINISH, PK11_R_DSO_FAILURE);
2301+		goto err;
2302+		}
2303+	pk11_dso = NULL;
2304+	pFuncList = NULL;
2305+	pk11_library_initialized = FALSE;
2306+	pk11_pid = 0;
2307+	/*
2308+	 * There is no way how to unregister atfork handlers (other than
2309+	 * unloading the library) so we just free the locks. For this reason
2310+	 * the atfork handlers check if the engine is initialized and bail out
2311+	 * immediately if not. This is necessary in case a process finishes
2312+	 * the engine before calling fork().
2313+	 */
2314+	pk11_free_all_locks();
2315+
2316+	return (1);
2317+
2318+err:
2319+	return (0);
2320+	}
2321+
2322+/* Standard engine interface function to set the dynamic library path */
2323+/* ARGSUSED */
2324+static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
2325+	{
2326+	int initialized = ((pk11_dso == NULL) ? 0 : 1);
2327+
2328+	switch (cmd)
2329+		{
2330+	case PK11_CMD_SO_PATH:
2331+		if (p == NULL)
2332+			{
2333+			PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
2334+			return (0);
2335+			}
2336+
2337+		if (initialized)
2338+			{
2339+			PK11err(PK11_F_CTRL, PK11_R_ALREADY_LOADED);
2340+			return (0);
2341+			}
2342+
2343+		return (set_PK11_LIBNAME((const char *)p));
2344+	case PK11_CMD_PIN:
2345+		if (pk11_pin) {
2346+			memset(pk11_pin, 0, strlen(pk11_pin));
2347+			OPENSSL_free((void*)pk11_pin);
2348+		}
2349+		pk11_pin = NULL;
2350+
2351+		if (p == NULL)
2352+			{
2353+			PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
2354+			return (0);
2355+			}
2356+
2357+		pk11_pin = BUF_strdup(p);
2358+		if (pk11_pin == NULL)
2359+			{
2360+			PK11err(PK11_F_GET_SESSION, PK11_R_MALLOC_FAILURE);
2361+			return (0);
2362+			}
2363+		return (1);
2364+	case PK11_CMD_SLOT:
2365+		SLOTID = (CK_SLOT_ID)i;
2366+#ifdef DEBUG_SLOT_SELECTION
2367+		fprintf(stderr, "%s: slot set\n", PK11_DBG);
2368+#endif
2369+		return (1);
2370+	default:
2371+		break;
2372+		}
2373+
2374+	PK11err(PK11_F_CTRL, PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED);
2375+
2376+	return (0);
2377+	}
2378+
2379+
2380+/* Required function by the engine random interface. It does nothing here */
2381+static void pk11_rand_cleanup(void)
2382+	{
2383+	return;
2384+	}
2385+
2386+/* ARGSUSED */
2387+static void pk11_rand_add(const void *buf, int num, double add)
2388+	{
2389+	PK11_SESSION *sp;
2390+
2391+	if ((sp = pk11_get_session(OP_RAND)) == NULL)
2392+		return;
2393+
2394+	/*
2395+	 * Ignore any errors (e.g. CKR_RANDOM_SEED_NOT_SUPPORTED) since
2396+	 * the calling functions do not care anyway
2397+	 */
2398+	pFuncList->C_SeedRandom(sp->session, (unsigned char *) buf, num);
2399+	pk11_return_session(sp, OP_RAND);
2400+
2401+	return;
2402+	}
2403+
2404+static void pk11_rand_seed(const void *buf, int num)
2405+	{
2406+	pk11_rand_add(buf, num, 0);
2407+	}
2408+
2409+static int pk11_rand_bytes(unsigned char *buf, int num)
2410+	{
2411+	CK_RV rv;
2412+	PK11_SESSION *sp;
2413+
2414+	if ((sp = pk11_get_session(OP_RAND)) == NULL)
2415+		return (0);
2416+
2417+	rv = pFuncList->C_GenerateRandom(sp->session, buf, num);
2418+	if (rv != CKR_OK)
2419+		{
2420+		PK11err_add_data(PK11_F_RAND_BYTES, PK11_R_GENERATERANDOM, rv);
2421+		pk11_return_session(sp, OP_RAND);
2422+		return (0);
2423+		}
2424+
2425+	pk11_return_session(sp, OP_RAND);
2426+	return (1);
2427+	}
2428+
2429+/* Required function by the engine random interface. It does nothing here */
2430+static int pk11_rand_status(void)
2431+	{
2432+	return (1);
2433+	}
2434+
2435+/* Free all BIGNUM structures from PK11_SESSION. */
2436+static void pk11_free_nums(PK11_SESSION *sp, PK11_OPTYPE optype)
2437+	{
2438+	switch (optype)
2439+		{
2440+#ifndef	OPENSSL_NO_RSA
2441+		case OP_RSA:
2442+			if (sp->opdata_rsa_n_num != NULL)
2443+				{
2444+				BN_free(sp->opdata_rsa_n_num);
2445+				sp->opdata_rsa_n_num = NULL;
2446+				}
2447+			if (sp->opdata_rsa_e_num != NULL)
2448+				{
2449+				BN_free(sp->opdata_rsa_e_num);
2450+				sp->opdata_rsa_e_num = NULL;
2451+				}
2452+			if (sp->opdata_rsa_pn_num != NULL)
2453+				{
2454+				BN_free(sp->opdata_rsa_pn_num);
2455+				sp->opdata_rsa_pn_num = NULL;
2456+				}
2457+			if (sp->opdata_rsa_pe_num != NULL)
2458+				{
2459+				BN_free(sp->opdata_rsa_pe_num);
2460+				sp->opdata_rsa_pe_num = NULL;
2461+				}
2462+			if (sp->opdata_rsa_d_num != NULL)
2463+				{
2464+				BN_free(sp->opdata_rsa_d_num);
2465+				sp->opdata_rsa_d_num = NULL;
2466+				}
2467+			break;
2468+#endif
2469+#ifndef	OPENSSL_NO_DSA
2470+		case OP_DSA:
2471+			if (sp->opdata_dsa_pub_num != NULL)
2472+				{
2473+				BN_free(sp->opdata_dsa_pub_num);
2474+				sp->opdata_dsa_pub_num = NULL;
2475+				}
2476+			if (sp->opdata_dsa_priv_num != NULL)
2477+				{
2478+				BN_free(sp->opdata_dsa_priv_num);
2479+				sp->opdata_dsa_priv_num = NULL;
2480+				}
2481+			break;
2482+#endif
2483+#ifndef	OPENSSL_NO_DH
2484+		case OP_DH:
2485+			if (sp->opdata_dh_priv_num != NULL)
2486+				{
2487+				BN_free(sp->opdata_dh_priv_num);
2488+				sp->opdata_dh_priv_num = NULL;
2489+				}
2490+			break;
2491+#endif
2492+		default:
2493+			break;
2494+		}
2495+	}
2496+
2497+/*
2498+ * Get new PK11_SESSION structure ready for use. Every process must have
2499+ * its own freelist of PK11_SESSION structures so handle fork() here
2500+ * by destroying the old and creating new freelist.
2501+ * The returned PK11_SESSION structure is disconnected from the freelist.
2502+ */
2503+PK11_SESSION *
2504+pk11_get_session(PK11_OPTYPE optype)
2505+	{
2506+	PK11_SESSION *sp = NULL, *sp1, *freelist;
2507+#ifndef NOPTHREADS
2508+	pthread_mutex_t *freelist_lock = NULL;
2509+#endif
2510+	static pid_t pid = 0;
2511+	pid_t new_pid;
2512+	CK_RV rv;
2513+
2514+	switch (optype)
2515+		{
2516+		case OP_RSA:
2517+		case OP_DSA:
2518+		case OP_DH:
2519+		case OP_RAND:
2520+		case OP_DIGEST:
2521+		case OP_CIPHER:
2522+#ifndef NOPTHREADS
2523+			freelist_lock = session_cache[optype].lock;
2524+#endif
2525+			break;
2526+		default:
2527+			PK11err(PK11_F_GET_SESSION,
2528+				PK11_R_INVALID_OPERATION_TYPE);
2529+			return (NULL);
2530+		}
2531+#ifndef NOPTHREADS
2532+	OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
2533+#else
2534+	CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
2535+#endif
2536+
2537+	/*
2538+	 * Will use it to find out if we forked. We cannot use the PID field in
2539+	 * the session structure because we could get a newly allocated session
2540+	 * here, with no PID information.
2541+	 */
2542+	if (pid == 0)
2543+		pid = getpid();
2544+
2545+	freelist = session_cache[optype].head;
2546+	sp = freelist;
2547+
2548+	/*
2549+	 * If the free list is empty, allocate new unitialized (filled
2550+	 * with zeroes) PK11_SESSION structure otherwise return first
2551+	 * structure from the freelist.
2552+	 */
2553+	if (sp == NULL)
2554+		{
2555+		if ((sp = OPENSSL_malloc(sizeof (PK11_SESSION))) == NULL)
2556+			{
2557+			PK11err(PK11_F_GET_SESSION,
2558+				PK11_R_MALLOC_FAILURE);
2559+			goto err;
2560+			}
2561+		(void) memset(sp, 0, sizeof (PK11_SESSION));
2562+
2563+		/*
2564+		 * It is a new session so it will look like a cache miss to the
2565+		 * code below. So, we must not try to to destroy its members so
2566+		 * mark them as unused.
2567+		 */
2568+		sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
2569+		sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
2570+		}
2571+	else
2572+		{
2573+		freelist = sp->next;
2574+		}
2575+
2576+	/*
2577+	 * Check whether we have forked. In that case, we must get rid of all
2578+	 * inherited sessions and start allocating new ones.
2579+	 */
2580+	if (pid != (new_pid = getpid()))
2581+		{
2582+		pid = new_pid;
2583+
2584+		/*
2585+		 * We are a new process and thus need to free any inherited
2586+		 * PK11_SESSION objects aside from the first session (sp) which
2587+		 * is the only PK11_SESSION structure we will reuse (for the
2588+		 * head of the list).
2589+		 */
2590+		while ((sp1 = freelist) != NULL)
2591+			{
2592+			freelist = sp1->next;
2593+			/*
2594+			 * NOTE: we do not want to call pk11_free_all_sessions()
2595+			 * here because it would close underlying PKCS#11
2596+			 * sessions and destroy all objects.
2597+			 */
2598+			pk11_free_nums(sp1, optype);
2599+			OPENSSL_free(sp1);
2600+			}
2601+
2602+		/* we have to free the active list as well. */
2603+		pk11_free_active_list(optype);
2604+
2605+		/* Initialize the process */
2606+		rv = pFuncList->C_Initialize((CK_VOID_PTR)&pk11_init_args);
2607+		if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
2608+			{
2609+			PK11err_add_data(PK11_F_GET_SESSION, PK11_R_INITIALIZE,
2610+			    rv);
2611+			OPENSSL_free(sp);
2612+			sp = NULL;
2613+			goto err;
2614+			}
2615+
2616+		/*
2617+		 * Choose slot here since the slot table is different on this
2618+		 * process. If we are here then we must have found at least one
2619+		 * usable slot before so we don't need to check any_slot_found.
2620+		 * See pk11_library_init()'s usage of this function for more
2621+		 * information.
2622+		 */
2623+#ifdef	SOLARIS_HW_SLOT_SELECTION
2624+		if (check_hw_mechanisms() == 0)
2625+			goto err;
2626+#endif	/* SOLARIS_HW_SLOT_SELECTION */
2627+		if (pk11_choose_slots(NULL) == 0)
2628+			goto err;
2629+
2630+		/* Open the global_session for the new process */
2631+		rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
2632+			NULL_PTR, NULL_PTR, &global_session);
2633+		if (rv != CKR_OK)
2634+			{
2635+			PK11err_add_data(PK11_F_GET_SESSION, PK11_R_OPENSESSION,
2636+			    rv);
2637+			OPENSSL_free(sp);
2638+			sp = NULL;
2639+			goto err;
2640+			}
2641+
2642+		/*
2643+		 * It is an inherited session from our parent so it needs
2644+		 * re-initialization.
2645+		 */
2646+		if (pk11_setup_session(sp, optype) == 0)
2647+			{
2648+			OPENSSL_free(sp);
2649+			sp = NULL;
2650+			goto err;
2651+			}
2652+		if (pk11_token_relogin(sp->session) == 0)
2653+			{
2654+			/*
2655+			 * We will keep the session in the cache list and let
2656+			 * the caller cope with the situation.
2657+			 */
2658+			freelist = sp;
2659+			sp = NULL;
2660+			goto err;
2661+			}
2662+		}
2663+
2664+	if (sp->pid == 0)
2665+		{
2666+		/* It is a new session and needs initialization. */
2667+		if (pk11_setup_session(sp, optype) == 0)
2668+			{
2669+			OPENSSL_free(sp);
2670+			sp = NULL;
2671+			}
2672+		}
2673+
2674+	/* set new head for the list of PK11_SESSION objects */
2675+	session_cache[optype].head = freelist;
2676+
2677+err:
2678+	if (sp != NULL)
2679+		sp->next = NULL;
2680+
2681+#ifndef NOPTHREADS
2682+	OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
2683+#else
2684+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
2685+#endif
2686+
2687+	return (sp);
2688+	}
2689+
2690+
2691+void
2692+pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype)
2693+	{
2694+#ifndef NOPTHREADS
2695+	pthread_mutex_t *freelist_lock;
2696+#endif
2697+	PK11_SESSION *freelist;
2698+
2699+	/*
2700+	 * If this is a session from the parent it will be taken care of and
2701+	 * freed in pk11_get_session() as part of the post-fork clean up the
2702+	 * next time we will ask for a new session.
2703+	 */
2704+	if (sp == NULL || sp->pid != getpid())
2705+		return;
2706+
2707+	switch (optype)
2708+		{
2709+		case OP_RSA:
2710+		case OP_DSA:
2711+		case OP_DH:
2712+		case OP_RAND:
2713+		case OP_DIGEST:
2714+		case OP_CIPHER:
2715+#ifndef NOPTHREADS
2716+			freelist_lock = session_cache[optype].lock;
2717+#endif
2718+			break;
2719+		default:
2720+			PK11err(PK11_F_RETURN_SESSION,
2721+				PK11_R_INVALID_OPERATION_TYPE);
2722+			return;
2723+		}
2724+
2725+#ifndef NOPTHREADS
2726+	OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
2727+#else
2728+	CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
2729+#endif
2730+	freelist = session_cache[optype].head;
2731+	sp->next = freelist;
2732+	session_cache[optype].head = sp;
2733+#ifndef NOPTHREADS
2734+	OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
2735+#else
2736+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
2737+#endif
2738+	}
2739+
2740+
2741+/* Destroy all objects. This function is called when the engine is finished */
2742+static int pk11_free_all_sessions()
2743+	{
2744+	int ret = 1;
2745+	int type;
2746+
2747+#ifndef OPENSSL_NO_RSA
2748+	(void) pk11_destroy_rsa_key_objects(NULL);
2749+#endif	/* OPENSSL_NO_RSA */
2750+#ifndef OPENSSL_NO_DSA
2751+	(void) pk11_destroy_dsa_key_objects(NULL);
2752+#endif	/* OPENSSL_NO_DSA */
2753+#ifndef OPENSSL_NO_DH
2754+	(void) pk11_destroy_dh_key_objects(NULL);
2755+#endif	/* OPENSSL_NO_DH */
2756+	(void) pk11_destroy_cipher_key_objects(NULL);
2757+
2758+	/*
2759+	 * We try to release as much as we can but any error means that we will
2760+	 * return 0 on exit.
2761+	 */
2762+	for (type = 0; type < OP_MAX; type++)
2763+		{
2764+		if (pk11_free_session_list(type) == 0)
2765+			ret = 0;
2766+		}
2767+
2768+	return (ret);
2769+	}
2770+
2771+/*
2772+ * Destroy session structures from the linked list specified. Free as many
2773+ * sessions as possible but any failure in C_CloseSession() means that we
2774+ * return an error on return.
2775+ */
2776+static int pk11_free_session_list(PK11_OPTYPE optype)
2777+	{
2778+	CK_RV rv;
2779+	PK11_SESSION *sp = NULL;
2780+	PK11_SESSION *freelist = NULL;
2781+	pid_t mypid = getpid();
2782+#ifndef NOPTHREADS
2783+	pthread_mutex_t *freelist_lock;
2784+#endif
2785+	int ret = 1;
2786+
2787+	switch (optype)
2788+		{
2789+		case OP_RSA:
2790+		case OP_DSA:
2791+		case OP_DH:
2792+		case OP_RAND:
2793+		case OP_DIGEST:
2794+		case OP_CIPHER:
2795+#ifndef NOPTHREADS
2796+			freelist_lock = session_cache[optype].lock;
2797+#endif
2798+			break;
2799+		default:
2800+			PK11err(PK11_F_FREE_ALL_SESSIONS,
2801+				PK11_R_INVALID_OPERATION_TYPE);
2802+			return (0);
2803+		}
2804+
2805+#ifndef NOPTHREADS
2806+	OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
2807+#else
2808+	CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
2809+#endif
2810+	freelist = session_cache[optype].head;
2811+	while ((sp = freelist) != NULL)
2812+		{
2813+		if (sp->session != CK_INVALID_HANDLE && sp->pid == mypid)
2814+			{
2815+			rv = pFuncList->C_CloseSession(sp->session);
2816+			if (rv != CKR_OK)
2817+				{
2818+				PK11err_add_data(PK11_F_FREE_ALL_SESSIONS,
2819+					PK11_R_CLOSESESSION, rv);
2820+				ret = 0;
2821+				}
2822+			}
2823+		freelist = sp->next;
2824+		pk11_free_nums(sp, optype);
2825+		OPENSSL_free(sp);
2826+		}
2827+
2828+#ifndef NOPTHREADS
2829+	OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
2830+#else
2831+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
2832+#endif
2833+	return (ret);
2834+	}
2835+
2836+
2837+static int
2838+pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype)
2839+	{
2840+	CK_RV rv;
2841+	CK_SLOT_ID myslot;
2842+
2843+	switch (optype)
2844+		{
2845+		case OP_RSA:
2846+		case OP_DSA:
2847+		case OP_DH:
2848+			myslot = pubkey_SLOTID;
2849+			break;
2850+		case OP_RAND:
2851+			myslot = rand_SLOTID;
2852+			break;
2853+		case OP_DIGEST:
2854+		case OP_CIPHER:
2855+			myslot = SLOTID;
2856+			break;
2857+		default:
2858+			PK11err(PK11_F_SETUP_SESSION,
2859+			    PK11_R_INVALID_OPERATION_TYPE);
2860+			return (0);
2861+		}
2862+
2863+	sp->session = CK_INVALID_HANDLE;
2864+#ifdef	DEBUG_SLOT_SELECTION
2865+	fprintf(stderr, "%s: myslot=%d optype=%d\n", PK11_DBG, myslot, optype);
2866+#endif	/* DEBUG_SLOT_SELECTION */
2867+	rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
2868+		NULL_PTR, NULL_PTR, &sp->session);
2869+	if (rv == CKR_CRYPTOKI_NOT_INITIALIZED)
2870+		{
2871+		/*
2872+		 * We are probably a child process so force the
2873+		 * reinitialize of the session
2874+		 */
2875+		pk11_library_initialized = FALSE;
2876+		if (!pk11_library_init(NULL))
2877+			return (0);
2878+		rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
2879+			NULL_PTR, NULL_PTR, &sp->session);
2880+		}
2881+	if (rv != CKR_OK)
2882+		{
2883+		PK11err_add_data(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION, rv);
2884+		return (0);
2885+		}
2886+
2887+	sp->pid = getpid();
2888+
2889+	switch (optype)
2890+		{
2891+#ifndef OPENSSL_NO_RSA
2892+		case OP_RSA:
2893+			sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
2894+			sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
2895+			sp->opdata_rsa_pub = NULL;
2896+			sp->opdata_rsa_n_num = NULL;
2897+			sp->opdata_rsa_e_num = NULL;
2898+			sp->opdata_rsa_priv = NULL;
2899+			sp->opdata_rsa_pn_num = NULL;
2900+			sp->opdata_rsa_pe_num = NULL;
2901+			sp->opdata_rsa_d_num = NULL;
2902+			break;
2903+#endif	/* OPENSSL_NO_RSA */
2904+#ifndef OPENSSL_NO_DSA
2905+		case OP_DSA:
2906+			sp->opdata_dsa_pub_key = CK_INVALID_HANDLE;
2907+			sp->opdata_dsa_priv_key = CK_INVALID_HANDLE;
2908+			sp->opdata_dsa_pub = NULL;
2909+			sp->opdata_dsa_pub_num = NULL;
2910+			sp->opdata_dsa_priv = NULL;
2911+			sp->opdata_dsa_priv_num = NULL;
2912+			break;
2913+#endif	/* OPENSSL_NO_DSA */
2914+#ifndef OPENSSL_NO_DH
2915+		case OP_DH:
2916+			sp->opdata_dh_key = CK_INVALID_HANDLE;
2917+			sp->opdata_dh = NULL;
2918+			sp->opdata_dh_priv_num = NULL;
2919+			break;
2920+#endif	/* OPENSSL_NO_DH */
2921+		case OP_CIPHER:
2922+			sp->opdata_cipher_key = CK_INVALID_HANDLE;
2923+			sp->opdata_encrypt = -1;
2924+			break;
2925+		default:
2926+			break;
2927+		}
2928+
2929+	/*
2930+	 * We always initialize the session as containing a non-persistent
2931+	 * object. The key load functions set it to persistent if that is so.
2932+	 */
2933+	sp->pub_persistent = CK_FALSE;
2934+	sp->priv_persistent = CK_FALSE;
2935+	return (1);
2936+	}
2937+
2938+#ifndef OPENSSL_NO_RSA
2939+/* Destroy RSA public key from single session. */
2940+int
2941+pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
2942+	{
2943+	int ret = 0;
2944+
2945+	if (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE)
2946+		{
2947+		TRY_OBJ_DESTROY(sp, sp->opdata_rsa_pub_key,
2948+		    ret, uselock, OP_RSA, CK_FALSE);
2949+		sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
2950+		sp->opdata_rsa_pub = NULL;
2951+		if (sp->opdata_rsa_n_num != NULL)
2952+			{
2953+			BN_free(sp->opdata_rsa_n_num);
2954+			sp->opdata_rsa_n_num = NULL;
2955+			}
2956+		if (sp->opdata_rsa_e_num != NULL)
2957+			{
2958+			BN_free(sp->opdata_rsa_e_num);
2959+			sp->opdata_rsa_e_num = NULL;
2960+			}
2961+		}
2962+
2963+	return (ret);
2964+	}
2965+
2966+/* Destroy RSA private key from single session. */
2967+int
2968+pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
2969+	{
2970+	int ret = 0;
2971+
2972+	if (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE)
2973+		{
2974+		TRY_OBJ_DESTROY(sp, sp->opdata_rsa_priv_key,
2975+		    ret, uselock, OP_RSA, CK_TRUE);
2976+		sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
2977+		sp->opdata_rsa_priv = NULL;
2978+		if (sp->opdata_rsa_d_num != NULL)
2979+			{
2980+			BN_free(sp->opdata_rsa_d_num);
2981+			sp->opdata_rsa_d_num = NULL;
2982+			}
2983+
2984+		/*
2985+		 * For the RSA key by reference code, public components 'n'/'e'
2986+		 * are the key components we use to check for the cache hit. We
2987+		 * must free those as well.
2988+		 */
2989+		if (sp->opdata_rsa_pn_num != NULL)
2990+			{
2991+			BN_free(sp->opdata_rsa_pn_num);
2992+			sp->opdata_rsa_pn_num = NULL;
2993+			}
2994+		if (sp->opdata_rsa_pe_num != NULL)
2995+			{
2996+			BN_free(sp->opdata_rsa_pe_num);
2997+			sp->opdata_rsa_pe_num = NULL;
2998+			}
2999+		}
3000+
3001+	return (ret);
3002+	}
3003+
3004+/*
3005+ * Destroy RSA key object wrapper. If session is NULL, try to destroy all
3006+ * objects in the free list.
3007+ */
3008+int
3009+pk11_destroy_rsa_key_objects(PK11_SESSION *session)
3010+	{
3011+	int ret = 1;
3012+	PK11_SESSION *sp = NULL;
3013+	PK11_SESSION *local_free_session;
3014+	CK_BBOOL uselock = TRUE;
3015+
3016+	if (session != NULL)
3017+		local_free_session = session;
3018+	else
3019+		{
3020+#ifndef NOPTHREADS
3021+		OPENSSL_assert(pthread_mutex_lock(session_cache[OP_RSA].lock) == 0);
3022+#else
3023+		CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
3024+#endif
3025+		local_free_session = session_cache[OP_RSA].head;
3026+		uselock = FALSE;
3027+		}
3028+
3029+	/*
3030+	 * go through the list of sessions and delete key objects
3031+	 */
3032+	while ((sp = local_free_session) != NULL)
3033+		{
3034+		local_free_session = sp->next;
3035+
3036+		/*
3037+		 * Do not terminate list traversal if one of the
3038+		 * destroy operations fails.
3039+		 */
3040+		if (pk11_destroy_rsa_object_pub(sp, uselock) == 0)
3041+			{
3042+			ret = 0;
3043+			continue;
3044+			}
3045+		if (pk11_destroy_rsa_object_priv(sp, uselock) == 0)
3046+			{
3047+			ret = 0;
3048+			continue;
3049+			}
3050+		}
3051+
3052+#ifndef NOPTHREADS
3053+	if (session == NULL)
3054+		OPENSSL_assert(pthread_mutex_unlock(session_cache[OP_RSA].lock) == 0);
3055+#else
3056+	if (session == NULL)
3057+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
3058+#endif
3059+
3060+	return (ret);
3061+	}
3062+#endif	/* OPENSSL_NO_RSA */
3063+
3064+#ifndef OPENSSL_NO_DSA
3065+/* Destroy DSA public key from single session. */
3066+int
3067+pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
3068+	{
3069+	int ret = 0;
3070+
3071+	if (sp->opdata_dsa_pub_key != CK_INVALID_HANDLE)
3072+		{
3073+		TRY_OBJ_DESTROY(sp, sp->opdata_dsa_pub_key,
3074+		    ret, uselock, OP_DSA, CK_FALSE);
3075+		sp->opdata_dsa_pub_key = CK_INVALID_HANDLE;
3076+		sp->opdata_dsa_pub = NULL;
3077+		if (sp->opdata_dsa_pub_num != NULL)
3078+			{
3079+			BN_free(sp->opdata_dsa_pub_num);
3080+			sp->opdata_dsa_pub_num = NULL;
3081+			}
3082+		}
3083+
3084+	return (ret);
3085+	}
3086+
3087+/* Destroy DSA private key from single session. */
3088+int
3089+pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
3090+	{
3091+	int ret = 0;
3092+
3093+	if (sp->opdata_dsa_priv_key != CK_INVALID_HANDLE)
3094+		{
3095+		TRY_OBJ_DESTROY(sp, sp->opdata_dsa_priv_key,
3096+		    ret, uselock, OP_DSA, CK_TRUE);
3097+		sp->opdata_dsa_priv_key = CK_INVALID_HANDLE;
3098+		sp->opdata_dsa_priv = NULL;
3099+		if (sp->opdata_dsa_priv_num != NULL)
3100+			{
3101+			BN_free(sp->opdata_dsa_priv_num);
3102+			sp->opdata_dsa_priv_num = NULL;
3103+			}
3104+		}
3105+
3106+	return (ret);
3107+	}
3108+
3109+/*
3110+ * Destroy DSA key object wrapper. If session is NULL, try to destroy all
3111+ * objects in the free list.
3112+ */
3113+int
3114+pk11_destroy_dsa_key_objects(PK11_SESSION *session)
3115+	{
3116+	int ret = 1;
3117+	PK11_SESSION *sp = NULL;
3118+	PK11_SESSION *local_free_session;
3119+	CK_BBOOL uselock = TRUE;
3120+
3121+	if (session != NULL)
3122+		local_free_session = session;
3123+	else
3124+		{
3125+#ifndef NOPTHREADS
3126+		OPENSSL_assert(pthread_mutex_lock(session_cache[OP_DSA].lock) == 0);
3127+#else
3128+		CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
3129+#endif
3130+		local_free_session = session_cache[OP_DSA].head;
3131+		uselock = FALSE;
3132+		}
3133+
3134+	/*
3135+	 * go through the list of sessions and delete key objects
3136+	 */
3137+	while ((sp = local_free_session) != NULL)
3138+		{
3139+		local_free_session = sp->next;
3140+
3141+		/*
3142+		 * Do not terminate list traversal if one of the
3143+		 * destroy operations fails.
3144+		 */
3145+		if (pk11_destroy_dsa_object_pub(sp, uselock) == 0)
3146+			{
3147+			ret = 0;
3148+			continue;
3149+			}
3150+		if (pk11_destroy_dsa_object_priv(sp, uselock) == 0)
3151+			{
3152+			ret = 0;
3153+			continue;
3154+			}
3155+		}
3156+
3157+#ifndef NOPTHREADS
3158+	if (session == NULL)
3159+		OPENSSL_assert(pthread_mutex_unlock(session_cache[OP_DSA].lock) == 0);
3160+#else
3161+	if (session == NULL)
3162+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
3163+#endif
3164+
3165+	return (ret);
3166+	}
3167+#endif	/* OPENSSL_NO_DSA */
3168+
3169+#ifndef OPENSSL_NO_DH
3170+/* Destroy DH key from single session. */
3171+int
3172+pk11_destroy_dh_object(PK11_SESSION *sp, CK_BBOOL uselock)
3173+	{
3174+	int ret = 0;
3175+
3176+	if (sp->opdata_dh_key != CK_INVALID_HANDLE)
3177+		{
3178+		TRY_OBJ_DESTROY(sp, sp->opdata_dh_key,
3179+		    ret, uselock, OP_DH, CK_TRUE);
3180+		sp->opdata_dh_key = CK_INVALID_HANDLE;
3181+		sp->opdata_dh = NULL;
3182+		if (sp->opdata_dh_priv_num != NULL)
3183+			{
3184+			BN_free(sp->opdata_dh_priv_num);
3185+			sp->opdata_dh_priv_num = NULL;
3186+			}
3187+		}
3188+
3189+	return (ret);
3190+	}
3191+
3192+/*
3193+ * Destroy DH key object wrapper.
3194+ *
3195+ * arg0: pointer to PKCS#11 engine session structure
3196+ *       if session is NULL, try to destroy all objects in the free list
3197+ */
3198+int
3199+pk11_destroy_dh_key_objects(PK11_SESSION *session)
3200+	{
3201+	int ret = 1;
3202+	PK11_SESSION *sp = NULL;
3203+	PK11_SESSION *local_free_session;
3204+	CK_BBOOL uselock = TRUE;
3205+
3206+	if (session != NULL)
3207+		local_free_session = session;
3208+	else
3209+		{
3210+#ifndef NOPTHREADS
3211+		OPENSSL_assert(pthread_mutex_lock(session_cache[OP_DH].lock) == 0);
3212+#else
3213+		CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
3214+#endif
3215+		local_free_session = session_cache[OP_DH].head;
3216+		uselock = FALSE;
3217+		}
3218+
3219+	while ((sp = local_free_session) != NULL)
3220+		{
3221+		local_free_session = sp->next;
3222+
3223+		/*
3224+		 * Do not terminate list traversal if one of the
3225+		 * destroy operations fails.
3226+		 */
3227+		if (pk11_destroy_dh_object(sp, uselock) == 0)
3228+			{
3229+			ret = 0;
3230+			continue;
3231+			}
3232+		}
3233+
3234+#ifndef NOPTHREADS
3235+	if (session == NULL)
3236+		OPENSSL_assert(pthread_mutex_unlock(session_cache[OP_DH].lock) == 0);
3237+#else
3238+	if (session == NULL)
3239+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
3240+#endif
3241+
3242+	return (ret);
3243+	}
3244+#endif	/* OPENSSL_NO_DH */
3245+
3246+static int
3247+pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
3248+	CK_BBOOL persistent)
3249+	{
3250+	CK_RV rv;
3251+
3252+	/*
3253+	 * We never try to destroy persistent objects which are the objects
3254+	 * stored in the keystore. Also, we always use read-only sessions so
3255+	 * C_DestroyObject() would be returning CKR_SESSION_READ_ONLY here.
3256+	 */
3257+	if (persistent == CK_TRUE)
3258+		return (1);
3259+
3260+	rv = pFuncList->C_DestroyObject(session, oh);
3261+	if (rv != CKR_OK)
3262+		{
3263+		PK11err_add_data(PK11_F_DESTROY_OBJECT, PK11_R_DESTROYOBJECT,
3264+		    rv);
3265+		return (0);
3266+		}
3267+
3268+	return (1);
3269+	}
3270+
3271+
3272+/* Symmetric ciphers and digests support functions */
3273+
3274+static int
3275+cipher_nid_to_pk11(int nid)
3276+	{
3277+	int i;
3278+
3279+	for (i = 0; i < PK11_CIPHER_MAX; i++)
3280+		if (ciphers[i].nid == nid)
3281+			return (ciphers[i].id);
3282+	return (-1);
3283+	}
3284+
3285+static int
3286+pk11_usable_ciphers(const int **nids)
3287+	{
3288+	if (cipher_count > 0)
3289+		*nids = cipher_nids;
3290+	else
3291+		*nids = NULL;
3292+	return (cipher_count);
3293+	}
3294+
3295+static int
3296+pk11_usable_digests(const int **nids)
3297+	{
3298+	if (digest_count > 0)
3299+		*nids = digest_nids;
3300+	else
3301+		*nids = NULL;
3302+	return (digest_count);
3303+	}
3304+
3305+/*
3306+ * Init context for encryption or decryption using a symmetric key.
3307+ */
3308+static int pk11_init_symmetric(EVP_CIPHER_CTX *ctx, PK11_CIPHER *pcipher,
3309+	PK11_SESSION *sp, CK_MECHANISM_PTR pmech)
3310+	{
3311+	CK_RV rv;
3312+#ifdef	SOLARIS_AES_CTR
3313+	CK_AES_CTR_PARAMS ctr_params;
3314+#endif	/* SOLARIS_AES_CTR */
3315+
3316+	/*
3317+	 * We expect pmech->mechanism to be already set and
3318+	 * pParameter/ulParameterLen initialized to NULL/0 before
3319+	 * pk11_init_symetric() is called.
3320+	 */
3321+	OPENSSL_assert(pmech->mechanism != 0);
3322+	OPENSSL_assert(pmech->pParameter == NULL);
3323+	OPENSSL_assert(pmech->ulParameterLen == 0);
3324+
3325+#ifdef	SOLARIS_AES_CTR
3326+	if (ctx->cipher->nid == NID_aes_128_ctr ||
3327+	    ctx->cipher->nid == NID_aes_192_ctr ||
3328+	    ctx->cipher->nid == NID_aes_256_ctr)
3329+		{
3330+		pmech->pParameter = (void *)(&ctr_params);
3331+		pmech->ulParameterLen = sizeof (ctr_params);
3332+		/*
3333+		 * For now, we are limited to the fixed length of the counter,
3334+		 * it covers the whole counter block. That's what RFC 4344
3335+		 * needs. For more information on internal structure of the
3336+		 * counter block, see RFC 3686. If needed in the future, we can
3337+		 * add code so that the counter length can be set via
3338+		 * ENGINE_ctrl() function.
3339+		 */
3340+		ctr_params.ulCounterBits = AES_BLOCK_SIZE * 8;
3341+		OPENSSL_assert(pcipher->iv_len == AES_BLOCK_SIZE);
3342+		(void) memcpy(ctr_params.cb, ctx->iv, AES_BLOCK_SIZE);
3343+		}
3344+	else
3345+#endif	/* SOLARIS_AES_CTR */
3346+		{
3347+		if (pcipher->iv_len > 0)
3348+			{
3349+			pmech->pParameter = (void *)ctx->iv;
3350+			pmech->ulParameterLen = pcipher->iv_len;
3351+			}
3352+		}
3353+
3354+	/* if we get here, the encryption needs to be reinitialized */
3355+	if (ctx->encrypt)
3356+		rv = pFuncList->C_EncryptInit(sp->session, pmech,
3357+			sp->opdata_cipher_key);
3358+	else
3359+		rv = pFuncList->C_DecryptInit(sp->session, pmech,
3360+			sp->opdata_cipher_key);
3361+
3362+	if (rv != CKR_OK)
3363+		{
3364+		PK11err_add_data(PK11_F_CIPHER_INIT, ctx->encrypt ?
3365+		    PK11_R_ENCRYPTINIT : PK11_R_DECRYPTINIT, rv);
3366+		pk11_return_session(sp, OP_CIPHER);
3367+		return (0);
3368+		}
3369+
3370+	return (1);
3371+	}
3372+
3373+/* ARGSUSED */
3374+static int
3375+pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
3376+    const unsigned char *iv, int enc)
3377+	{
3378+	CK_MECHANISM mech;
3379+	int index;
3380+	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
3381+	PK11_SESSION *sp;
3382+	PK11_CIPHER *p_ciph_table_row;
3383+
3384+	state->sp = NULL;
3385+
3386+	index = cipher_nid_to_pk11(ctx->cipher->nid);
3387+	if (index < 0 || index >= PK11_CIPHER_MAX)
3388+		return (0);
3389+
3390+	p_ciph_table_row = &ciphers[index];
3391+	/*
3392+	 * iv_len in the ctx->cipher structure is the maximum IV length for the
3393+	 * current cipher and it must be less or equal to the IV length in our
3394+	 * ciphers table. The key length must be in the allowed interval. From
3395+	 * all cipher modes that the PKCS#11 engine supports only RC4 allows a
3396+	 * key length to be in some range, all other NIDs have a precise key
3397+	 * length. Every application can define its own EVP functions so this
3398+	 * code serves as a sanity check.
3399+	 *
3400+	 * Note that the reason why the IV length in ctx->cipher might be
3401+	 * greater than the actual length is that OpenSSL uses BLOCK_CIPHER_defs
3402+	 * macro to define functions that return EVP structures for all DES
3403+	 * modes. So, even ECB modes get 8 byte IV.
3404+	 */
3405+	if (ctx->cipher->iv_len < p_ciph_table_row->iv_len ||
3406+	    ctx->key_len < p_ciph_table_row->min_key_len ||
3407+	    ctx->key_len > p_ciph_table_row->max_key_len) {
3408+		PK11err(PK11_F_CIPHER_INIT, PK11_R_KEY_OR_IV_LEN_PROBLEM);
3409+		return (0);
3410+	}
3411+
3412+	if ((sp = pk11_get_session(OP_CIPHER)) == NULL)
3413+		return (0);
3414+
3415+	/* if applicable, the mechanism parameter is used for IV */
3416+	mech.mechanism = p_ciph_table_row->mech_type;
3417+	mech.pParameter = NULL;
3418+	mech.ulParameterLen = 0;
3419+
3420+	/* The key object is destroyed here if it is not the current key. */
3421+	(void) check_new_cipher_key(sp, key, ctx->key_len);
3422+
3423+	/*
3424+	 * If the key is the same and the encryption is also the same, then
3425+	 * just reuse it. However, we must not forget to reinitialize the
3426+	 * context that was finalized in pk11_cipher_cleanup().
3427+	 */
3428+	if (sp->opdata_cipher_key != CK_INVALID_HANDLE &&
3429+	    sp->opdata_encrypt == ctx->encrypt)
3430+		{
3431+		state->sp = sp;
3432+		if (pk11_init_symmetric(ctx, p_ciph_table_row, sp, &mech) == 0)
3433+			return (0);
3434+
3435+		return (1);
3436+		}
3437+
3438+	/*
3439+	 * Check if the key has been invalidated. If so, a new key object
3440+	 * needs to be created.
3441+	 */
3442+	if (sp->opdata_cipher_key == CK_INVALID_HANDLE)
3443+		{
3444+		sp->opdata_cipher_key = pk11_get_cipher_key(
3445+			ctx, key, p_ciph_table_row->key_type, sp);
3446+		}
3447+
3448+	if (sp->opdata_encrypt != ctx->encrypt && sp->opdata_encrypt != -1)
3449+		{
3450+		/*
3451+		 * The previous encryption/decryption is different. Need to
3452+		 * terminate the previous * active encryption/decryption here.
3453+		 */
3454+		if (!pk11_cipher_final(sp))
3455+			{
3456+			pk11_return_session(sp, OP_CIPHER);
3457+			return (0);
3458+			}
3459+		}
3460+
3461+	if (sp->opdata_cipher_key == CK_INVALID_HANDLE)
3462+		{
3463+		pk11_return_session(sp, OP_CIPHER);
3464+		return (0);
3465+		}
3466+
3467+	/* now initialize the context with a new key */
3468+	if (pk11_init_symmetric(ctx, p_ciph_table_row, sp, &mech) == 0)
3469+		return (0);
3470+
3471+	sp->opdata_encrypt = ctx->encrypt;
3472+	state->sp = sp;
3473+
3474+	return (1);
3475+	}
3476+
3477+/*
3478+ * When reusing the same key in an encryption/decryption session for a
3479+ * decryption/encryption session, we need to close the active session
3480+ * and recreate a new one. Note that the key is in the global session so
3481+ * that it needs not be recreated.
3482+ *
3483+ * It is more appropriate to use C_En/DecryptFinish here. At the time of this
3484+ * development, these two functions in the PKCS#11 libraries used return
3485+ * unexpected errors when passing in 0 length output. It may be a good
3486+ * idea to try them again if performance is a problem here and fix
3487+ * C_En/DecryptFinial if there are bugs there causing the problem.
3488+ */
3489+static int
3490+pk11_cipher_final(PK11_SESSION *sp)
3491+	{
3492+	CK_RV rv;
3493+
3494+	rv = pFuncList->C_CloseSession(sp->session);
3495+	if (rv != CKR_OK)
3496+		{
3497+		PK11err_add_data(PK11_F_CIPHER_FINAL, PK11_R_CLOSESESSION, rv);
3498+		return (0);
3499+		}
3500+
3501+	rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
3502+		NULL_PTR, NULL_PTR, &sp->session);
3503+	if (rv != CKR_OK)
3504+		{
3505+		PK11err_add_data(PK11_F_CIPHER_FINAL, PK11_R_OPENSESSION, rv);
3506+		return (0);
3507+		}
3508+
3509+	return (1);
3510+	}
3511+
3512+/*
3513+ * An engine interface function. The calling function allocates sufficient
3514+ * memory for the output buffer "out" to hold the results.
3515+ */
3516+#if OPENSSL_VERSION_NUMBER < 0x10000000L
3517+static int
3518+pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
3519+	const unsigned char *in, unsigned int inl)
3520+#else
3521+static int
3522+pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
3523+	const unsigned char *in, size_t inl)
3524+#endif
3525+	{
3526+	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
3527+	PK11_SESSION *sp;
3528+	CK_RV rv;
3529+	unsigned long outl = inl;
3530+
3531+	if (state == NULL || state->sp == NULL)
3532+		return (0);
3533+
3534+	sp = (PK11_SESSION *) state->sp;
3535+
3536+	if (!inl)
3537+		return (1);
3538+
3539+	/* RC4 is the only stream cipher we support */
3540+	if (ctx->cipher->nid != NID_rc4 && (inl % ctx->cipher->block_size) != 0)
3541+		return (0);
3542+
3543+	if (ctx->encrypt)
3544+		{
3545+		rv = pFuncList->C_EncryptUpdate(sp->session,
3546+			(unsigned char *)in, inl, out, &outl);
3547+
3548+		if (rv != CKR_OK)
3549+			{
3550+			PK11err_add_data(PK11_F_CIPHER_DO_CIPHER,
3551+			    PK11_R_ENCRYPTUPDATE, rv);
3552+			return (0);
3553+			}
3554+		}
3555+	else
3556+		{
3557+		rv = pFuncList->C_DecryptUpdate(sp->session,
3558+			(unsigned char *)in, inl, out, &outl);
3559+
3560+		if (rv != CKR_OK)
3561+			{
3562+			PK11err_add_data(PK11_F_CIPHER_DO_CIPHER,
3563+			    PK11_R_DECRYPTUPDATE, rv);
3564+			return (0);
3565+			}
3566+		}
3567+
3568+	/*
3569+	 * For DES_CBC, DES3_CBC, AES_CBC, and RC4, the output size is always
3570+	 * the same size of input.
3571+	 * The application has guaranteed to call the block ciphers with
3572+	 * correctly aligned buffers.
3573+	 */
3574+	if (inl != outl)
3575+		return (0);
3576+
3577+	return (1);
3578+	}
3579+
3580+/*
3581+ * Return the session to the pool. Calling C_EncryptFinal() and C_DecryptFinal()
3582+ * here is the right thing because in EVP_DecryptFinal_ex(), engine's
3583+ * do_cipher() is not even called, and in EVP_EncryptFinal_ex() it is called but
3584+ * the engine can't find out that it's the finalizing call. We wouldn't
3585+ * necessarily have to finalize the context here since reinitializing it with
3586+ * C_(Encrypt|Decrypt)Init() should be fine but for the sake of correctness,
3587+ * let's do it. Some implementations might leak memory if the previously used
3588+ * context is initialized without finalizing it first.
3589+ */
3590+static int
3591+pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx)
3592+	{
3593+	CK_RV rv;
3594+	CK_ULONG len = EVP_MAX_BLOCK_LENGTH;
3595+	CK_BYTE buf[EVP_MAX_BLOCK_LENGTH];
3596+	PK11_CIPHER_STATE *state = ctx->cipher_data;
3597+
3598+	if (state != NULL && state->sp != NULL)
3599+		{
3600+		/*
3601+		 * We are not interested in the data here, we just need to get
3602+		 * rid of the context.
3603+		 */
3604+		if (ctx->encrypt)
3605+			rv = pFuncList->C_EncryptFinal(
3606+			    state->sp->session, buf, &len);
3607+		else
3608+			rv = pFuncList->C_DecryptFinal(
3609+			    state->sp->session, buf, &len);
3610+
3611+		if (rv != CKR_OK)
3612+			{
3613+			PK11err_add_data(PK11_F_CIPHER_CLEANUP, ctx->encrypt ?
3614+			    PK11_R_ENCRYPTFINAL : PK11_R_DECRYPTFINAL, rv);
3615+			pk11_return_session(state->sp, OP_CIPHER);
3616+			return (0);
3617+			}
3618+
3619+		pk11_return_session(state->sp, OP_CIPHER);
3620+		state->sp = NULL;
3621+		}
3622+
3623+	return (1);
3624+	}
3625+
3626+/*
3627+ * Registered by the ENGINE when used to find out how to deal with
3628+ * a particular NID in the ENGINE. This says what we'll do at the
3629+ * top level - note, that list is restricted by what we answer with
3630+ */
3631+/* ARGSUSED */
3632+static int
3633+pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
3634+	const int **nids, int nid)
3635+	{
3636+	if (!cipher)
3637+		return (pk11_usable_ciphers(nids));
3638+
3639+	switch (nid)
3640+		{
3641+		case NID_des_ede3_cbc:
3642+			*cipher = &pk11_3des_cbc;
3643+			break;
3644+		case NID_des_cbc:
3645+			*cipher = &pk11_des_cbc;
3646+			break;
3647+		case NID_des_ede3_ecb:
3648+			*cipher = &pk11_3des_ecb;
3649+			break;
3650+		case NID_des_ecb:
3651+			*cipher = &pk11_des_ecb;
3652+			break;
3653+		case NID_aes_128_cbc:
3654+			*cipher = &pk11_aes_128_cbc;
3655+			break;
3656+		case NID_aes_192_cbc:
3657+			*cipher = &pk11_aes_192_cbc;
3658+			break;
3659+		case NID_aes_256_cbc:
3660+			*cipher = &pk11_aes_256_cbc;
3661+			break;
3662+		case NID_aes_128_ecb:
3663+			*cipher = &pk11_aes_128_ecb;
3664+			break;
3665+		case NID_aes_192_ecb:
3666+			*cipher = &pk11_aes_192_ecb;
3667+			break;
3668+		case NID_aes_256_ecb:
3669+			*cipher = &pk11_aes_256_ecb;
3670+			break;
3671+		case NID_bf_cbc:
3672+			*cipher = &pk11_bf_cbc;
3673+			break;
3674+		case NID_rc4:
3675+			*cipher = &pk11_rc4;
3676+			break;
3677+		default:
3678+#ifdef	SOLARIS_AES_CTR
3679+			/*
3680+			 * These can't be in separated cases because the NIDs
3681+			 * here are not constants.
3682+			 */
3683+			if (nid == NID_aes_128_ctr)
3684+				*cipher = &pk11_aes_128_ctr;
3685+			else if (nid == NID_aes_192_ctr)
3686+				*cipher = &pk11_aes_192_ctr;
3687+			else if (nid == NID_aes_256_ctr)
3688+				*cipher = &pk11_aes_256_ctr;
3689+			else
3690+#endif	/* SOLARIS_AES_CTR */
3691+			*cipher = NULL;
3692+			break;
3693+		}
3694+	return (*cipher != NULL);
3695+	}
3696+
3697+/* ARGSUSED */
3698+static int
3699+pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
3700+	const int **nids, int nid)
3701+	{
3702+	if (!digest)
3703+		return (pk11_usable_digests(nids));
3704+
3705+	switch (nid)
3706+		{
3707+		case NID_md5:
3708+			*digest = &pk11_md5;
3709+			break;
3710+		case NID_sha1:
3711+			*digest = &pk11_sha1;
3712+			break;
3713+		case NID_sha224:
3714+			*digest = &pk11_sha224;
3715+			break;
3716+		case NID_sha256:
3717+			*digest = &pk11_sha256;
3718+			break;
3719+		case NID_sha384:
3720+			*digest = &pk11_sha384;
3721+			break;
3722+		case NID_sha512:
3723+			*digest = &pk11_sha512;
3724+			break;
3725+		default:
3726+			*digest = NULL;
3727+			break;
3728+		}
3729+	return (*digest != NULL);
3730+	}
3731+
3732+
3733+/* Create a secret key object in a PKCS#11 session */
3734+static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
3735+	const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp)
3736+	{
3737+	CK_RV rv;
3738+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
3739+	CK_OBJECT_CLASS obj_key = CKO_SECRET_KEY;
3740+	CK_ULONG ul_key_attr_count = 6;
3741+	unsigned char key_buf[PK11_KEY_LEN_MAX];
3742+
3743+	CK_ATTRIBUTE  a_key_template[] =
3744+		{
3745+		{CKA_CLASS, (void*) NULL, sizeof (CK_OBJECT_CLASS)},
3746+		{CKA_KEY_TYPE, (void*) NULL, sizeof (CK_KEY_TYPE)},
3747+		{CKA_TOKEN, &myfalse, sizeof (myfalse)},
3748+		{CKA_ENCRYPT, &mytrue, sizeof (mytrue)},
3749+		{CKA_DECRYPT, &mytrue, sizeof (mytrue)},
3750+		{CKA_VALUE, (void*) NULL, 0},
3751+		};
3752+
3753+	/*
3754+	 * Create secret key object in global_session. All other sessions
3755+	 * can use the key handles. Here is why:
3756+	 * OpenSSL will call EncryptInit and EncryptUpdate using a secret key.
3757+	 * It may then call DecryptInit and DecryptUpdate using the same key.
3758+	 * To use the same key object, we need to call EncryptFinal with
3759+	 * a 0 length message. Currently, this does not work for 3DES
3760+	 * mechanism. To get around this problem, we close the session and
3761+	 * then create a new session to use the same key object. When a session
3762+	 * is closed, all the object handles will be invalid. Thus, create key
3763+	 * objects in a global session, an individual session may be closed to
3764+	 * terminate the active operation.
3765+	 */
3766+	CK_SESSION_HANDLE session = global_session;
3767+	a_key_template[0].pValue = &obj_key;
3768+	a_key_template[1].pValue = &key_type;
3769+	if (ctx->key_len > PK11_KEY_LEN_MAX)
3770+		{
3771+		a_key_template[5].pValue = (void *) key;
3772+		}
3773+	else
3774+		{
3775+		memset(key_buf, 0, PK11_KEY_LEN_MAX);
3776+		memcpy(key_buf, key, ctx->key_len);
3777+		if ((key_type == CKK_DES) ||
3778+		    (key_type == CKK_DES2) ||
3779+		    (key_type == CKK_DES3))
3780+			DES_fixup_key_parity((DES_cblock *) &key_buf[0]);
3781+		if ((key_type == CKK_DES2) ||
3782+		    (key_type == CKK_DES3))
3783+			DES_fixup_key_parity((DES_cblock *) &key_buf[8]);
3784+		if (key_type == CKK_DES3)
3785+			DES_fixup_key_parity((DES_cblock *) &key_buf[16]);
3786+		a_key_template[5].pValue = (void *) key_buf;
3787+		}
3788+	a_key_template[5].ulValueLen = (unsigned long) ctx->key_len;
3789+
3790+	rv = pFuncList->C_CreateObject(session,
3791+		a_key_template, ul_key_attr_count, &h_key);
3792+	if (rv != CKR_OK)
3793+		{
3794+		memset(key_buf, 0, PK11_KEY_LEN_MAX);
3795+		PK11err_add_data(PK11_F_GET_CIPHER_KEY, PK11_R_CREATEOBJECT,
3796+		    rv);
3797+		goto err;
3798+		}
3799+
3800+	/*
3801+	 * Save the key information used in this session.
3802+	 * The max can be saved is PK11_KEY_LEN_MAX.
3803+	 */
3804+	if (ctx->key_len > PK11_KEY_LEN_MAX)
3805+		{
3806+		sp->opdata_key_len = PK11_KEY_LEN_MAX;
3807+		(void) memcpy(sp->opdata_key, key, sp->opdata_key_len);
3808+		}
3809+	else
3810+		{
3811+		sp->opdata_key_len = ctx->key_len;
3812+		(void) memcpy(sp->opdata_key, key_buf, sp->opdata_key_len);
3813+		}
3814+	memset(key_buf, 0, PK11_KEY_LEN_MAX);
3815+err:
3816+
3817+	return (h_key);
3818+	}
3819+
3820+static int
3821+md_nid_to_pk11(int nid)
3822+	{
3823+	int i;
3824+
3825+	for (i = 0; i < PK11_DIGEST_MAX; i++)
3826+		if (digests[i].nid == nid)
3827+			return (digests[i].id);
3828+	return (-1);
3829+	}
3830+
3831+static int
3832+pk11_digest_init(EVP_MD_CTX *ctx)
3833+	{
3834+	CK_RV rv;
3835+	CK_MECHANISM mech;
3836+	int index;
3837+	PK11_SESSION *sp;
3838+	PK11_DIGEST *pdp;
3839+	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
3840+
3841+	state->sp = NULL;
3842+
3843+	index = md_nid_to_pk11(ctx->digest->type);
3844+	if (index < 0 || index >= PK11_DIGEST_MAX)
3845+		return (0);
3846+
3847+	pdp = &digests[index];
3848+	if ((sp = pk11_get_session(OP_DIGEST)) == NULL)
3849+		return (0);
3850+
3851+	/* at present, no parameter is needed for supported digests */
3852+	mech.mechanism = pdp->mech_type;
3853+	mech.pParameter = NULL;
3854+	mech.ulParameterLen = 0;
3855+
3856+	rv = pFuncList->C_DigestInit(sp->session, &mech);
3857+
3858+	if (rv != CKR_OK)
3859+		{
3860+		PK11err_add_data(PK11_F_DIGEST_INIT, PK11_R_DIGESTINIT, rv);
3861+		pk11_return_session(sp, OP_DIGEST);
3862+		return (0);
3863+		}
3864+
3865+	state->sp = sp;
3866+
3867+	return (1);
3868+	}
3869+
3870+static int
3871+pk11_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
3872+	{
3873+	CK_RV rv;
3874+	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
3875+
3876+	/* 0 length message will cause a failure in C_DigestFinal */
3877+	if (count == 0)
3878+		return (1);
3879+
3880+	if (state == NULL || state->sp == NULL)
3881+		return (0);
3882+
3883+	rv = pFuncList->C_DigestUpdate(state->sp->session, (CK_BYTE *) data,
3884+		count);
3885+
3886+	if (rv != CKR_OK)
3887+		{
3888+		PK11err_add_data(PK11_F_DIGEST_UPDATE, PK11_R_DIGESTUPDATE, rv);
3889+		pk11_return_session(state->sp, OP_DIGEST);
3890+		state->sp = NULL;
3891+		return (0);
3892+		}
3893+
3894+	return (1);
3895+	}
3896+
3897+static int
3898+pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
3899+	{
3900+	CK_RV rv;
3901+	unsigned long len;
3902+	PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
3903+	len = ctx->digest->md_size;
3904+
3905+	if (state == NULL || state->sp == NULL)
3906+		return (0);
3907+
3908+	rv = pFuncList->C_DigestFinal(state->sp->session, md, &len);
3909+
3910+	if (rv != CKR_OK)
3911+		{
3912+		PK11err_add_data(PK11_F_DIGEST_FINAL, PK11_R_DIGESTFINAL, rv);
3913+		pk11_return_session(state->sp, OP_DIGEST);
3914+		state->sp = NULL;
3915+		return (0);
3916+		}
3917+
3918+	if (ctx->digest->md_size != len)
3919+		return (0);
3920+
3921+	/*
3922+	 * Final is called and digest is returned, so return the session
3923+	 * to the pool
3924+	 */
3925+	pk11_return_session(state->sp, OP_DIGEST);
3926+	state->sp = NULL;
3927+
3928+	return (1);
3929+	}
3930+
3931+static int
3932+pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
3933+	{
3934+	CK_RV rv;
3935+	int ret = 0;
3936+	PK11_CIPHER_STATE *state, *state_to;
3937+	CK_BYTE_PTR pstate = NULL;
3938+	CK_ULONG ul_state_len;
3939+
3940+	/* The copy-from state */
3941+	state = (PK11_CIPHER_STATE *) from->md_data;
3942+	if (state == NULL || state->sp == NULL)
3943+		goto err;
3944+
3945+	/* Initialize the copy-to state */
3946+	if (!pk11_digest_init(to))
3947+		goto err;
3948+	state_to = (PK11_CIPHER_STATE *) to->md_data;
3949+
3950+	/* Get the size of the operation state of the copy-from session */
3951+	rv = pFuncList->C_GetOperationState(state->sp->session, NULL,
3952+		&ul_state_len);
3953+
3954+	if (rv != CKR_OK)
3955+		{
3956+		PK11err_add_data(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE,
3957+		    rv);
3958+		goto err;
3959+		}
3960+	if (ul_state_len == 0)
3961+		{
3962+		goto err;
3963+		}
3964+
3965+	pstate = OPENSSL_malloc(ul_state_len);
3966+	if (pstate == NULL)
3967+		{
3968+		PK11err(PK11_F_DIGEST_COPY, PK11_R_MALLOC_FAILURE);
3969+		goto err;
3970+		}
3971+
3972+	/* Get the operation state of the copy-from session */
3973+	rv = pFuncList->C_GetOperationState(state->sp->session, pstate,
3974+		&ul_state_len);
3975+
3976+	if (rv != CKR_OK)
3977+		{
3978+		PK11err_add_data(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE,
3979+		    rv);
3980+		goto err;
3981+		}
3982+
3983+	/* Set the operation state of the copy-to session */
3984+	rv = pFuncList->C_SetOperationState(state_to->sp->session, pstate,
3985+		ul_state_len, 0, 0);
3986+
3987+	if (rv != CKR_OK)
3988+		{
3989+		PK11err_add_data(PK11_F_DIGEST_COPY,
3990+		    PK11_R_SET_OPERATION_STATE, rv);
3991+		goto err;
3992+		}
3993+
3994+	ret = 1;
3995+err:
3996+	if (pstate != NULL)
3997+		OPENSSL_free(pstate);
3998+
3999+	return (ret);
4000+	}
4001+
4002+/* Return any pending session state to the pool */
4003+static int
4004+pk11_digest_cleanup(EVP_MD_CTX *ctx)
4005+	{
4006+	PK11_CIPHER_STATE *state = ctx->md_data;
4007+	unsigned char buf[EVP_MAX_MD_SIZE];
4008+
4009+	if (state != NULL && state->sp != NULL)
4010+		{
4011+		/*
4012+		 * If state->sp is not NULL then pk11_digest_final() has not
4013+		 * been called yet. We must call it now to free any memory
4014+		 * that might have been allocated in the token when
4015+		 * pk11_digest_init() was called. pk11_digest_final()
4016+		 * will return the session to the cache.
4017+		 */
4018+		if (!pk11_digest_final(ctx, buf))
4019+			return (0);
4020+		}
4021+
4022+	return (1);
4023+	}
4024+
4025+/*
4026+ * Check if the new key is the same as the key object in the session. If the key
4027+ * is the same, no need to create a new key object. Otherwise, the old key
4028+ * object needs to be destroyed and a new one will be created. Return 1 for
4029+ * cache hit, 0 for cache miss. Note that we must check the key length first
4030+ * otherwise we could end up reusing a different, longer key with the same
4031+ * prefix.
4032+ */
4033+static int check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key,
4034+	int key_len)
4035+	{
4036+	if (sp->opdata_key_len != key_len ||
4037+	    memcmp(sp->opdata_key, key, key_len) != 0)
4038+		{
4039+		(void) pk11_destroy_cipher_key_objects(sp);
4040+		return (0);
4041+		}
4042+	return (1);
4043+	}
4044+
4045+/* Destroy one or more secret key objects. */
4046+static int pk11_destroy_cipher_key_objects(PK11_SESSION *session)
4047+	{
4048+	int ret = 0;
4049+	PK11_SESSION *sp = NULL;
4050+	PK11_SESSION *local_free_session;
4051+
4052+	if (session != NULL)
4053+		local_free_session = session;
4054+	else
4055+		{
4056+#ifndef NOPTHREADS
4057+		OPENSSL_assert(pthread_mutex_lock(session_cache[OP_CIPHER].lock) == 0);
4058+#else
4059+		CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
4060+#endif
4061+		local_free_session = session_cache[OP_CIPHER].head;
4062+		}
4063+
4064+	while ((sp = local_free_session) != NULL)
4065+		{
4066+		local_free_session = sp->next;
4067+
4068+		if (sp->opdata_cipher_key != CK_INVALID_HANDLE)
4069+			{
4070+			/*
4071+			 * The secret key object is created in the
4072+			 * global_session. See pk11_get_cipher_key().
4073+			 */
4074+			if (pk11_destroy_object(global_session,
4075+				sp->opdata_cipher_key, CK_FALSE) == 0)
4076+				goto err;
4077+			sp->opdata_cipher_key = CK_INVALID_HANDLE;
4078+			}
4079+		}
4080+	ret = 1;
4081+err:
4082+
4083+#ifndef NOPTHREADS
4084+	if (session == NULL)
4085+		OPENSSL_assert(pthread_mutex_unlock(session_cache[OP_CIPHER].lock) == 0);
4086+#else
4087+	if (session == NULL)
4088+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
4089+#endif
4090+
4091+	return (ret);
4092+	}
4093+
4094+
4095+/*
4096+ * Public key mechanisms optionally supported
4097+ *
4098+ * CKM_RSA_X_509
4099+ * CKM_RSA_PKCS
4100+ * CKM_DSA
4101+ *
4102+ * The first slot that supports at least one of those mechanisms is chosen as a
4103+ * public key slot.
4104+ *
4105+ * Symmetric ciphers optionally supported
4106+ *
4107+ * CKM_DES3_CBC
4108+ * CKM_DES_CBC
4109+ * CKM_AES_CBC
4110+ * CKM_DES3_ECB
4111+ * CKM_DES_ECB
4112+ * CKM_AES_ECB
4113+ * CKM_AES_CTR
4114+ * CKM_RC4
4115+ * CKM_BLOWFISH_CBC
4116+ *
4117+ * Digests optionally supported
4118+ *
4119+ * CKM_MD5
4120+ * CKM_SHA_1
4121+ * CKM_SHA224
4122+ * CKM_SHA256
4123+ * CKM_SHA384
4124+ * CKM_SHA512
4125+ *
4126+ * The output of this function is a set of global variables indicating which
4127+ * mechanisms from RSA, DSA, DH and RAND are present, and also two arrays of
4128+ * mechanisms, one for symmetric ciphers and one for digests. Also, 3 global
4129+ * variables carry information about which slot was chosen for (a) public key
4130+ * mechanisms, (b) random operations, and (c) symmetric ciphers and digests.
4131+ */
4132+static int
4133+pk11_choose_slots(int *any_slot_found)
4134+	{
4135+	CK_SLOT_ID_PTR pSlotList = NULL_PTR;
4136+	CK_ULONG ulSlotCount = 0;
4137+	CK_MECHANISM_INFO mech_info;
4138+	CK_TOKEN_INFO token_info;
4139+	unsigned int i;
4140+	CK_RV rv;
4141+	CK_SLOT_ID best_slot_sofar = 0;
4142+	CK_BBOOL found_candidate_slot = CK_FALSE;
4143+	int slot_n_cipher = 0;
4144+	int slot_n_digest = 0;
4145+	CK_SLOT_ID current_slot = 0;
4146+	int current_slot_n_cipher = 0;
4147+	int current_slot_n_digest = 0;
4148+
4149+	int local_cipher_nids[PK11_CIPHER_MAX];
4150+	int local_digest_nids[PK11_DIGEST_MAX];
4151+
4152+	/* let's initialize the output parameter */
4153+	if (any_slot_found != NULL)
4154+		*any_slot_found = 0;
4155+
4156+	/* Get slot list for memory allocation */
4157+	rv = pFuncList->C_GetSlotList(CK_FALSE, NULL_PTR, &ulSlotCount);
4158+
4159+	if (rv != CKR_OK)
4160+		{
4161+		PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
4162+		return (0);
4163+		}
4164+
4165+	/* it's not an error if we didn't find any providers */
4166+	if (ulSlotCount == 0)
4167+		{
4168+#ifdef	DEBUG_SLOT_SELECTION
4169+		fprintf(stderr, "%s: no crypto providers found\n", PK11_DBG);
4170+#endif	/* DEBUG_SLOT_SELECTION */
4171+		return (1);
4172+		}
4173+
4174+	pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
4175+
4176+	if (pSlotList == NULL)
4177+		{
4178+		PK11err(PK11_F_CHOOSE_SLOT, PK11_R_MALLOC_FAILURE);
4179+		return (0);
4180+		}
4181+
4182+	/* Get the slot list for processing */
4183+	rv = pFuncList->C_GetSlotList(CK_FALSE, pSlotList, &ulSlotCount);
4184+	if (rv != CKR_OK)
4185+		{
4186+		PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
4187+		OPENSSL_free(pSlotList);
4188+		return (0);
4189+		}
4190+
4191+#ifdef	DEBUG_SLOT_SELECTION
4192+	fprintf(stderr, "%s: provider: %s\n", PK11_DBG, def_PK11_LIBNAME);
4193+	fprintf(stderr, "%s: number of slots: %d\n", PK11_DBG, ulSlotCount);
4194+
4195+	fprintf(stderr, "%s: == checking rand slots ==\n", PK11_DBG);
4196+#endif	/* DEBUG_SLOT_SELECTION */
4197+	for (i = 0; i < ulSlotCount; i++)
4198+		{
4199+		current_slot = pSlotList[i];
4200+
4201+#ifdef	DEBUG_SLOT_SELECTION
4202+	fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
4203+#endif	/* DEBUG_SLOT_SELECTION */
4204+		/* Check if slot has random support. */
4205+		rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
4206+		if (rv != CKR_OK)
4207+			continue;
4208+
4209+#ifdef	DEBUG_SLOT_SELECTION
4210+	fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
4211+#endif	/* DEBUG_SLOT_SELECTION */
4212+
4213+		if (token_info.flags & CKF_RNG)
4214+			{
4215+#ifdef	DEBUG_SLOT_SELECTION
4216+	fprintf(stderr, "%s: this token has CKF_RNG flag\n", PK11_DBG);
4217+#endif	/* DEBUG_SLOT_SELECTION */
4218+			pk11_have_random = CK_TRUE;
4219+			rand_SLOTID = current_slot;
4220+			break;
4221+			}
4222+		}
4223+
4224+#ifdef	DEBUG_SLOT_SELECTION
4225+	fprintf(stderr, "%s: == checking pubkey slots ==\n", PK11_DBG);
4226+#endif	/* DEBUG_SLOT_SELECTION */
4227+
4228+	pubkey_SLOTID = pSlotList[0];
4229+	for (i = 0; i < ulSlotCount; i++)
4230+		{
4231+		CK_BBOOL slot_has_rsa = CK_FALSE;
4232+		CK_BBOOL slot_has_recover = CK_FALSE;
4233+		CK_BBOOL slot_has_dsa = CK_FALSE;
4234+		CK_BBOOL slot_has_dh = CK_FALSE;
4235+		current_slot = pSlotList[i];
4236+
4237+#ifdef	DEBUG_SLOT_SELECTION
4238+	fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
4239+#endif	/* DEBUG_SLOT_SELECTION */
4240+		rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
4241+		if (rv != CKR_OK)
4242+			continue;
4243+
4244+#ifdef	DEBUG_SLOT_SELECTION
4245+	fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
4246+#endif	/* DEBUG_SLOT_SELECTION */
4247+
4248+#ifndef OPENSSL_NO_RSA
4249+		/*
4250+		 * Check if this slot is capable of signing and
4251+		 * verifying with CKM_RSA_PKCS.
4252+		 */
4253+		rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS,
4254+			&mech_info);
4255+
4256+		if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
4257+				(mech_info.flags & CKF_VERIFY)))
4258+			{
4259+			/*
4260+			 * Check if this slot is capable of encryption,
4261+			 * decryption, sign, and verify with CKM_RSA_X_509.
4262+			 */
4263+			rv = pFuncList->C_GetMechanismInfo(current_slot,
4264+			    CKM_RSA_X_509, &mech_info);
4265+
4266+			if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
4267+			    (mech_info.flags & CKF_VERIFY) &&
4268+			    (mech_info.flags & CKF_ENCRYPT) &&
4269+			    (mech_info.flags & CKF_DECRYPT)))
4270+				{
4271+				slot_has_rsa = CK_TRUE;
4272+				if (mech_info.flags & CKF_VERIFY_RECOVER)
4273+					{
4274+					slot_has_recover = CK_TRUE;
4275+					}
4276+				}
4277+			}
4278+#endif	/* OPENSSL_NO_RSA */
4279+
4280+#ifndef OPENSSL_NO_DSA
4281+		/*
4282+		 * Check if this slot is capable of signing and
4283+		 * verifying with CKM_DSA.
4284+		 */
4285+		rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_DSA,
4286+			&mech_info);
4287+		if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
4288+		    (mech_info.flags & CKF_VERIFY)))
4289+			{
4290+			slot_has_dsa = CK_TRUE;
4291+			}
4292+
4293+#endif	/* OPENSSL_NO_DSA */
4294+
4295+#ifndef OPENSSL_NO_DH
4296+		/*
4297+		 * Check if this slot is capable of DH key generataion and
4298+		 * derivation.
4299+		 */
4300+		rv = pFuncList->C_GetMechanismInfo(current_slot,
4301+		    CKM_DH_PKCS_KEY_PAIR_GEN, &mech_info);
4302+
4303+		if (rv == CKR_OK && (mech_info.flags & CKF_GENERATE_KEY_PAIR))
4304+			{
4305+			rv = pFuncList->C_GetMechanismInfo(current_slot,
4306+				CKM_DH_PKCS_DERIVE, &mech_info);
4307+			if (rv == CKR_OK && (mech_info.flags & CKF_DERIVE))
4308+				{
4309+				slot_has_dh = CK_TRUE;
4310+				}
4311+			}
4312+#endif	/* OPENSSL_NO_DH */
4313+
4314+		if (!found_candidate_slot &&
4315+		    (slot_has_rsa || slot_has_dsa || slot_has_dh))
4316+			{
4317+#ifdef	DEBUG_SLOT_SELECTION
4318+			fprintf(stderr,
4319+			    "%s: potential slot: %d\n", PK11_DBG, current_slot);
4320+#endif	/* DEBUG_SLOT_SELECTION */
4321+			best_slot_sofar = current_slot;
4322+			pk11_have_rsa = slot_has_rsa;
4323+			pk11_have_recover = slot_has_recover;
4324+			pk11_have_dsa = slot_has_dsa;
4325+			pk11_have_dh = slot_has_dh;
4326+			found_candidate_slot = CK_TRUE;
4327+			/*
4328+			 * Cache the flags for later use. We might
4329+			 * need those if RSA keys by reference feature
4330+			 * is used.
4331+			 */
4332+			pubkey_token_flags = token_info.flags;
4333+#ifdef	DEBUG_SLOT_SELECTION
4334+			fprintf(stderr,
4335+			    "%s: setting found_candidate_slot to CK_TRUE\n",
4336+			    PK11_DBG);
4337+			fprintf(stderr,
4338+			    "%s: best so far slot: %d\n", PK11_DBG,
4339+			    best_slot_sofar);
4340+			fprintf(stderr, "%s: pubkey flags changed to "
4341+			    "%lu.\n", PK11_DBG, pubkey_token_flags);
4342+			}
4343+		else
4344+			{
4345+			fprintf(stderr,
4346+			    "%s: no rsa/dsa/dh\n", PK11_DBG);
4347+			}
4348+#else
4349+			} /* if */
4350+#endif	/* DEBUG_SLOT_SELECTION */
4351+		} /* for */
4352+
4353+	if (found_candidate_slot == CK_TRUE)
4354+		{
4355+		pubkey_SLOTID = best_slot_sofar;
4356+		}
4357+
4358+	found_candidate_slot = CK_FALSE;
4359+	best_slot_sofar = 0;
4360+
4361+#ifdef	DEBUG_SLOT_SELECTION
4362+	fprintf(stderr, "%s: == checking cipher/digest ==\n", PK11_DBG);
4363+#endif	/* DEBUG_SLOT_SELECTION */
4364+
4365+	SLOTID = pSlotList[0];
4366+	for (i = 0; i < ulSlotCount; i++)
4367+		{
4368+#ifdef	DEBUG_SLOT_SELECTION
4369+	fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
4370+#endif	/* DEBUG_SLOT_SELECTION */
4371+
4372+		current_slot = pSlotList[i];
4373+		current_slot_n_cipher = 0;
4374+		current_slot_n_digest = 0;
4375+		(void) memset(local_cipher_nids, 0, sizeof (local_cipher_nids));
4376+		(void) memset(local_digest_nids, 0, sizeof (local_digest_nids));
4377+
4378+		pk11_find_symmetric_ciphers(pFuncList, current_slot,
4379+		    &current_slot_n_cipher, local_cipher_nids);
4380+
4381+		pk11_find_digests(pFuncList, current_slot,
4382+		    &current_slot_n_digest, local_digest_nids);
4383+
4384+#ifdef	DEBUG_SLOT_SELECTION
4385+		fprintf(stderr, "%s: current_slot_n_cipher %d\n", PK11_DBG,
4386+			current_slot_n_cipher);
4387+		fprintf(stderr, "%s: current_slot_n_digest %d\n", PK11_DBG,
4388+			current_slot_n_digest);
4389+		fprintf(stderr, "%s: best so far cipher/digest slot: %d\n",
4390+			PK11_DBG, best_slot_sofar);
4391+#endif	/* DEBUG_SLOT_SELECTION */
4392+
4393+		/*
4394+		 * If the current slot supports more ciphers/digests than
4395+		 * the previous best one we change the current best to this one,
4396+		 * otherwise leave it where it is.
4397+		 */
4398+		if ((current_slot_n_cipher + current_slot_n_digest) >
4399+		    (slot_n_cipher + slot_n_digest))
4400+			{
4401+#ifdef	DEBUG_SLOT_SELECTION
4402+			fprintf(stderr,
4403+				"%s: changing best so far slot to %d\n",
4404+				PK11_DBG, current_slot);
4405+#endif	/* DEBUG_SLOT_SELECTION */
4406+			best_slot_sofar = SLOTID = current_slot;
4407+			cipher_count = slot_n_cipher = current_slot_n_cipher;
4408+			digest_count = slot_n_digest = current_slot_n_digest;
4409+			(void) memcpy(cipher_nids, local_cipher_nids,
4410+			    sizeof (local_cipher_nids));
4411+			(void) memcpy(digest_nids, local_digest_nids,
4412+			    sizeof (local_digest_nids));
4413+			}
4414+		}
4415+
4416+#ifdef	DEBUG_SLOT_SELECTION
4417+	fprintf(stderr,
4418+	    "%s: chosen pubkey slot: %d\n", PK11_DBG, pubkey_SLOTID);
4419+	fprintf(stderr,
4420+	    "%s: chosen rand slot: %d\n", PK11_DBG, rand_SLOTID);
4421+	fprintf(stderr,
4422+	    "%s: chosen cipher/digest slot: %d\n", PK11_DBG, SLOTID);
4423+	fprintf(stderr,
4424+	    "%s: pk11_have_rsa %d\n", PK11_DBG, pk11_have_rsa);
4425+	fprintf(stderr,
4426+	    "%s: pk11_have_recover %d\n", PK11_DBG, pk11_have_recover);
4427+	fprintf(stderr,
4428+	    "%s: pk11_have_dsa %d\n", PK11_DBG, pk11_have_dsa);
4429+	fprintf(stderr,
4430+	    "%s: pk11_have_dh %d\n", PK11_DBG, pk11_have_dh);
4431+	fprintf(stderr,
4432+	    "%s: pk11_have_random %d\n", PK11_DBG, pk11_have_random);
4433+	fprintf(stderr,
4434+	    "%s: cipher_count %d\n", PK11_DBG, cipher_count);
4435+	fprintf(stderr,
4436+	    "%s: digest_count %d\n", PK11_DBG, digest_count);
4437+#endif	/* DEBUG_SLOT_SELECTION */
4438+
4439+	if (pSlotList != NULL)
4440+		OPENSSL_free(pSlotList);
4441+
4442+#ifdef	SOLARIS_HW_SLOT_SELECTION
4443+	OPENSSL_free(hw_cnids);
4444+	OPENSSL_free(hw_dnids);
4445+#endif	/* SOLARIS_HW_SLOT_SELECTION */
4446+
4447+	if (any_slot_found != NULL)
4448+		*any_slot_found = 1;
4449+	return (1);
4450+	}
4451+
4452+static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR pflist,
4453+    int slot_id, CK_MECHANISM_TYPE mech, int *current_slot_n_cipher,
4454+    int *local_cipher_nids, int id)
4455+	{
4456+	CK_MECHANISM_INFO mech_info;
4457+	CK_RV rv;
4458+
4459+#ifdef	DEBUG_SLOT_SELECTION
4460+	fprintf(stderr, "%s: checking mech: %x", PK11_DBG, mech);
4461+#endif	/* DEBUG_SLOT_SELECTION */
4462+	rv = pflist->C_GetMechanismInfo(slot_id, mech, &mech_info);
4463+
4464+	if (rv != CKR_OK)
4465+		{
4466+#ifdef	DEBUG_SLOT_SELECTION
4467+		fprintf(stderr, " not found\n");
4468+#endif	/* DEBUG_SLOT_SELECTION */
4469+		return;
4470+		}
4471+
4472+	if ((mech_info.flags & CKF_ENCRYPT) &&
4473+	    (mech_info.flags & CKF_DECRYPT))
4474+		{
4475+#ifdef	SOLARIS_HW_SLOT_SELECTION
4476+		if (nid_in_table(ciphers[id].nid, hw_cnids))
4477+#endif	/* SOLARIS_HW_SLOT_SELECTION */
4478+			{
4479+#ifdef	DEBUG_SLOT_SELECTION
4480+		fprintf(stderr, " usable\n");
4481+#endif	/* DEBUG_SLOT_SELECTION */
4482+			local_cipher_nids[(*current_slot_n_cipher)++] =
4483+			    ciphers[id].nid;
4484+			}
4485+#ifdef	SOLARIS_HW_SLOT_SELECTION
4486+#ifdef	DEBUG_SLOT_SELECTION
4487+		else
4488+			{
4489+		fprintf(stderr, " rejected, software implementation only\n");
4490+			}
4491+#endif	/* DEBUG_SLOT_SELECTION */
4492+#endif	/* SOLARIS_HW_SLOT_SELECTION */
4493+		}
4494+#ifdef	DEBUG_SLOT_SELECTION
4495+	else
4496+		{
4497+		fprintf(stderr, " unusable\n");
4498+		}
4499+#endif	/* DEBUG_SLOT_SELECTION */
4500+
4501+	return;
4502+	}
4503+
4504+static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
4505+    CK_MECHANISM_TYPE mech, int *current_slot_n_digest, int *local_digest_nids,
4506+    int id)
4507+	{
4508+	CK_MECHANISM_INFO mech_info;
4509+	CK_RV rv;
4510+
4511+#ifdef	DEBUG_SLOT_SELECTION
4512+	fprintf(stderr, "%s: checking mech: %x", PK11_DBG, mech);
4513+#endif	/* DEBUG_SLOT_SELECTION */
4514+	rv = pflist->C_GetMechanismInfo(slot_id, mech, &mech_info);
4515+
4516+	if (rv != CKR_OK)
4517+		{
4518+#ifdef	DEBUG_SLOT_SELECTION
4519+		fprintf(stderr, " not found\n");
4520+#endif	/* DEBUG_SLOT_SELECTION */
4521+		return;
4522+		}
4523+
4524+	if (mech_info.flags & CKF_DIGEST)
4525+		{
4526+#ifdef	SOLARIS_HW_SLOT_SELECTION
4527+		if (nid_in_table(digests[id].nid, hw_dnids))
4528+#endif	/* SOLARIS_HW_SLOT_SELECTION */
4529+			{
4530+#ifdef	DEBUG_SLOT_SELECTION
4531+		fprintf(stderr, " usable\n");
4532+#endif	/* DEBUG_SLOT_SELECTION */
4533+			local_digest_nids[(*current_slot_n_digest)++] =
4534+			    digests[id].nid;
4535+			}
4536+#ifdef	SOLARIS_HW_SLOT_SELECTION
4537+#ifdef	DEBUG_SLOT_SELECTION
4538+		else
4539+			{
4540+		fprintf(stderr, " rejected, software implementation only\n");
4541+			}
4542+#endif	/* DEBUG_SLOT_SELECTION */
4543+#endif	/* SOLARIS_HW_SLOT_SELECTION */
4544+		}
4545+#ifdef	DEBUG_SLOT_SELECTION
4546+	else
4547+		{
4548+		fprintf(stderr, " unusable\n");
4549+		}
4550+#endif	/* DEBUG_SLOT_SELECTION */
4551+
4552+	return;
4553+	}
4554+
4555+#ifdef	SOLARIS_AES_CTR
4556+/* create a new NID when we have no OID for that mechanism */
4557+static int pk11_add_NID(char *sn, char *ln)
4558+	{
4559+	ASN1_OBJECT *o;
4560+	int nid;
4561+
4562+	if ((o = ASN1_OBJECT_create(OBJ_new_nid(1), (unsigned char *)"",
4563+	    1, sn, ln)) == NULL)
4564+		{
4565+		return (0);
4566+		}
4567+
4568+	/* will return NID_undef on error */
4569+	nid = OBJ_add_object(o);
4570+	ASN1_OBJECT_free(o);
4571+
4572+	return (nid);
4573+	}
4574+
4575+/*
4576+ * Create new NIDs for AES counter mode. OpenSSL doesn't support them now so we
4577+ * have to help ourselves here.
4578+ */
4579+static int pk11_add_aes_ctr_NIDs(void)
4580+	{
4581+	/* are we already set? */
4582+	if (NID_aes_256_ctr != NID_undef)
4583+		return (1);
4584+
4585+	/*
4586+	 * There are no official names for AES counter modes yet so we just
4587+	 * follow the format of those that exist.
4588+	 */
4589+	if ((NID_aes_128_ctr = pk11_add_NID("AES-128-CTR", "aes-128-ctr")) ==
4590+	    NID_undef)
4591+		goto err;
4592+	ciphers[PK11_AES_128_CTR].nid = pk11_aes_128_ctr.nid = NID_aes_128_ctr;
4593+	if ((NID_aes_192_ctr = pk11_add_NID("AES-192-CTR", "aes-192-ctr")) ==
4594+	    NID_undef)
4595+		goto err;
4596+	ciphers[PK11_AES_192_CTR].nid = pk11_aes_192_ctr.nid = NID_aes_192_ctr;
4597+	if ((NID_aes_256_ctr = pk11_add_NID("AES-256-CTR", "aes-256-ctr")) ==
4598+	    NID_undef)
4599+		goto err;
4600+	ciphers[PK11_AES_256_CTR].nid = pk11_aes_256_ctr.nid = NID_aes_256_ctr;
4601+	return (1);
4602+
4603+err:
4604+	PK11err(PK11_F_ADD_AES_CTR_NIDS, PK11_R_ADD_NID_FAILED);
4605+	return (0);
4606+	}
4607+#endif	/* SOLARIS_AES_CTR */
4608+
4609+/* Find what symmetric ciphers this slot supports. */
4610+static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
4611+    CK_SLOT_ID current_slot, int *current_slot_n_cipher, int *local_cipher_nids)
4612+	{
4613+	int i;
4614+
4615+	for (i = 0; i < PK11_CIPHER_MAX; ++i)
4616+		{
4617+		pk11_get_symmetric_cipher(pflist, current_slot,
4618+		    ciphers[i].mech_type, current_slot_n_cipher,
4619+		    local_cipher_nids, ciphers[i].id);
4620+		}
4621+	}
4622+
4623+/* Find what digest algorithms this slot supports. */
4624+static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
4625+    CK_SLOT_ID current_slot, int *current_slot_n_digest, int *local_digest_nids)
4626+	{
4627+	int i;
4628+
4629+	for (i = 0; i < PK11_DIGEST_MAX; ++i)
4630+		{
4631+		pk11_get_digest(pflist, current_slot, digests[i].mech_type,
4632+		    current_slot_n_digest, local_digest_nids, digests[i].id);
4633+		}
4634+	}
4635+
4636+#ifdef	SOLARIS_HW_SLOT_SELECTION
4637+/*
4638+ * It would be great if we could use pkcs11_kernel directly since this library
4639+ * offers hardware slots only. That's the easiest way to achieve the situation
4640+ * where we use the hardware accelerators when present and OpenSSL native code
4641+ * otherwise. That presumes the fact that OpenSSL native code is faster than the
4642+ * code in the soft token. It's a logical assumption - Crypto Framework has some
4643+ * inherent overhead so going there for the software implementation of a
4644+ * mechanism should be logically slower in contrast to the OpenSSL native code,
4645+ * presuming that both implementations are of similar speed. For example, the
4646+ * soft token for AES is roughly three times slower than OpenSSL for 64 byte
4647+ * blocks and still 20% slower for 8KB blocks. So, if we want to ship products
4648+ * that use the PKCS#11 engine by default, we must somehow avoid that regression
4649+ * on machines without hardware acceleration. That's why switching to the
4650+ * pkcs11_kernel library seems like a very good idea.
4651+ *
4652+ * The problem is that OpenSSL built with SunStudio is roughly 2x slower for
4653+ * asymmetric operations (RSA/DSA/DH) than the soft token built with the same
4654+ * compiler. That means that if we switched to pkcs11_kernel from the libpkcs11
4655+ * library, we would have had a performance regression on machines without
4656+ * hardware acceleration for asymmetric operations for all applications that use
4657+ * the PKCS#11 engine. There is one such application - Apache web server since
4658+ * it's shipped configured to use the PKCS#11 engine by default. Having said
4659+ * that, we can't switch to the pkcs11_kernel library now and have to come with
4660+ * a solution that, on non-accelerated machines, uses the OpenSSL native code
4661+ * for all symmetric ciphers and digests while it uses the soft token for
4662+ * asymmetric operations.
4663+ *
4664+ * This is the idea: dlopen() pkcs11_kernel directly and find out what
4665+ * mechanisms are there. We don't care about duplications (more slots can
4666+ * support the same mechanism), we just want to know what mechanisms can be
4667+ * possibly supported in hardware on that particular machine. As said before,
4668+ * pkcs11_kernel will show you hardware providers only.
4669+ *
4670+ * Then, we rely on the fact that since we use libpkcs11 library we will find
4671+ * the metaslot. When we go through the metaslot's mechanisms for symmetric
4672+ * ciphers and digests, we check that any found mechanism is in the table
4673+ * created using the pkcs11_kernel library. So, as a result we have two arrays
4674+ * of mechanisms that were advertised as supported in hardware which was the
4675+ * goal of that whole excercise. Thus, we can use libpkcs11 but avoid soft token
4676+ * code for symmetric ciphers and digests. See pk11_choose_slots() for more
4677+ * information.
4678+ *
4679+ * This is Solaris specific code, if SOLARIS_HW_SLOT_SELECTION is not defined
4680+ * the code won't be used.
4681+ */
4682+#if defined(__sparcv9) || defined(__x86_64) || defined(__amd64)
4683+static const char pkcs11_kernel[] = "/usr/lib/security/64/pkcs11_kernel.so.1";
4684+#else
4685+static const char pkcs11_kernel[] = "/usr/lib/security/pkcs11_kernel.so.1";
4686+#endif
4687+
4688+/*
4689+ * Check hardware capabilities of the machines. The output are two lists,
4690+ * hw_cnids and hw_dnids, that contain hardware mechanisms found in all hardware
4691+ * providers together. They are not sorted and may contain duplicate mechanisms.
4692+ */
4693+static int check_hw_mechanisms(void)
4694+	{
4695+	int i;
4696+	CK_RV rv;
4697+	void *handle;
4698+	CK_C_GetFunctionList p;
4699+	CK_TOKEN_INFO token_info;
4700+	CK_ULONG ulSlotCount = 0;
4701+	int n_cipher = 0, n_digest = 0;
4702+	CK_FUNCTION_LIST_PTR pflist = NULL;
4703+	CK_SLOT_ID_PTR pSlotList = NULL_PTR;
4704+	int *tmp_hw_cnids = NULL, *tmp_hw_dnids = NULL;
4705+	int hw_ctable_size, hw_dtable_size;
4706+
4707+#ifdef	DEBUG_SLOT_SELECTION
4708+	fprintf(stderr, "%s: SOLARIS_HW_SLOT_SELECTION code running\n",
4709+	    PK11_DBG);
4710+#endif
4711+	if ((handle = dlopen(pkcs11_kernel, RTLD_LAZY)) == NULL)
4712+		{
4713+		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
4714+		goto err;
4715+		}
4716+
4717+	if ((p = (CK_C_GetFunctionList)dlsym(handle,
4718+	    PK11_GET_FUNCTION_LIST)) == NULL)
4719+		{
4720+		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
4721+		goto err;
4722+		}
4723+
4724+	/* get the full function list from the loaded library */
4725+	if (p(&pflist) != CKR_OK)
4726+		{
4727+		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
4728+		goto err;
4729+		}
4730+
4731+	rv = pflist->C_Initialize((CK_VOID_PTR)&pk11_init_args);
4732+	if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
4733+		{
4734+		PK11err_add_data(PK11_F_CHECK_HW_MECHANISMS,
4735+		    PK11_R_INITIALIZE, rv);
4736+		goto err;
4737+		}
4738+
4739+	if (pflist->C_GetSlotList(0, NULL_PTR, &ulSlotCount) != CKR_OK)
4740+		{
4741+		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_GETSLOTLIST);
4742+		goto err;
4743+		}
4744+
4745+	/* no slots, set the hw mechanism tables as empty */
4746+	if (ulSlotCount == 0)
4747+		{
4748+#ifdef	DEBUG_SLOT_SELECTION
4749+	fprintf(stderr, "%s: no hardware mechanisms found\n", PK11_DBG);
4750+#endif
4751+		hw_cnids = OPENSSL_malloc(sizeof (int));
4752+		hw_dnids = OPENSSL_malloc(sizeof (int));
4753+		if (hw_cnids == NULL || hw_dnids == NULL)
4754+			{
4755+			PK11err(PK11_F_CHECK_HW_MECHANISMS,
4756+			    PK11_R_MALLOC_FAILURE);
4757+			return (0);
4758+			}
4759+		/* this means empty tables */
4760+		hw_cnids[0] = NID_undef;
4761+		hw_dnids[0] = NID_undef;
4762+		return (1);
4763+		}
4764+
4765+	pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
4766+	if (pSlotList == NULL)
4767+		{
4768+		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_MALLOC_FAILURE);
4769+		goto err;
4770+		}
4771+
4772+	/* Get the slot list for processing */
4773+	if (pflist->C_GetSlotList(0, pSlotList, &ulSlotCount) != CKR_OK)
4774+		{
4775+		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_GETSLOTLIST);
4776+		goto err;
4777+		}
4778+
4779+	/*
4780+	 * We don't care about duplicit mechanisms in multiple slots and also
4781+	 * reserve one slot for the terminal NID_undef which we use to stop the
4782+	 * search.
4783+	 */
4784+	hw_ctable_size = ulSlotCount * PK11_CIPHER_MAX + 1;
4785+	hw_dtable_size = ulSlotCount * PK11_DIGEST_MAX + 1;
4786+	tmp_hw_cnids = OPENSSL_malloc(hw_ctable_size * sizeof (int));
4787+	tmp_hw_dnids = OPENSSL_malloc(hw_dtable_size * sizeof (int));
4788+	if (tmp_hw_cnids == NULL || tmp_hw_dnids == NULL)
4789+		{
4790+		PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_MALLOC_FAILURE);
4791+		goto err;
4792+		}
4793+
4794+	/*
4795+	 * Do not use memset since we should not rely on the fact that NID_undef
4796+	 * is zero now.
4797+	 */
4798+	for (i = 0; i < hw_ctable_size; ++i)
4799+		tmp_hw_cnids[i] = NID_undef;
4800+	for (i = 0; i < hw_dtable_size; ++i)
4801+		tmp_hw_dnids[i] = NID_undef;
4802+
4803+#ifdef	DEBUG_SLOT_SELECTION
4804+	fprintf(stderr, "%s: provider: %s\n", PK11_DBG, pkcs11_kernel);
4805+	fprintf(stderr, "%s: found %d hardware slots\n", PK11_DBG, ulSlotCount);
4806+	fprintf(stderr, "%s: now looking for mechs supported in hw\n",
4807+	    PK11_DBG);
4808+#endif	/* DEBUG_SLOT_SELECTION */
4809+
4810+	for (i = 0; i < ulSlotCount; i++)
4811+		{
4812+		if (pflist->C_GetTokenInfo(pSlotList[i], &token_info) != CKR_OK)
4813+			continue;
4814+
4815+#ifdef	DEBUG_SLOT_SELECTION
4816+	fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
4817+#endif	/* DEBUG_SLOT_SELECTION */
4818+
4819+		/*
4820+		 * We are filling the hw mech tables here. Global tables are
4821+		 * still NULL so all mechanisms are put into tmp tables.
4822+		 */
4823+		pk11_find_symmetric_ciphers(pflist, pSlotList[i],
4824+		    &n_cipher, tmp_hw_cnids);
4825+		pk11_find_digests(pflist, pSlotList[i],
4826+		    &n_digest, tmp_hw_dnids);
4827+		}
4828+
4829+	/*
4830+	 * Since we are part of a library (libcrypto.so), calling this function
4831+	 * may have side-effects. Also, C_Finalize() is triggered by
4832+	 * dlclose(3C).
4833+	 */
4834+#if 0
4835+	pflist->C_Finalize(NULL);
4836+#endif
4837+	OPENSSL_free(pSlotList);
4838+	(void) dlclose(handle);
4839+	hw_cnids = tmp_hw_cnids;
4840+	hw_dnids = tmp_hw_dnids;
4841+
4842+#ifdef	DEBUG_SLOT_SELECTION
4843+	fprintf(stderr, "%s: hw mechs check complete\n", PK11_DBG);
4844+#endif	/* DEBUG_SLOT_SELECTION */
4845+	return (1);
4846+
4847+err:
4848+	if (pSlotList != NULL)
4849+		OPENSSL_free(pSlotList);
4850+	if (tmp_hw_cnids != NULL)
4851+		OPENSSL_free(tmp_hw_cnids);
4852+	if (tmp_hw_dnids != NULL)
4853+		OPENSSL_free(tmp_hw_dnids);
4854+
4855+	return (0);
4856+	}
4857+
4858+/*
4859+ * Check presence of a NID in the table of NIDs. The table may be NULL (i.e.,
4860+ * non-existent).
4861+ */
4862+static int nid_in_table(int nid, int *nid_table)
4863+	{
4864+	int i = 0;
4865+
4866+	/*
4867+	 * a special case. NULL means that we are initializing a new
4868+	 * table.
4869+	 */
4870+	if (nid_table == NULL)
4871+		return (1);
4872+
4873+	/*
4874+	 * the table is never full, there is always at least one
4875+	 * NID_undef.
4876+	 */
4877+	while (nid_table[i] != NID_undef)
4878+		{
4879+		if (nid_table[i++] == nid)
4880+			{
4881+#ifdef	DEBUG_SLOT_SELECTION
4882+	fprintf(stderr, " (NID %d in hw table, idx %d)", nid, i);
4883+#endif	/* DEBUG_SLOT_SELECTION */
4884+			return (1);
4885+			}
4886+		}
4887+
4888+	return (0);
4889+	}
4890+#endif	/* SOLARIS_HW_SLOT_SELECTION */
4891+
4892+#endif	/* OPENSSL_NO_HW_PK11CA */
4893+#endif	/* OPENSSL_NO_HW_PK11 */
4894+#endif	/* OPENSSL_NO_HW */
4895Index: openssl/crypto/engine/hw_pk11_err.c
4896diff -u /dev/null openssl/crypto/engine/hw_pk11_err.c:1.4.10.1
4897--- /dev/null	Fri Jan  2 13:56:40 2015
4898+++ openssl/crypto/engine/hw_pk11_err.c	Tue Jun 14 21:52:40 2011
4899@@ -0,0 +1,288 @@
4900+/*
4901+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
4902+ * Use is subject to license terms.
4903+ */
4904+
4905+/* crypto/engine/hw_pk11_err.c */
4906+/*
4907+ * This product includes software developed by the OpenSSL Project for
4908+ * use in the OpenSSL Toolkit (http://www.openssl.org/).
4909+ *
4910+ * This project also referenced hw_pkcs11-0.9.7b.patch written by
4911+ * Afchine Madjlessi.
4912+ */
4913+/*
4914+ * ====================================================================
4915+ * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
4916+ *
4917+ * Redistribution and use in source and binary forms, with or without
4918+ * modification, are permitted provided that the following conditions
4919+ * are met:
4920+ *
4921+ * 1. Redistributions of source code must retain the above copyright
4922+ *    notice, this list of conditions and the following disclaimer.
4923+ *
4924+ * 2. Redistributions in binary form must reproduce the above copyright
4925+ *    notice, this list of conditions and the following disclaimer in
4926+ *    the documentation and/or other materials provided with the
4927+ *    distribution.
4928+ *
4929+ * 3. All advertising materials mentioning features or use of this
4930+ *    software must display the following acknowledgment:
4931+ *    "This product includes software developed by the OpenSSL Project
4932+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
4933+ *
4934+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
4935+ *    endorse or promote products derived from this software without
4936+ *    prior written permission. For written permission, please contact
4937+ *    licensing@OpenSSL.org.
4938+ *
4939+ * 5. Products derived from this software may not be called "OpenSSL"
4940+ *    nor may "OpenSSL" appear in their names without prior written
4941+ *    permission of the OpenSSL Project.
4942+ *
4943+ * 6. Redistributions of any form whatsoever must retain the following
4944+ *    acknowledgment:
4945+ *    "This product includes software developed by the OpenSSL Project
4946+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
4947+ *
4948+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
4949+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4950+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
4951+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
4952+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4953+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
4954+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
4955+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4956+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4957+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
4958+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
4959+ * OF THE POSSIBILITY OF SUCH DAMAGE.
4960+ * ====================================================================
4961+ *
4962+ * This product includes cryptographic software written by Eric Young
4963+ * (eay@cryptsoft.com).  This product includes software written by Tim
4964+ * Hudson (tjh@cryptsoft.com).
4965+ *
4966+ */
4967+
4968+#include <stdio.h>
4969+#include <openssl/err.h>
4970+#include "hw_pk11_err.h"
4971+
4972+/* BEGIN ERROR CODES */
4973+#ifndef OPENSSL_NO_ERR
4974+static ERR_STRING_DATA pk11_str_functs[]=
4975+{
4976+{ ERR_PACK(0, PK11_F_INIT, 0),			"PK11_INIT"},
4977+{ ERR_PACK(0, PK11_F_FINISH, 0),		"PK11_FINISH"},
4978+{ ERR_PACK(0, PK11_F_DESTROY, 0),		"PK11_DESTROY"},
4979+{ ERR_PACK(0, PK11_F_CTRL, 0),			"PK11_CTRL"},
4980+{ ERR_PACK(0, PK11_F_RSA_INIT, 0),		"PK11_RSA_INIT"},
4981+{ ERR_PACK(0, PK11_F_RSA_FINISH, 0),		"PK11_RSA_FINISH"},
4982+{ ERR_PACK(0, PK11_F_GET_PUB_RSA_KEY, 0),	"PK11_GET_PUB_RSA_KEY"},
4983+{ ERR_PACK(0, PK11_F_GET_PRIV_RSA_KEY, 0),	"PK11_GET_PRIV_RSA_KEY"},
4984+{ ERR_PACK(0, PK11_F_RSA_GEN_KEY, 0),		"PK11_RSA_GEN_KEY"},
4985+{ ERR_PACK(0, PK11_F_RSA_PUB_ENC, 0),		"PK11_RSA_PUB_ENC"},
4986+{ ERR_PACK(0, PK11_F_RSA_PRIV_ENC, 0),		"PK11_RSA_PRIV_ENC"},
4987+{ ERR_PACK(0, PK11_F_RSA_PUB_DEC, 0),		"PK11_RSA_PUB_DEC"},
4988+{ ERR_PACK(0, PK11_F_RSA_PRIV_DEC, 0),		"PK11_RSA_PRIV_DEC"},
4989+{ ERR_PACK(0, PK11_F_RSA_SIGN, 0),		"PK11_RSA_SIGN"},
4990+{ ERR_PACK(0, PK11_F_RSA_VERIFY, 0),		"PK11_RSA_VERIFY"},
4991+{ ERR_PACK(0, PK11_F_RAND_ADD, 0),		"PK11_RAND_ADD"},
4992+{ ERR_PACK(0, PK11_F_RAND_BYTES, 0),		"PK11_RAND_BYTES"},
4993+{ ERR_PACK(0, PK11_F_GET_SESSION, 0),		"PK11_GET_SESSION"},
4994+{ ERR_PACK(0, PK11_F_FREE_SESSION, 0),		"PK11_FREE_SESSION"},
4995+{ ERR_PACK(0, PK11_F_LOAD_PUBKEY, 0),		"PK11_LOAD_PUBKEY"},
4996+{ ERR_PACK(0, PK11_F_LOAD_PRIVKEY, 0),		"PK11_LOAD_PRIV_KEY"},
4997+{ ERR_PACK(0, PK11_F_RSA_PUB_ENC_LOW, 0),	"PK11_RSA_PUB_ENC_LOW"},
4998+{ ERR_PACK(0, PK11_F_RSA_PRIV_ENC_LOW, 0),	"PK11_RSA_PRIV_ENC_LOW"},
4999+{ ERR_PACK(0, PK11_F_RSA_PUB_DEC_LOW, 0),	"PK11_RSA_PUB_DEC_LOW"},
5000+{ ERR_PACK(0, PK11_F_RSA_PRIV_DEC_LOW, 0),	"PK11_RSA_PRIV_DEC_LOW"},
5001+{ ERR_PACK(0, PK11_F_DSA_SIGN, 0),		"PK11_DSA_SIGN"},
5002+{ ERR_PACK(0, PK11_F_DSA_VERIFY, 0),		"PK11_DSA_VERIFY"},
5003+{ ERR_PACK(0, PK11_F_DSA_INIT, 0),		"PK11_DSA_INIT"},
5004+{ ERR_PACK(0, PK11_F_DSA_FINISH, 0),		"PK11_DSA_FINISH"},
5005+{ ERR_PACK(0, PK11_F_GET_PUB_DSA_KEY, 0),	"PK11_GET_PUB_DSA_KEY"},
5006+{ ERR_PACK(0, PK11_F_GET_PRIV_DSA_KEY, 0),	"PK11_GET_PRIV_DSA_KEY"},
5007+{ ERR_PACK(0, PK11_F_DH_INIT, 0),		"PK11_DH_INIT"},
5008+{ ERR_PACK(0, PK11_F_DH_FINISH, 0),		"PK11_DH_FINISH"},
5009+{ ERR_PACK(0, PK11_F_MOD_EXP_DH, 0),		"PK11_MOD_EXP_DH"},
5010+{ ERR_PACK(0, PK11_F_GET_DH_KEY, 0),		"PK11_GET_DH_KEY"},
5011+{ ERR_PACK(0, PK11_F_FREE_ALL_SESSIONS, 0),	"PK11_FREE_ALL_SESSIONS"},
5012+{ ERR_PACK(0, PK11_F_SETUP_SESSION, 0),		"PK11_SETUP_SESSION"},
5013+{ ERR_PACK(0, PK11_F_DESTROY_OBJECT, 0),	"PK11_DESTROY_OBJECT"},
5014+{ ERR_PACK(0, PK11_F_CIPHER_INIT, 0),		"PK11_CIPHER_INIT"},
5015+{ ERR_PACK(0, PK11_F_CIPHER_DO_CIPHER, 0),	"PK11_CIPHER_DO_CIPHER"},
5016+{ ERR_PACK(0, PK11_F_GET_CIPHER_KEY, 0),	"PK11_GET_CIPHER_KEY"},
5017+{ ERR_PACK(0, PK11_F_DIGEST_INIT, 0),		"PK11_DIGEST_INIT"},
5018+{ ERR_PACK(0, PK11_F_DIGEST_UPDATE, 0),		"PK11_DIGEST_UPDATE"},
5019+{ ERR_PACK(0, PK11_F_DIGEST_FINAL, 0),		"PK11_DIGEST_FINAL"},
5020+{ ERR_PACK(0, PK11_F_CHOOSE_SLOT, 0),		"PK11_CHOOSE_SLOT"},
5021+{ ERR_PACK(0, PK11_F_CIPHER_FINAL, 0),		"PK11_CIPHER_FINAL"},
5022+{ ERR_PACK(0, PK11_F_LIBRARY_INIT, 0),		"PK11_LIBRARY_INIT"},
5023+{ ERR_PACK(0, PK11_F_LOAD, 0),			"ENGINE_LOAD_PK11"},
5024+{ ERR_PACK(0, PK11_F_DH_GEN_KEY, 0),		"PK11_DH_GEN_KEY"},
5025+{ ERR_PACK(0, PK11_F_DH_COMP_KEY, 0),		"PK11_DH_COMP_KEY"},
5026+{ ERR_PACK(0, PK11_F_DIGEST_COPY, 0),		"PK11_DIGEST_COPY"},
5027+{ ERR_PACK(0, PK11_F_CIPHER_CLEANUP, 0),	"PK11_CIPHER_CLEANUP"},
5028+{ ERR_PACK(0, PK11_F_ACTIVE_ADD, 0),		"PK11_ACTIVE_ADD"},
5029+{ ERR_PACK(0, PK11_F_ACTIVE_DELETE, 0),		"PK11_ACTIVE_DELETE"},
5030+{ ERR_PACK(0, PK11_F_CHECK_HW_MECHANISMS, 0),	"PK11_CHECK_HW_MECHANISMS"},
5031+{ ERR_PACK(0, PK11_F_INIT_SYMMETRIC, 0),	"PK11_INIT_SYMMETRIC"},
5032+{ ERR_PACK(0, PK11_F_ADD_AES_CTR_NIDS, 0),	"PK11_ADD_AES_CTR_NIDS"},
5033+{ ERR_PACK(0, PK11_F_INIT_ALL_LOCKS, 0),	"PK11_INIT_ALL_LOCKS"},
5034+{ ERR_PACK(0, PK11_F_RETURN_SESSION, 0),	"PK11_RETURN_SESSION"},
5035+{ ERR_PACK(0, PK11_F_GET_PIN, 0),		"PK11_GET_PIN"},
5036+{ ERR_PACK(0, PK11_F_FIND_ONE_OBJECT, 0),	"PK11_FIND_ONE_OBJECT"},
5037+{ ERR_PACK(0, PK11_F_CHECK_TOKEN_ATTRS, 0),	"PK11_CHECK_TOKEN_ATTRS"},
5038+{ ERR_PACK(0, PK11_F_CACHE_PIN, 0),		"PK11_CACHE_PIN"},
5039+{ ERR_PACK(0, PK11_F_MLOCK_PIN_IN_MEMORY, 0),	"PK11_MLOCK_PIN_IN_MEMORY"},
5040+{ ERR_PACK(0, PK11_F_TOKEN_LOGIN, 0),		"PK11_TOKEN_LOGIN"},
5041+{ ERR_PACK(0, PK11_F_TOKEN_RELOGIN, 0),		"PK11_TOKEN_RELOGIN"},
5042+{ ERR_PACK(0, PK11_F_RUN_ASKPASS, 0),		"PK11_F_RUN_ASKPASS"},
5043+{ 0, NULL}
5044+};
5045+
5046+static ERR_STRING_DATA pk11_str_reasons[]=
5047+{
5048+{ PK11_R_ALREADY_LOADED,		"PKCS#11 DSO already loaded"},
5049+{ PK11_R_DSO_FAILURE,			"unable to load PKCS#11 DSO"},
5050+{ PK11_R_NOT_LOADED,			"PKCS#11 DSO not loaded"},
5051+{ PK11_R_PASSED_NULL_PARAMETER,		"null parameter passed"},
5052+{ PK11_R_COMMAND_NOT_IMPLEMENTED,	"command not implemented"},
5053+{ PK11_R_INITIALIZE,			"C_Initialize failed"},
5054+{ PK11_R_FINALIZE,			"C_Finalize failed"},
5055+{ PK11_R_GETINFO,			"C_GetInfo faile"},
5056+{ PK11_R_GETSLOTLIST,			"C_GetSlotList failed"},
5057+{ PK11_R_NO_MODULUS_OR_NO_EXPONENT,	"no modulus or no exponent"},
5058+{ PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID,	"attr sensitive or invalid"},
5059+{ PK11_R_GETATTRIBUTVALUE,		"C_GetAttributeValue failed"},
5060+{ PK11_R_NO_MODULUS,			"no modulus"},
5061+{ PK11_R_NO_EXPONENT,			"no exponent"},
5062+{ PK11_R_FINDOBJECTSINIT,		"C_FindObjectsInit failed"},
5063+{ PK11_R_FINDOBJECTS,			"C_FindObjects failed"},
5064+{ PK11_R_FINDOBJECTSFINAL,		"C_FindObjectsFinal failed"},
5065+{ PK11_R_CREATEOBJECT,			"C_CreateObject failed"},
5066+{ PK11_R_DESTROYOBJECT,			"C_DestroyObject failed"},
5067+{ PK11_R_OPENSESSION,			"C_OpenSession failed"},
5068+{ PK11_R_CLOSESESSION,			"C_CloseSession failed"},
5069+{ PK11_R_ENCRYPTINIT,			"C_EncryptInit failed"},
5070+{ PK11_R_ENCRYPT,			"C_Encrypt failed"},
5071+{ PK11_R_SIGNINIT,			"C_SignInit failed"},
5072+{ PK11_R_SIGN,				"C_Sign failed"},
5073+{ PK11_R_DECRYPTINIT,			"C_DecryptInit failed"},
5074+{ PK11_R_DECRYPT,			"C_Decrypt failed"},
5075+{ PK11_R_VERIFYINIT,			"C_VerifyRecover failed"},
5076+{ PK11_R_VERIFY,			"C_Verify failed"},
5077+{ PK11_R_VERIFYRECOVERINIT,		"C_VerifyRecoverInit failed"},
5078+{ PK11_R_VERIFYRECOVER,			"C_VerifyRecover failed"},
5079+{ PK11_R_GEN_KEY,			"C_GenerateKeyPair failed"},
5080+{ PK11_R_SEEDRANDOM,			"C_SeedRandom failed"},
5081+{ PK11_R_GENERATERANDOM,		"C_GenerateRandom failed"},
5082+{ PK11_R_INVALID_MESSAGE_LENGTH,	"invalid message length"},
5083+{ PK11_R_UNKNOWN_ALGORITHM_TYPE,	"unknown algorithm type"},
5084+{ PK11_R_UNKNOWN_ASN1_OBJECT_ID,	"unknown asn1 onject id"},
5085+{ PK11_R_UNKNOWN_PADDING_TYPE,		"unknown padding type"},
5086+{ PK11_R_PADDING_CHECK_FAILED,		"padding check failed"},
5087+{ PK11_R_DIGEST_TOO_BIG,		"digest too big"},
5088+{ PK11_R_MALLOC_FAILURE,		"malloc failure"},
5089+{ PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED,	"ctl command not implemented"},
5090+{ PK11_R_DATA_GREATER_THAN_MOD_LEN,	"data is bigger than mod"},
5091+{ PK11_R_DATA_TOO_LARGE_FOR_MODULUS,	"data is too larger for mod"},
5092+{ PK11_R_MISSING_KEY_COMPONENT,		"a dsa component is missing"},
5093+{ PK11_R_INVALID_SIGNATURE_LENGTH,	"invalid signature length"},
5094+{ PK11_R_INVALID_DSA_SIGNATURE_R,	"missing r in dsa verify"},
5095+{ PK11_R_INVALID_DSA_SIGNATURE_S,	"missing s in dsa verify"},
5096+{ PK11_R_INCONSISTENT_KEY,		"inconsistent key type"},
5097+{ PK11_R_ENCRYPTUPDATE,			"C_EncryptUpdate failed"},
5098+{ PK11_R_DECRYPTUPDATE,			"C_DecryptUpdate failed"},
5099+{ PK11_R_DIGESTINIT,			"C_DigestInit failed"},
5100+{ PK11_R_DIGESTUPDATE,			"C_DigestUpdate failed"},
5101+{ PK11_R_DIGESTFINAL,			"C_DigestFinal failed"},
5102+{ PK11_R_ENCRYPTFINAL,			"C_EncryptFinal failed"},
5103+{ PK11_R_DECRYPTFINAL,			"C_DecryptFinal failed"},
5104+{ PK11_R_NO_PRNG_SUPPORT,		"Slot does not support PRNG"},
5105+{ PK11_R_GETTOKENINFO,			"C_GetTokenInfo failed"},
5106+{ PK11_R_DERIVEKEY,			"C_DeriveKey failed"},
5107+{ PK11_R_GET_OPERATION_STATE,		"C_GetOperationState failed"},
5108+{ PK11_R_SET_OPERATION_STATE,		"C_SetOperationState failed"},
5109+{ PK11_R_INVALID_HANDLE,		"invalid PKCS#11 object handle"},
5110+{ PK11_R_KEY_OR_IV_LEN_PROBLEM,		"IV or key length incorrect"},
5111+{ PK11_R_INVALID_OPERATION_TYPE,	"invalid operation type"},
5112+{ PK11_R_ADD_NID_FAILED,		"failed to add NID" },
5113+{ PK11_R_ATFORK_FAILED,			"atfork() failed" },
5114+{ PK11_R_TOKEN_LOGIN_FAILED,		"C_Login() failed on token" },
5115+{ PK11_R_MORE_THAN_ONE_OBJECT_FOUND,	"more than one object found" },
5116+{ PK11_R_INVALID_PKCS11_URI,		"pkcs11 URI provided is invalid" },
5117+{ PK11_R_COULD_NOT_READ_PIN,		"could not read PIN from terminal" },
5118+{ PK11_R_PIN_NOT_READ_FROM_COMMAND,	"PIN not read from external command" },
5119+{ PK11_R_COULD_NOT_OPEN_COMMAND,	"could not popen() dialog command" },
5120+{ PK11_R_PIPE_FAILED,			"pipe() failed" },
5121+{ PK11_R_BAD_PASSPHRASE_SPEC,		"bad passphrasedialog specification" },
5122+{ PK11_R_TOKEN_NOT_INITIALIZED,		"token not initialized" },
5123+{ PK11_R_TOKEN_PIN_NOT_SET,		"token PIN required but not set" },
5124+{ PK11_R_TOKEN_PIN_NOT_PROVIDED,	"token PIN required but not provided" },
5125+{ PK11_R_MISSING_OBJECT_LABEL,		"missing mandatory 'object' keyword" },
5126+{ PK11_R_TOKEN_ATTRS_DO_NOT_MATCH,	"token attrs provided do not match" },
5127+{ PK11_R_PRIV_KEY_NOT_FOUND,		"private key not found in keystore" },
5128+{ PK11_R_NO_OBJECT_FOUND,		"specified object not found" },
5129+{ PK11_R_PIN_CACHING_POLICY_INVALID,	"PIN set but caching policy invalid" },
5130+{ PK11_R_SYSCONF_FAILED,		"sysconf() failed" },
5131+{ PK11_R_MMAP_FAILED,			"mmap() failed" },
5132+{ PK11_R_PRIV_PROC_LOCK_MEMORY_MISSING,	"PROC_LOCK_MEMORY privilege missing" },
5133+{ PK11_R_MLOCK_FAILED,			"mlock() failed" },
5134+{ PK11_R_FORK_FAILED,			"fork() failed" },
5135+{ 0,	NULL}
5136+};
5137+#endif	/* OPENSSL_NO_ERR */
5138+
5139+static int pk11_lib_error_code = 0;
5140+static int pk11_error_init = 1;
5141+
5142+static void
5143+ERR_load_pk11_strings(void)
5144+	{
5145+	if (pk11_lib_error_code == 0)
5146+		pk11_lib_error_code = ERR_get_next_error_library();
5147+
5148+	if (pk11_error_init)
5149+		{
5150+		pk11_error_init = 0;
5151+#ifndef OPENSSL_NO_ERR
5152+		ERR_load_strings(pk11_lib_error_code, pk11_str_functs);
5153+		ERR_load_strings(pk11_lib_error_code, pk11_str_reasons);
5154+#endif
5155+		}
5156+}
5157+
5158+static void
5159+ERR_unload_pk11_strings(void)
5160+	{
5161+	if (pk11_error_init == 0)
5162+		{
5163+#ifndef OPENSSL_NO_ERR
5164+		ERR_unload_strings(pk11_lib_error_code, pk11_str_functs);
5165+		ERR_unload_strings(pk11_lib_error_code, pk11_str_reasons);
5166+#endif
5167+		pk11_error_init = 1;
5168+		}
5169+}
5170+
5171+void
5172+ERR_pk11_error(int function, int reason, char *file, int line)
5173+{
5174+	if (pk11_lib_error_code == 0)
5175+		pk11_lib_error_code = ERR_get_next_error_library();
5176+	ERR_PUT_error(pk11_lib_error_code, function, reason, file, line);
5177+}
5178+
5179+void
5180+PK11err_add_data(int function, int reason, CK_RV rv)
5181+{
5182+	char tmp_buf[20];
5183+
5184+	PK11err(function, reason);
5185+	(void) BIO_snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
5186+	ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
5187+}
5188Index: openssl/crypto/engine/hw_pk11_err.h
5189diff -u /dev/null openssl/crypto/engine/hw_pk11_err.h:1.9.10.2
5190--- /dev/null	Fri Jan  2 13:56:40 2015
5191+++ openssl/crypto/engine/hw_pk11_err.h	Fri Oct  4 14:45:25 2013
5192@@ -0,0 +1,440 @@
5193+/*
5194+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
5195+ * Use is subject to license terms.
5196+ */
5197+
5198+/*
5199+ * This product includes software developed by the OpenSSL Project for
5200+ * use in the OpenSSL Toolkit (http://www.openssl.org/).
5201+ *
5202+ * This project also referenced hw_pkcs11-0.9.7b.patch written by
5203+ * Afchine Madjlessi.
5204+ */
5205+/*
5206+ * ====================================================================
5207+ * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
5208+ *
5209+ * Redistribution and use in source and binary forms, with or without
5210+ * modification, are permitted provided that the following conditions
5211+ * are met:
5212+ *
5213+ * 1. Redistributions of source code must retain the above copyright
5214+ *    notice, this list of conditions and the following disclaimer.
5215+ *
5216+ * 2. Redistributions in binary form must reproduce the above copyright
5217+ *    notice, this list of conditions and the following disclaimer in
5218+ *    the documentation and/or other materials provided with the
5219+ *    distribution.
5220+ *
5221+ * 3. All advertising materials mentioning features or use of this
5222+ *    software must display the following acknowledgment:
5223+ *    "This product includes software developed by the OpenSSL Project
5224+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
5225+ *
5226+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
5227+ *    endorse or promote products derived from this software without
5228+ *    prior written permission. For written permission, please contact
5229+ *    licensing@OpenSSL.org.
5230+ *
5231+ * 5. Products derived from this software may not be called "OpenSSL"
5232+ *    nor may "OpenSSL" appear in their names without prior written
5233+ *    permission of the OpenSSL Project.
5234+ *
5235+ * 6. Redistributions of any form whatsoever must retain the following
5236+ *    acknowledgment:
5237+ *    "This product includes software developed by the OpenSSL Project
5238+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
5239+ *
5240+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
5241+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5242+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
5243+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
5244+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
5245+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
5246+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5247+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5248+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
5249+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
5250+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
5251+ * OF THE POSSIBILITY OF SUCH DAMAGE.
5252+ * ====================================================================
5253+ *
5254+ * This product includes cryptographic software written by Eric Young
5255+ * (eay@cryptsoft.com).  This product includes software written by Tim
5256+ * Hudson (tjh@cryptsoft.com).
5257+ *
5258+ */
5259+
5260+#ifndef	HW_PK11_ERR_H
5261+#define	HW_PK11_ERR_H
5262+
5263+void ERR_pk11_error(int function, int reason, char *file, int line);
5264+void PK11err_add_data(int function, int reason, CK_RV rv);
5265+#define	PK11err(f, r)	ERR_pk11_error((f), (r), __FILE__, __LINE__)
5266+
5267+/* Error codes for the PK11 functions. */
5268+
5269+/* Function codes. */
5270+
5271+#define	PK11_F_INIT				100
5272+#define	PK11_F_FINISH				101
5273+#define	PK11_F_DESTROY				102
5274+#define	PK11_F_CTRL				103
5275+#define	PK11_F_RSA_INIT				104
5276+#define	PK11_F_RSA_FINISH			105
5277+#define	PK11_F_GET_PUB_RSA_KEY			106
5278+#define	PK11_F_GET_PRIV_RSA_KEY			107
5279+#define	PK11_F_RSA_GEN_KEY			108
5280+#define	PK11_F_RSA_PUB_ENC			109
5281+#define	PK11_F_RSA_PRIV_ENC			110
5282+#define	PK11_F_RSA_PUB_DEC			111
5283+#define	PK11_F_RSA_PRIV_DEC			112
5284+#define	PK11_F_RSA_SIGN				113
5285+#define	PK11_F_RSA_VERIFY			114
5286+#define	PK11_F_RAND_ADD				115
5287+#define	PK11_F_RAND_BYTES			116
5288+#define	PK11_F_GET_SESSION			117
5289+#define	PK11_F_FREE_SESSION			118
5290+#define	PK11_F_LOAD_PUBKEY			119
5291+#define	PK11_F_LOAD_PRIVKEY			120
5292+#define	PK11_F_RSA_PUB_ENC_LOW			121
5293+#define	PK11_F_RSA_PRIV_ENC_LOW			122
5294+#define	PK11_F_RSA_PUB_DEC_LOW			123
5295+#define	PK11_F_RSA_PRIV_DEC_LOW			124
5296+#define	PK11_F_DSA_SIGN				125
5297+#define	PK11_F_DSA_VERIFY			126
5298+#define	PK11_F_DSA_INIT				127
5299+#define	PK11_F_DSA_FINISH			128
5300+#define	PK11_F_GET_PUB_DSA_KEY			129
5301+#define	PK11_F_GET_PRIV_DSA_KEY			130
5302+#define	PK11_F_DH_INIT				131
5303+#define	PK11_F_DH_FINISH			132
5304+#define	PK11_F_MOD_EXP_DH			133
5305+#define	PK11_F_GET_DH_KEY			134
5306+#define	PK11_F_FREE_ALL_SESSIONS		135
5307+#define	PK11_F_SETUP_SESSION			136
5308+#define	PK11_F_DESTROY_OBJECT			137
5309+#define	PK11_F_CIPHER_INIT			138
5310+#define	PK11_F_CIPHER_DO_CIPHER			139
5311+#define	PK11_F_GET_CIPHER_KEY			140
5312+#define	PK11_F_DIGEST_INIT			141
5313+#define	PK11_F_DIGEST_UPDATE			142
5314+#define	PK11_F_DIGEST_FINAL			143
5315+#define	PK11_F_CHOOSE_SLOT			144
5316+#define	PK11_F_CIPHER_FINAL			145
5317+#define	PK11_F_LIBRARY_INIT			146
5318+#define	PK11_F_LOAD				147
5319+#define	PK11_F_DH_GEN_KEY			148
5320+#define	PK11_F_DH_COMP_KEY			149
5321+#define	PK11_F_DIGEST_COPY			150
5322+#define	PK11_F_CIPHER_CLEANUP			151
5323+#define	PK11_F_ACTIVE_ADD			152
5324+#define	PK11_F_ACTIVE_DELETE			153
5325+#define	PK11_F_CHECK_HW_MECHANISMS		154
5326+#define	PK11_F_INIT_SYMMETRIC			155
5327+#define	PK11_F_ADD_AES_CTR_NIDS			156
5328+#define	PK11_F_INIT_ALL_LOCKS			157
5329+#define	PK11_F_RETURN_SESSION			158
5330+#define	PK11_F_GET_PIN				159
5331+#define	PK11_F_FIND_ONE_OBJECT			160
5332+#define	PK11_F_CHECK_TOKEN_ATTRS		161
5333+#define	PK11_F_CACHE_PIN			162
5334+#define	PK11_F_MLOCK_PIN_IN_MEMORY		163
5335+#define	PK11_F_TOKEN_LOGIN			164
5336+#define	PK11_F_TOKEN_RELOGIN			165
5337+#define	PK11_F_RUN_ASKPASS			166
5338+
5339+/* Reason codes. */
5340+#define	PK11_R_ALREADY_LOADED 			100
5341+#define	PK11_R_DSO_FAILURE 			101
5342+#define	PK11_R_NOT_LOADED 			102
5343+#define	PK11_R_PASSED_NULL_PARAMETER 		103
5344+#define	PK11_R_COMMAND_NOT_IMPLEMENTED 		104
5345+#define	PK11_R_INITIALIZE 			105
5346+#define	PK11_R_FINALIZE 			106
5347+#define	PK11_R_GETINFO 				107
5348+#define	PK11_R_GETSLOTLIST 			108
5349+#define	PK11_R_NO_MODULUS_OR_NO_EXPONENT 	109
5350+#define	PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID 	110
5351+#define	PK11_R_GETATTRIBUTVALUE 		111
5352+#define	PK11_R_NO_MODULUS 			112
5353+#define	PK11_R_NO_EXPONENT 			113
5354+#define	PK11_R_FINDOBJECTSINIT 			114
5355+#define	PK11_R_FINDOBJECTS 			115
5356+#define	PK11_R_FINDOBJECTSFINAL 		116
5357+#define	PK11_R_CREATEOBJECT 			118
5358+#define	PK11_R_DESTROYOBJECT 			119
5359+#define	PK11_R_OPENSESSION 			120
5360+#define	PK11_R_CLOSESESSION 			121
5361+#define	PK11_R_ENCRYPTINIT 			122
5362+#define	PK11_R_ENCRYPT 				123
5363+#define	PK11_R_SIGNINIT 			124
5364+#define	PK11_R_SIGN 				125
5365+#define	PK11_R_DECRYPTINIT 			126
5366+#define	PK11_R_DECRYPT 				127
5367+#define	PK11_R_VERIFYINIT 			128
5368+#define	PK11_R_VERIFY 				129
5369+#define	PK11_R_VERIFYRECOVERINIT 		130
5370+#define	PK11_R_VERIFYRECOVER 			131
5371+#define	PK11_R_GEN_KEY 				132
5372+#define	PK11_R_SEEDRANDOM 			133
5373+#define	PK11_R_GENERATERANDOM 			134
5374+#define	PK11_R_INVALID_MESSAGE_LENGTH 		135
5375+#define	PK11_R_UNKNOWN_ALGORITHM_TYPE 		136
5376+#define	PK11_R_UNKNOWN_ASN1_OBJECT_ID 		137
5377+#define	PK11_R_UNKNOWN_PADDING_TYPE 		138
5378+#define	PK11_R_PADDING_CHECK_FAILED 		139
5379+#define	PK11_R_DIGEST_TOO_BIG 			140
5380+#define	PK11_R_MALLOC_FAILURE 			141
5381+#define	PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED 	142
5382+#define	PK11_R_DATA_GREATER_THAN_MOD_LEN 	143
5383+#define	PK11_R_DATA_TOO_LARGE_FOR_MODULUS 	144
5384+#define	PK11_R_MISSING_KEY_COMPONENT		145
5385+#define	PK11_R_INVALID_SIGNATURE_LENGTH		146
5386+#define	PK11_R_INVALID_DSA_SIGNATURE_R		147
5387+#define	PK11_R_INVALID_DSA_SIGNATURE_S		148
5388+#define	PK11_R_INCONSISTENT_KEY			149
5389+#define	PK11_R_ENCRYPTUPDATE			150
5390+#define	PK11_R_DECRYPTUPDATE			151
5391+#define	PK11_R_DIGESTINIT			152
5392+#define	PK11_R_DIGESTUPDATE			153
5393+#define	PK11_R_DIGESTFINAL			154
5394+#define	PK11_R_ENCRYPTFINAL			155
5395+#define	PK11_R_DECRYPTFINAL			156
5396+#define	PK11_R_NO_PRNG_SUPPORT			157
5397+#define	PK11_R_GETTOKENINFO			158
5398+#define	PK11_R_DERIVEKEY			159
5399+#define	PK11_R_GET_OPERATION_STATE		160
5400+#define	PK11_R_SET_OPERATION_STATE		161
5401+#define	PK11_R_INVALID_HANDLE			162
5402+#define	PK11_R_KEY_OR_IV_LEN_PROBLEM		163
5403+#define	PK11_R_INVALID_OPERATION_TYPE		164
5404+#define	PK11_R_ADD_NID_FAILED			165
5405+#define	PK11_R_ATFORK_FAILED			166
5406+
5407+#define	PK11_R_TOKEN_LOGIN_FAILED		167
5408+#define	PK11_R_MORE_THAN_ONE_OBJECT_FOUND	168
5409+#define	PK11_R_INVALID_PKCS11_URI		169
5410+#define	PK11_R_COULD_NOT_READ_PIN		170
5411+#define	PK11_R_COULD_NOT_OPEN_COMMAND		171
5412+#define	PK11_R_PIPE_FAILED			172
5413+#define	PK11_R_PIN_NOT_READ_FROM_COMMAND	173
5414+#define	PK11_R_BAD_PASSPHRASE_SPEC		174
5415+#define	PK11_R_TOKEN_NOT_INITIALIZED		175
5416+#define	PK11_R_TOKEN_PIN_NOT_SET		176
5417+#define	PK11_R_TOKEN_PIN_NOT_PROVIDED		177
5418+#define	PK11_R_MISSING_OBJECT_LABEL		178
5419+#define	PK11_R_TOKEN_ATTRS_DO_NOT_MATCH		179
5420+#define	PK11_R_PRIV_KEY_NOT_FOUND		180
5421+#define	PK11_R_NO_OBJECT_FOUND			181
5422+#define	PK11_R_PIN_CACHING_POLICY_INVALID	182
5423+#define	PK11_R_SYSCONF_FAILED			183
5424+#define	PK11_R_MMAP_FAILED			183
5425+#define	PK11_R_PRIV_PROC_LOCK_MEMORY_MISSING	184
5426+#define	PK11_R_MLOCK_FAILED			185
5427+#define	PK11_R_FORK_FAILED			186
5428+
5429+/* max byte length of a symetric key we support */
5430+#define	PK11_KEY_LEN_MAX			32
5431+
5432+#ifdef NOPTHREADS
5433+/*
5434+ * CRYPTO_LOCK_PK11_ENGINE lock is primarily used for the protection of the
5435+ * free_session list and active_list but generally serves as a global
5436+ * per-process lock for the whole engine.
5437+ *
5438+ * We reuse CRYPTO_LOCK_EC lock (which is defined in OpenSSL for EC method) as
5439+ * the global engine lock. This is not optimal w.r.t. performance but
5440+ * it's safe.
5441+ */
5442+#define CRYPTO_LOCK_PK11_ENGINE	CRYPTO_LOCK_EC
5443+#endif
5444+
5445+/*
5446+ * This structure encapsulates all reusable information for a PKCS#11
5447+ * session. A list of these objects is created on behalf of the
5448+ * calling application using an on-demand method. Each operation
5449+ * type (see PK11_OPTYPE below) has its own per-process list.
5450+ * Each of the lists is basically a cache for faster PKCS#11 object
5451+ * access to avoid expensive C_Find{,Init,Final}Object() calls.
5452+ *
5453+ * When a new request comes in, an object will be taken from the list
5454+ * (if there is one) or a new one is created to handle the request
5455+ * (if the list is empty). See pk11_get_session() on how it is done.
5456+ */
5457+typedef struct PK11_st_SESSION
5458+	{
5459+	struct PK11_st_SESSION	*next;
5460+	CK_SESSION_HANDLE	session;	/* PK11 session handle */
5461+	pid_t			pid;		/* Current process ID */
5462+	CK_BBOOL		pub_persistent;	/* is pub key in keystore? */
5463+	CK_BBOOL		priv_persistent;/* is priv key in keystore? */
5464+	union
5465+		{
5466+#ifndef OPENSSL_NO_RSA
5467+		struct
5468+			{
5469+			CK_OBJECT_HANDLE	rsa_pub_key; /* pub handle */
5470+			CK_OBJECT_HANDLE	rsa_priv_key; /* priv handle */
5471+			RSA			*rsa_pub; /* pub key addr */
5472+			BIGNUM			*rsa_n_num; /* pub modulus */
5473+			BIGNUM			*rsa_e_num; /* pub exponent */
5474+			RSA			*rsa_priv; /* priv key addr */
5475+			BIGNUM			*rsa_pn_num; /* pub modulus */
5476+			BIGNUM			*rsa_pe_num; /* pub exponent */
5477+			BIGNUM			*rsa_d_num; /* priv exponent */
5478+			} u_RSA;
5479+#endif /* OPENSSL_NO_RSA */
5480+#ifndef OPENSSL_NO_DSA
5481+		struct
5482+			{
5483+			CK_OBJECT_HANDLE	dsa_pub_key; /* pub handle */
5484+			CK_OBJECT_HANDLE	dsa_priv_key; /* priv handle */
5485+			DSA			*dsa_pub; /* pub key addr */
5486+			BIGNUM			*dsa_pub_num; /* pub key */
5487+			DSA			*dsa_priv; /* priv key addr */
5488+			BIGNUM			*dsa_priv_num; /* priv key */
5489+			} u_DSA;
5490+#endif /* OPENSSL_NO_DSA */
5491+#ifndef OPENSSL_NO_DH
5492+		struct
5493+			{
5494+			CK_OBJECT_HANDLE	dh_key; /* key handle */
5495+			DH			*dh; /* dh key addr */
5496+			BIGNUM			*dh_priv_num; /* priv dh key */
5497+			} u_DH;
5498+#endif /* OPENSSL_NO_DH */
5499+		struct
5500+			{
5501+			CK_OBJECT_HANDLE	cipher_key; /* key handle */
5502+			unsigned char		key[PK11_KEY_LEN_MAX];
5503+			int			key_len; /* priv key len */
5504+			int			encrypt; /* 1/0 enc/decr */
5505+			} u_cipher;
5506+		} opdata_u;
5507+	} PK11_SESSION;
5508+
5509+#define	opdata_rsa_pub_key	opdata_u.u_RSA.rsa_pub_key
5510+#define	opdata_rsa_priv_key	opdata_u.u_RSA.rsa_priv_key
5511+#define	opdata_rsa_pub		opdata_u.u_RSA.rsa_pub
5512+#define	opdata_rsa_priv		opdata_u.u_RSA.rsa_priv
5513+#define	opdata_rsa_n_num	opdata_u.u_RSA.rsa_n_num
5514+#define	opdata_rsa_e_num	opdata_u.u_RSA.rsa_e_num
5515+#define	opdata_rsa_pn_num	opdata_u.u_RSA.rsa_pn_num
5516+#define	opdata_rsa_pe_num	opdata_u.u_RSA.rsa_pe_num
5517+#define	opdata_rsa_d_num	opdata_u.u_RSA.rsa_d_num
5518+#define	opdata_dsa_pub_key	opdata_u.u_DSA.dsa_pub_key
5519+#define	opdata_dsa_priv_key	opdata_u.u_DSA.dsa_priv_key
5520+#define	opdata_dsa_pub		opdata_u.u_DSA.dsa_pub
5521+#define	opdata_dsa_pub_num	opdata_u.u_DSA.dsa_pub_num
5522+#define	opdata_dsa_priv		opdata_u.u_DSA.dsa_priv
5523+#define	opdata_dsa_priv_num	opdata_u.u_DSA.dsa_priv_num
5524+#define	opdata_dh_key		opdata_u.u_DH.dh_key
5525+#define	opdata_dh		opdata_u.u_DH.dh
5526+#define	opdata_dh_priv_num	opdata_u.u_DH.dh_priv_num
5527+#define	opdata_cipher_key	opdata_u.u_cipher.cipher_key
5528+#define	opdata_key		opdata_u.u_cipher.key
5529+#define	opdata_key_len		opdata_u.u_cipher.key_len
5530+#define	opdata_encrypt		opdata_u.u_cipher.encrypt
5531+
5532+/*
5533+ * We have 3 different groups of operation types:
5534+ *   1) asymmetric operations
5535+ *   2) random operations
5536+ *   3) symmetric and digest operations
5537+ *
5538+ * This division into groups stems from the fact that it's common that hardware
5539+ * providers may support operations from one group only. For example, hardware
5540+ * providers on UltraSPARC T2, n2rng(7d), ncp(7d), and n2cp(7d), each support
5541+ * only a single group of operations.
5542+ *
5543+ * For every group a different slot can be chosen. That means that we must have
5544+ * at least 3 different lists of cached PKCS#11 sessions since sessions from
5545+ * different groups may be initialized in different slots.
5546+ *
5547+ * To provide locking granularity in multithreaded environment, the groups are
5548+ * further splitted into types with each type having a separate session cache.
5549+ */
5550+typedef enum PK11_OPTYPE_ENUM
5551+	{
5552+	OP_RAND,
5553+	OP_RSA,
5554+	OP_DSA,
5555+	OP_DH,
5556+	OP_CIPHER,
5557+	OP_DIGEST,
5558+	OP_MAX
5559+	} PK11_OPTYPE;
5560+
5561+/*
5562+ * This structure contains the heads of the lists forming the object caches
5563+ * and locks associated with the lists.
5564+ */
5565+typedef struct PK11_st_CACHE
5566+	{
5567+	PK11_SESSION *head;
5568+#ifndef NOPTHREADS
5569+	pthread_mutex_t *lock;
5570+#endif
5571+	} PK11_CACHE;
5572+
5573+/* structure for tracking handles of asymmetric key objects */
5574+typedef struct PK11_active_st
5575+	{
5576+	CK_OBJECT_HANDLE h;
5577+	unsigned int refcnt;
5578+	struct PK11_active_st *prev;
5579+	struct PK11_active_st *next;
5580+	} PK11_active;
5581+
5582+#ifndef NOPTHREADS
5583+extern pthread_mutex_t *find_lock[];
5584+#endif
5585+extern PK11_active *active_list[];
5586+/*
5587+ * These variables are specific for the RSA keys by reference code. See
5588+ * hw_pk11_pub.c for explanation.
5589+ */
5590+extern CK_FLAGS pubkey_token_flags;
5591+
5592+#ifndef NOPTHREADS
5593+#define	LOCK_OBJSTORE(alg_type)	\
5594+	OPENSSL_assert(pthread_mutex_lock(find_lock[alg_type]) == 0)
5595+#define	UNLOCK_OBJSTORE(alg_type)	\
5596+	OPENSSL_assert(pthread_mutex_unlock(find_lock[alg_type]) == 0)
5597+#else
5598+#define	LOCK_OBJSTORE(alg_type)	\
5599+	CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE)
5600+#define	UNLOCK_OBJSTORE(alg_type)	\
5601+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE)
5602+#endif
5603+
5604+extern PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
5605+extern void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
5606+extern int pk11_token_relogin(CK_SESSION_HANDLE session);
5607+
5608+#ifndef OPENSSL_NO_RSA
5609+extern int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
5610+extern int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
5611+extern int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
5612+extern EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *pubkey_file,
5613+	UI_METHOD *ui_method, void *callback_data);
5614+extern EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
5615+	UI_METHOD *ui_method, void *callback_data);
5616+extern RSA_METHOD *PK11_RSA(void);
5617+#endif /* OPENSSL_NO_RSA */
5618+#ifndef OPENSSL_NO_DSA
5619+extern int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
5620+extern int pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
5621+extern int pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
5622+extern DSA_METHOD *PK11_DSA(void);
5623+#endif /* OPENSSL_NO_DSA */
5624+#ifndef OPENSSL_NO_DH
5625+extern int pk11_destroy_dh_key_objects(PK11_SESSION *session);
5626+extern int pk11_destroy_dh_object(PK11_SESSION *sp, CK_BBOOL uselock);
5627+extern DH_METHOD *PK11_DH(void);
5628+#endif /* OPENSSL_NO_DH */
5629+
5630+extern CK_FUNCTION_LIST_PTR pFuncList;
5631+
5632+#endif /* HW_PK11_ERR_H */
5633Index: openssl/crypto/engine/hw_pk11_pub.c
5634diff -u /dev/null openssl/crypto/engine/hw_pk11_pub.c:1.32.4.7
5635--- /dev/null	Fri Jan  2 13:56:40 2015
5636+++ openssl/crypto/engine/hw_pk11_pub.c	Fri Oct  4 14:45:25 2013
5637@@ -0,0 +1,3556 @@
5638+/*
5639+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
5640+ * Use is subject to license terms.
5641+ */
5642+
5643+/* crypto/engine/hw_pk11_pub.c */
5644+/*
5645+ * This product includes software developed by the OpenSSL Project for
5646+ * use in the OpenSSL Toolkit (http://www.openssl.org/).
5647+ *
5648+ * This project also referenced hw_pkcs11-0.9.7b.patch written by
5649+ * Afchine Madjlessi.
5650+ */
5651+/*
5652+ * ====================================================================
5653+ * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
5654+ *
5655+ * Redistribution and use in source and binary forms, with or without
5656+ * modification, are permitted provided that the following conditions
5657+ * are met:
5658+ *
5659+ * 1. Redistributions of source code must retain the above copyright
5660+ *    notice, this list of conditions and the following disclaimer.
5661+ *
5662+ * 2. Redistributions in binary form must reproduce the above copyright
5663+ *    notice, this list of conditions and the following disclaimer in
5664+ *    the documentation and/or other materials provided with the
5665+ *    distribution.
5666+ *
5667+ * 3. All advertising materials mentioning features or use of this
5668+ *    software must display the following acknowledgment:
5669+ *    "This product includes software developed by the OpenSSL Project
5670+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
5671+ *
5672+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
5673+ *    endorse or promote products derived from this software without
5674+ *    prior written permission. For written permission, please contact
5675+ *    licensing@OpenSSL.org.
5676+ *
5677+ * 5. Products derived from this software may not be called "OpenSSL"
5678+ *    nor may "OpenSSL" appear in their names without prior written
5679+ *    permission of the OpenSSL Project.
5680+ *
5681+ * 6. Redistributions of any form whatsoever must retain the following
5682+ *    acknowledgment:
5683+ *    "This product includes software developed by the OpenSSL Project
5684+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
5685+ *
5686+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
5687+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5688+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
5689+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
5690+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
5691+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
5692+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5693+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5694+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
5695+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
5696+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
5697+ * OF THE POSSIBILITY OF SUCH DAMAGE.
5698+ * ====================================================================
5699+ *
5700+ * This product includes cryptographic software written by Eric Young
5701+ * (eay@cryptsoft.com).  This product includes software written by Tim
5702+ * Hudson (tjh@cryptsoft.com).
5703+ *
5704+ */
5705+
5706+#include <stdio.h>
5707+#include <stdlib.h>
5708+#include <string.h>
5709+#include <sys/types.h>
5710+
5711+#include <openssl/e_os2.h>
5712+#include <openssl/crypto.h>
5713+#include <cryptlib.h>
5714+#include <openssl/engine.h>
5715+#include <openssl/dso.h>
5716+#include <openssl/err.h>
5717+#include <openssl/bn.h>
5718+#include <openssl/pem.h>
5719+#ifndef OPENSSL_NO_RSA
5720+#include <openssl/rsa.h>
5721+#endif /* OPENSSL_NO_RSA */
5722+#ifndef OPENSSL_NO_DSA
5723+#include <openssl/dsa.h>
5724+#endif /* OPENSSL_NO_DSA */
5725+#ifndef OPENSSL_NO_DH
5726+#include <openssl/dh.h>
5727+#endif /* OPENSSL_NO_DH */
5728+#include <openssl/rand.h>
5729+#include <openssl/objects.h>
5730+#include <openssl/x509.h>
5731+
5732+#ifdef OPENSSL_SYS_WIN32
5733+#define NOPTHREADS
5734+typedef int pid_t;
5735+#define HAVE_GETPASSPHRASE
5736+static char *getpassphrase(const char *prompt);
5737+#ifndef NULL_PTR
5738+#define NULL_PTR NULL
5739+#endif
5740+#define CK_DEFINE_FUNCTION(returnType, name) \
5741+	returnType __declspec(dllexport) name
5742+#define CK_DECLARE_FUNCTION(returnType, name) \
5743+	returnType __declspec(dllimport) name
5744+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
5745+	returnType __declspec(dllimport) (* name)
5746+#else
5747+#include <unistd.h>
5748+#endif
5749+
5750+#ifndef NOPTHREADS
5751+#include <pthread.h>
5752+#endif
5753+
5754+#ifndef OPENSSL_NO_HW
5755+#ifndef OPENSSL_NO_HW_PK11
5756+#ifndef OPENSSL_NO_HW_PK11CA
5757+
5758+#ifdef OPENSSL_SYS_WIN32
5759+#pragma pack(push, cryptoki, 1)
5760+#include "cryptoki.h"
5761+#include "pkcs11.h"
5762+#pragma pack(pop, cryptoki)
5763+#else
5764+#include "cryptoki.h"
5765+#include "pkcs11.h"
5766+#endif
5767+#include "hw_pk11ca.h"
5768+#include "hw_pk11_err.h"
5769+
5770+static CK_BBOOL pk11_login_done = CK_FALSE;
5771+extern CK_SLOT_ID pubkey_SLOTID;
5772+#ifndef NOPTHREADS
5773+extern pthread_mutex_t *token_lock;
5774+#endif
5775+
5776+#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun)))
5777+#define getpassphrase(x)	getpass(x)
5778+#endif
5779+
5780+#ifndef OPENSSL_NO_RSA
5781+/* RSA stuff */
5782+static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
5783+	unsigned char *to, RSA *rsa, int padding);
5784+static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
5785+	unsigned char *to, RSA *rsa, int padding);
5786+static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
5787+	unsigned char *to, RSA *rsa, int padding);
5788+static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
5789+	unsigned char *to, RSA *rsa, int padding);
5790+static int pk11_RSA_init(RSA *rsa);
5791+static int pk11_RSA_finish(RSA *rsa);
5792+static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
5793+	unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
5794+#if OPENSSL_VERSION_NUMBER < 0x10000000L
5795+static int pk11_RSA_verify(int dtype, const unsigned char *m,
5796+	unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
5797+	const RSA *rsa);
5798+#else
5799+static int pk11_RSA_verify(int dtype, const unsigned char *m,
5800+	unsigned int m_len, const unsigned char *sigbuf, unsigned int siglen,
5801+	const RSA *rsa);
5802+#endif
5803+EVP_PKEY *pk11_load_privkey(ENGINE*, const char *privkey_file,
5804+	UI_METHOD *ui_method, void *callback_data);
5805+EVP_PKEY *pk11_load_pubkey(ENGINE*, const char *pubkey_file,
5806+	UI_METHOD *ui_method, void *callback_data);
5807+
5808+static int pk11_RSA_public_encrypt_low(int flen, const unsigned char *from,
5809+	unsigned char *to, RSA *rsa);
5810+static int pk11_RSA_private_encrypt_low(int flen, const unsigned char *from,
5811+	unsigned char *to, RSA *rsa);
5812+static int pk11_RSA_public_decrypt_low(int flen, const unsigned char *from,
5813+	unsigned char *to, RSA *rsa);
5814+static int pk11_RSA_private_decrypt_low(int flen, const unsigned char *from,
5815+	unsigned char *to, RSA *rsa);
5816+
5817+static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA* rsa, RSA** key_ptr,
5818+	BIGNUM **rsa_n_num, BIGNUM **rsa_e_num, CK_SESSION_HANDLE session);
5819+static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa, RSA** key_ptr,
5820+	BIGNUM **rsa_d_num, BIGNUM **rsa_n_num, BIGNUM **rsa_e_num,
5821+	CK_SESSION_HANDLE session);
5822+
5823+static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa);
5824+static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa);
5825+#endif
5826+
5827+/* DSA stuff */
5828+#ifndef OPENSSL_NO_DSA
5829+static int pk11_DSA_init(DSA *dsa);
5830+static int pk11_DSA_finish(DSA *dsa);
5831+static DSA_SIG *pk11_dsa_do_sign(const unsigned char *dgst, int dlen,
5832+	DSA *dsa);
5833+static int pk11_dsa_do_verify(const unsigned char *dgst, int dgst_len,
5834+	DSA_SIG *sig, DSA *dsa);
5835+
5836+static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa, DSA **key_ptr,
5837+	BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session);
5838+static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa, DSA **key_ptr,
5839+	BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session);
5840+
5841+static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa);
5842+static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa);
5843+#endif
5844+
5845+/* DH stuff */
5846+#ifndef OPENSSL_NO_DH
5847+static int pk11_DH_init(DH *dh);
5848+static int pk11_DH_finish(DH *dh);
5849+static int pk11_DH_generate_key(DH *dh);
5850+static int pk11_DH_compute_key(unsigned char *key,
5851+	const BIGNUM *pub_key, DH *dh);
5852+
5853+static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh, DH **key_ptr,
5854+	BIGNUM **priv_key, CK_SESSION_HANDLE session);
5855+
5856+static int check_new_dh_key(PK11_SESSION *sp, DH *dh);
5857+#endif
5858+
5859+static int find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
5860+	CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey);
5861+static int init_template_value(BIGNUM *bn, CK_VOID_PTR *pValue,
5862+	CK_ULONG *ulValueLen);
5863+static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn);
5864+
5865+static int pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
5866+	CK_BBOOL is_private);
5867+
5868+/* Read mode string to be used for fopen() */
5869+#if SOLARIS_OPENSSL
5870+static char *read_mode_flags = "rF";
5871+#else
5872+static char *read_mode_flags = "r";
5873+#endif
5874+
5875+/*
5876+ * increment/create reference for an asymmetric key handle via active list
5877+ * manipulation. If active list operation fails, unlock (if locked), set error
5878+ * variable and jump to the specified label.
5879+ */
5880+#define	KEY_HANDLE_REFHOLD(key_handle, alg_type, unlock, var, label)	\
5881+	{								\
5882+	if (pk11_active_add(key_handle, alg_type) < 0)			\
5883+		{							\
5884+		var = TRUE;						\
5885+		if (unlock)						\
5886+			UNLOCK_OBJSTORE(alg_type);			\
5887+		goto label;						\
5888+		}							\
5889+	}
5890+
5891+/*
5892+ * Find active list entry according to object handle and return pointer to the
5893+ * entry otherwise return NULL.
5894+ *
5895+ * This function presumes it is called with lock protecting the active list
5896+ * held.
5897+ */
5898+static PK11_active *pk11_active_find(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
5899+	{
5900+	PK11_active *entry;
5901+
5902+	for (entry = active_list[type]; entry != NULL; entry = entry->next)
5903+		if (entry->h == h)
5904+			return (entry);
5905+
5906+	return (NULL);
5907+	}
5908+
5909+/*
5910+ * Search for an entry in the active list using PKCS#11 object handle as a
5911+ * search key and return refcnt of the found/created entry or -1 in case of
5912+ * failure.
5913+ *
5914+ * This function presumes it is called with lock protecting the active list
5915+ * held.
5916+ */
5917+int
5918+pk11_active_add(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
5919+	{
5920+	PK11_active *entry = NULL;
5921+
5922+	if (h == CK_INVALID_HANDLE)
5923+		{
5924+		PK11err(PK11_F_ACTIVE_ADD, PK11_R_INVALID_HANDLE);
5925+		return (-1);
5926+		}
5927+
5928+	/* search for entry in the active list */
5929+	if ((entry = pk11_active_find(h, type)) != NULL)
5930+		entry->refcnt++;
5931+	else
5932+		{
5933+		/* not found, create new entry and add it to the list */
5934+		entry = OPENSSL_malloc(sizeof (PK11_active));
5935+		if (entry == NULL)
5936+			{
5937+			PK11err(PK11_F_ACTIVE_ADD, PK11_R_MALLOC_FAILURE);
5938+			return (-1);
5939+			}
5940+		entry->h = h;
5941+		entry->refcnt = 1;
5942+		entry->prev = NULL;
5943+		entry->next = NULL;
5944+		/* connect the newly created entry to the list */
5945+		if (active_list[type] == NULL)
5946+			active_list[type] = entry;
5947+		else /* make the entry first in the list */
5948+			{
5949+			entry->next = active_list[type];
5950+			active_list[type]->prev = entry;
5951+			active_list[type] = entry;
5952+			}
5953+		}
5954+
5955+	return (entry->refcnt);
5956+	}
5957+
5958+/*
5959+ * Remove active list entry from the list and free it.
5960+ *
5961+ * This function presumes it is called with lock protecting the active list
5962+ * held.
5963+ */
5964+void
5965+pk11_active_remove(PK11_active *entry, PK11_OPTYPE type)
5966+	{
5967+	PK11_active *prev_entry;
5968+
5969+	/* remove the entry from the list and free it */
5970+	if ((prev_entry = entry->prev) != NULL)
5971+		{
5972+		prev_entry->next = entry->next;
5973+		if (entry->next != NULL)
5974+			entry->next->prev = prev_entry;
5975+		}
5976+	else
5977+		{
5978+		active_list[type] = entry->next;
5979+		/* we were the first but not the only one */
5980+		if (entry->next != NULL)
5981+			entry->next->prev = NULL;
5982+		}
5983+
5984+	/* sanitization */
5985+	entry->h = CK_INVALID_HANDLE;
5986+	entry->prev = NULL;
5987+	entry->next = NULL;
5988+	OPENSSL_free(entry);
5989+	}
5990+
5991+/* Free all entries from the active list. */
5992+void
5993+pk11_free_active_list(PK11_OPTYPE type)
5994+	{
5995+	PK11_active *entry;
5996+
5997+	/* only for asymmetric types since only they have C_Find* locks. */
5998+	switch (type)
5999+		{
6000+		case OP_RSA:
6001+		case OP_DSA:
6002+		case OP_DH:
6003+			break;
6004+		default:
6005+			return;
6006+		}
6007+
6008+	/* see find_lock array definition for more info on object locking */
6009+	LOCK_OBJSTORE(type);
6010+	while ((entry = active_list[type]) != NULL)
6011+		pk11_active_remove(entry, type);
6012+	UNLOCK_OBJSTORE(type);
6013+	}
6014+
6015+/*
6016+ * Search for active list entry associated with given PKCS#11 object handle,
6017+ * decrement its refcnt and if it drops to 0, disconnect the entry and free it.
6018+ *
6019+ * Return 1 if the PKCS#11 object associated with the entry has no references,
6020+ * return 0 if there is at least one reference, -1 on error.
6021+ *
6022+ * This function presumes it is called with lock protecting the active list
6023+ * held.
6024+ */
6025+int
6026+pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
6027+	{
6028+	PK11_active *entry = NULL;
6029+
6030+	if ((entry = pk11_active_find(h, type)) == NULL)
6031+		{
6032+		PK11err(PK11_F_ACTIVE_DELETE, PK11_R_INVALID_HANDLE);
6033+		return (-1);
6034+		}
6035+
6036+	OPENSSL_assert(entry->refcnt > 0);
6037+	entry->refcnt--;
6038+	if (entry->refcnt == 0)
6039+		{
6040+		pk11_active_remove(entry, type);
6041+		return (1);
6042+		}
6043+
6044+	return (0);
6045+	}
6046+
6047+#ifndef OPENSSL_NO_RSA
6048+/* Our internal RSA_METHOD that we provide pointers to */
6049+static RSA_METHOD pk11_rsa =
6050+	{
6051+	"PKCS#11 RSA method",
6052+	pk11_RSA_public_encrypt,		/* rsa_pub_encrypt */
6053+	pk11_RSA_public_decrypt,		/* rsa_pub_decrypt */
6054+	pk11_RSA_private_encrypt,		/* rsa_priv_encrypt */
6055+	pk11_RSA_private_decrypt,		/* rsa_priv_decrypt */
6056+	NULL,					/* rsa_mod_exp */
6057+	NULL,					/* bn_mod_exp */
6058+	pk11_RSA_init,				/* init */
6059+	pk11_RSA_finish,			/* finish */
6060+	RSA_FLAG_SIGN_VER,			/* flags */
6061+	NULL,					/* app_data */
6062+	pk11_RSA_sign,				/* rsa_sign */
6063+	pk11_RSA_verify				/* rsa_verify */
6064+	};
6065+
6066+RSA_METHOD *
6067+PK11_RSA(void)
6068+	{
6069+	return (&pk11_rsa);
6070+	}
6071+#endif
6072+
6073+#ifndef OPENSSL_NO_DSA
6074+/* Our internal DSA_METHOD that we provide pointers to */
6075+static DSA_METHOD pk11_dsa =
6076+	{
6077+	"PKCS#11 DSA method",
6078+	pk11_dsa_do_sign, 	/* dsa_do_sign */
6079+	NULL, 			/* dsa_sign_setup */
6080+	pk11_dsa_do_verify, 	/* dsa_do_verify */
6081+	NULL,			/* dsa_mod_exp */
6082+	NULL, 			/* bn_mod_exp */
6083+	pk11_DSA_init, 		/* init */
6084+	pk11_DSA_finish, 	/* finish */
6085+	0, 			/* flags */
6086+	NULL 			/* app_data */
6087+	};
6088+
6089+DSA_METHOD *
6090+PK11_DSA(void)
6091+	{
6092+	return (&pk11_dsa);
6093+	}
6094+#endif
6095+
6096+#ifndef OPENSSL_NO_DH
6097+/*
6098+ * PKCS #11 V2.20, section 11.2 specifies that the number of bytes needed for
6099+ * output buffer may somewhat exceed the precise number of bytes needed, but
6100+ * should not exceed it by a large amount. That may be caused, for example, by
6101+ * rounding it up to multiple of X in the underlying bignum library. 8 should be
6102+ * enough.
6103+ */
6104+#define	DH_BUF_RESERVE	8
6105+
6106+/* Our internal DH_METHOD that we provide pointers to */
6107+static DH_METHOD pk11_dh =
6108+	{
6109+	"PKCS#11 DH method",
6110+	pk11_DH_generate_key,	/* generate_key */
6111+	pk11_DH_compute_key,	/* compute_key */
6112+	NULL,			/* bn_mod_exp */
6113+	pk11_DH_init,		/* init */
6114+	pk11_DH_finish,		/* finish */
6115+	0,			/* flags */
6116+	NULL,			/* app_data */
6117+	NULL			/* generate_params */
6118+	};
6119+
6120+DH_METHOD *
6121+PK11_DH(void)
6122+	{
6123+	return (&pk11_dh);
6124+	}
6125+#endif
6126+
6127+/* Size of an SSL signature: MD5+SHA1 */
6128+#define	SSL_SIG_LENGTH		36
6129+
6130+/* Lengths of DSA data and signature */
6131+#define	DSA_DATA_LEN		20
6132+#define	DSA_SIGNATURE_LEN	40
6133+
6134+static CK_BBOOL mytrue = TRUE;
6135+static CK_BBOOL myfalse = FALSE;
6136+
6137+#ifndef OPENSSL_NO_RSA
6138+/*
6139+ * Similiar to OpenSSL to take advantage of the paddings. The goal is to
6140+ * support all paddings in this engine although PK11 library does not
6141+ * support all the paddings used in OpenSSL.
6142+ * The input errors should have been checked in the padding functions.
6143+ */
6144+static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
6145+		unsigned char *to, RSA *rsa, int padding)
6146+	{
6147+	int i, num = 0, r = -1;
6148+	unsigned char *buf = NULL;
6149+
6150+	num = BN_num_bytes(rsa->n);
6151+	if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
6152+		{
6153+		RSAerr(PK11_F_RSA_PUB_ENC, PK11_R_MALLOC_FAILURE);
6154+		goto err;
6155+		}
6156+
6157+	switch (padding)
6158+		{
6159+	case RSA_PKCS1_PADDING:
6160+		i = RSA_padding_add_PKCS1_type_2(buf, num, from, flen);
6161+		break;
6162+#ifndef OPENSSL_NO_SHA
6163+	case RSA_PKCS1_OAEP_PADDING:
6164+		i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0);
6165+		break;
6166+#endif
6167+	case RSA_SSLV23_PADDING:
6168+		i = RSA_padding_add_SSLv23(buf, num, from, flen);
6169+		break;
6170+	case RSA_NO_PADDING:
6171+		i = RSA_padding_add_none(buf, num, from, flen);
6172+		break;
6173+	default:
6174+		RSAerr(PK11_F_RSA_PUB_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
6175+		goto err;
6176+		}
6177+	if (i <= 0) goto err;
6178+
6179+	/* PK11 functions are called here */
6180+	r = pk11_RSA_public_encrypt_low(num, buf, to, rsa);
6181+err:
6182+	if (buf != NULL)
6183+		{
6184+		OPENSSL_cleanse(buf, num);
6185+		OPENSSL_free(buf);
6186+		}
6187+	return (r);
6188+	}
6189+
6190+
6191+/*
6192+ * Similar to Openssl to take advantage of the paddings. The input errors
6193+ * should be catched in the padding functions
6194+ */
6195+static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
6196+	unsigned char *to, RSA *rsa, int padding)
6197+	{
6198+	int i, num = 0, r = -1;
6199+	unsigned char *buf = NULL;
6200+
6201+	num = BN_num_bytes(rsa->n);
6202+	if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
6203+		{
6204+		RSAerr(PK11_F_RSA_PRIV_ENC, PK11_R_MALLOC_FAILURE);
6205+		goto err;
6206+		}
6207+
6208+	switch (padding)
6209+		{
6210+	case RSA_PKCS1_PADDING:
6211+		i = RSA_padding_add_PKCS1_type_1(buf, num, from, flen);
6212+		break;
6213+	case RSA_NO_PADDING:
6214+		i = RSA_padding_add_none(buf, num, from, flen);
6215+		break;
6216+	case RSA_SSLV23_PADDING:
6217+	default:
6218+		RSAerr(PK11_F_RSA_PRIV_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
6219+		goto err;
6220+		}
6221+	if (i <= 0) goto err;
6222+
6223+	/* PK11 functions are called here */
6224+	r = pk11_RSA_private_encrypt_low(num, buf, to, rsa);
6225+err:
6226+	if (buf != NULL)
6227+		{
6228+		OPENSSL_cleanse(buf, num);
6229+		OPENSSL_free(buf);
6230+		}
6231+	return (r);
6232+	}
6233+
6234+/* Similar to OpenSSL code. Input errors are also checked here */
6235+static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
6236+	unsigned char *to, RSA *rsa, int padding)
6237+	{
6238+	BIGNUM f;
6239+	int j, num = 0, r = -1;
6240+	unsigned char *p;
6241+	unsigned char *buf = NULL;
6242+
6243+	BN_init(&f);
6244+
6245+	num = BN_num_bytes(rsa->n);
6246+
6247+	if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
6248+		{
6249+		RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_MALLOC_FAILURE);
6250+		goto err;
6251+		}
6252+
6253+	/*
6254+	 * This check was for equality but PGP does evil things
6255+	 * and chops off the top '0' bytes
6256+	 */
6257+	if (flen > num)
6258+		{
6259+		RSAerr(PK11_F_RSA_PRIV_DEC,
6260+			PK11_R_DATA_GREATER_THAN_MOD_LEN);
6261+		goto err;
6262+		}
6263+
6264+	/* make data into a big number */
6265+	if (BN_bin2bn(from, (int)flen, &f) == NULL)
6266+		goto err;
6267+
6268+	if (BN_ucmp(&f, rsa->n) >= 0)
6269+		{
6270+		RSAerr(PK11_F_RSA_PRIV_DEC,
6271+			PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
6272+		goto err;
6273+		}
6274+
6275+	/* PK11 functions are called here */
6276+	r = pk11_RSA_private_decrypt_low(flen, from, buf, rsa);
6277+
6278+	/*
6279+	 * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
6280+	 * Needs to skip these 0's paddings here.
6281+	 */
6282+	for (j = 0; j < r; j++)
6283+		if (buf[j] != 0)
6284+			break;
6285+
6286+	p = buf + j;
6287+	j = r - j;  /* j is only used with no-padding mode */
6288+
6289+	switch (padding)
6290+		{
6291+	case RSA_PKCS1_PADDING:
6292+		r = RSA_padding_check_PKCS1_type_2(to, num, p, j, num);
6293+		break;
6294+#ifndef OPENSSL_NO_SHA
6295+	case RSA_PKCS1_OAEP_PADDING:
6296+		r = RSA_padding_check_PKCS1_OAEP(to, num, p, j, num, NULL, 0);
6297+		break;
6298+#endif
6299+	case RSA_SSLV23_PADDING:
6300+		r = RSA_padding_check_SSLv23(to, num, p, j, num);
6301+		break;
6302+	case RSA_NO_PADDING:
6303+		r = RSA_padding_check_none(to, num, p, j, num);
6304+		break;
6305+	default:
6306+		RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
6307+		goto err;
6308+		}
6309+	if (r < 0)
6310+		RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_PADDING_CHECK_FAILED);
6311+
6312+err:
6313+	BN_clear_free(&f);
6314+	if (buf != NULL)
6315+		{
6316+		OPENSSL_cleanse(buf, num);
6317+		OPENSSL_free(buf);
6318+		}
6319+	return (r);
6320+	}
6321+
6322+/* Similar to OpenSSL code. Input errors are also checked here */
6323+static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
6324+	unsigned char *to, RSA *rsa, int padding)
6325+	{
6326+	BIGNUM f;
6327+	int i, num = 0, r = -1;
6328+	unsigned char *p;
6329+	unsigned char *buf = NULL;
6330+
6331+	BN_init(&f);
6332+	num = BN_num_bytes(rsa->n);
6333+	buf = (unsigned char *)OPENSSL_malloc(num);
6334+	if (buf == NULL)
6335+		{
6336+		RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_MALLOC_FAILURE);
6337+		goto err;
6338+		}
6339+
6340+	/*
6341+	 * This check was for equality but PGP does evil things
6342+	 * and chops off the top '0' bytes
6343+	 */
6344+	if (flen > num)
6345+		{
6346+		RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_DATA_GREATER_THAN_MOD_LEN);
6347+		goto err;
6348+		}
6349+
6350+	if (BN_bin2bn(from, flen, &f) == NULL)
6351+		goto err;
6352+
6353+	if (BN_ucmp(&f, rsa->n) >= 0)
6354+		{
6355+		RSAerr(PK11_F_RSA_PUB_DEC,
6356+			PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
6357+		goto err;
6358+		}
6359+
6360+	/* PK11 functions are called here */
6361+	r = pk11_RSA_public_decrypt_low(flen, from, buf, rsa);
6362+
6363+	/*
6364+	 * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
6365+	 * Needs to skip these 0's here
6366+	 */
6367+	for (i = 0; i < r; i++)
6368+		if (buf[i] != 0)
6369+			break;
6370+
6371+	p = buf + i;
6372+	i = r - i;  /* i is only used with no-padding mode */
6373+
6374+	switch (padding)
6375+		{
6376+	case RSA_PKCS1_PADDING:
6377+		r = RSA_padding_check_PKCS1_type_1(to, num, p, i, num);
6378+		break;
6379+	case RSA_NO_PADDING:
6380+		r = RSA_padding_check_none(to, num, p, i, num);
6381+		break;
6382+	default:
6383+		RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
6384+		goto err;
6385+		}
6386+	if (r < 0)
6387+		RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_PADDING_CHECK_FAILED);
6388+
6389+err:
6390+	BN_clear_free(&f);
6391+	if (buf != NULL)
6392+		{
6393+		OPENSSL_cleanse(buf, num);
6394+		OPENSSL_free(buf);
6395+		}
6396+	return (r);
6397+	}
6398+
6399+/*
6400+ * This function implements RSA public encryption using C_EncryptInit and
6401+ * C_Encrypt pk11 interfaces. Note that the CKM_RSA_X_509 is used here.
6402+ * The calling function allocated sufficient memory in "to" to store results.
6403+ */
6404+static int pk11_RSA_public_encrypt_low(int flen,
6405+	const unsigned char *from, unsigned char *to, RSA *rsa)
6406+	{
6407+	CK_ULONG bytes_encrypted = flen;
6408+	int retval = -1;
6409+	CK_RV rv;
6410+	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6411+	CK_MECHANISM *p_mech = &mech_rsa;
6412+	CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
6413+	PK11_SESSION *sp;
6414+
6415+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
6416+		return (-1);
6417+
6418+	(void) check_new_rsa_key_pub(sp, rsa);
6419+
6420+	h_pub_key = sp->opdata_rsa_pub_key;
6421+	if (h_pub_key == CK_INVALID_HANDLE)
6422+		h_pub_key = sp->opdata_rsa_pub_key =
6423+			pk11_get_public_rsa_key(rsa, &sp->opdata_rsa_pub,
6424+			    &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
6425+			    sp->session);
6426+
6427+	if (h_pub_key != CK_INVALID_HANDLE)
6428+		{
6429+		rv = pFuncList->C_EncryptInit(sp->session, p_mech,
6430+			h_pub_key);
6431+
6432+		if (rv != CKR_OK)
6433+			{
6434+			PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
6435+			    PK11_R_ENCRYPTINIT, rv);
6436+			pk11_return_session(sp, OP_RSA);
6437+			return (-1);
6438+			}
6439+
6440+		rv = pFuncList->C_Encrypt(sp->session,
6441+			(unsigned char *)from, flen, to, &bytes_encrypted);
6442+
6443+		if (rv != CKR_OK)
6444+			{
6445+			PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
6446+			    PK11_R_ENCRYPT, rv);
6447+			pk11_return_session(sp, OP_RSA);
6448+			return (-1);
6449+			}
6450+		retval = bytes_encrypted;
6451+		}
6452+
6453+	pk11_return_session(sp, OP_RSA);
6454+	return (retval);
6455+	}
6456+
6457+
6458+/*
6459+ * This function implements RSA private encryption using C_SignInit and
6460+ * C_Sign pk11 APIs. Note that CKM_RSA_X_509 is used here.
6461+ * The calling function allocated sufficient memory in "to" to store results.
6462+ */
6463+static int pk11_RSA_private_encrypt_low(int flen,
6464+	const unsigned char *from, unsigned char *to, RSA *rsa)
6465+	{
6466+	CK_ULONG ul_sig_len = flen;
6467+	int retval = -1;
6468+	CK_RV rv;
6469+	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6470+	CK_MECHANISM *p_mech = &mech_rsa;
6471+	CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
6472+	PK11_SESSION *sp;
6473+
6474+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
6475+		return (-1);
6476+
6477+	(void) check_new_rsa_key_priv(sp, rsa);
6478+
6479+	h_priv_key = sp->opdata_rsa_priv_key;
6480+	if (h_priv_key == CK_INVALID_HANDLE)
6481+		{
6482+		h_priv_key = sp->opdata_rsa_priv_key =
6483+			pk11_get_private_rsa_key(rsa, &sp->opdata_rsa_priv,
6484+			    &sp->opdata_rsa_d_num, &sp->opdata_rsa_pn_num,
6485+			    &sp->opdata_rsa_pe_num, sp->session);
6486+		}
6487+
6488+	if (h_priv_key != CK_INVALID_HANDLE)
6489+		{
6490+		rv = pFuncList->C_SignInit(sp->session, p_mech,
6491+			h_priv_key);
6492+
6493+		if (rv != CKR_OK)
6494+			{
6495+			PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW,
6496+			    PK11_R_SIGNINIT, rv);
6497+			pk11_return_session(sp, OP_RSA);
6498+			return (-1);
6499+			}
6500+
6501+		rv = pFuncList->C_Sign(sp->session,
6502+			(unsigned char *)from, flen, to, &ul_sig_len);
6503+
6504+		if (rv != CKR_OK)
6505+			{
6506+			PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW, PK11_R_SIGN,
6507+			    rv);
6508+			pk11_return_session(sp, OP_RSA);
6509+			return (-1);
6510+			}
6511+
6512+		retval = ul_sig_len;
6513+		}
6514+
6515+	pk11_return_session(sp, OP_RSA);
6516+	return (retval);
6517+	}
6518+
6519+
6520+/*
6521+ * This function implements RSA private decryption using C_DecryptInit and
6522+ * C_Decrypt pk11 APIs. Note that CKM_RSA_X_509 mechanism is used here.
6523+ * The calling function allocated sufficient memory in "to" to store results.
6524+ */
6525+static int pk11_RSA_private_decrypt_low(int flen,
6526+	const unsigned char *from, unsigned char *to, RSA *rsa)
6527+	{
6528+	CK_ULONG bytes_decrypted = flen;
6529+	int retval = -1;
6530+	CK_RV rv;
6531+	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6532+	CK_MECHANISM *p_mech = &mech_rsa;
6533+	CK_OBJECT_HANDLE h_priv_key;
6534+	PK11_SESSION *sp;
6535+
6536+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
6537+		return (-1);
6538+
6539+	(void) check_new_rsa_key_priv(sp, rsa);
6540+
6541+	h_priv_key = sp->opdata_rsa_priv_key;
6542+	if (h_priv_key == CK_INVALID_HANDLE)
6543+		h_priv_key = sp->opdata_rsa_priv_key =
6544+			pk11_get_private_rsa_key(rsa, &sp->opdata_rsa_priv,
6545+			    &sp->opdata_rsa_d_num, &sp->opdata_rsa_pn_num,
6546+			    &sp->opdata_rsa_pe_num, sp->session);
6547+
6548+	if (h_priv_key != CK_INVALID_HANDLE)
6549+		{
6550+		rv = pFuncList->C_DecryptInit(sp->session, p_mech,
6551+			h_priv_key);
6552+
6553+		if (rv != CKR_OK)
6554+			{
6555+			PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
6556+				PK11_R_DECRYPTINIT, rv);
6557+			pk11_return_session(sp, OP_RSA);
6558+			return (-1);
6559+			}
6560+
6561+		rv = pFuncList->C_Decrypt(sp->session,
6562+			(unsigned char *)from, flen, to, &bytes_decrypted);
6563+
6564+		if (rv != CKR_OK)
6565+			{
6566+			PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
6567+			    PK11_R_DECRYPT, rv);
6568+			pk11_return_session(sp, OP_RSA);
6569+			return (-1);
6570+			}
6571+		retval = bytes_decrypted;
6572+		}
6573+
6574+	pk11_return_session(sp, OP_RSA);
6575+	return (retval);
6576+	}
6577+
6578+
6579+/*
6580+ * This function implements RSA public decryption using C_VerifyRecoverInit
6581+ * and C_VerifyRecover pk11 APIs. Note that CKM_RSA_X_509 is used here.
6582+ * The calling function allocated sufficient memory in "to" to store results.
6583+ */
6584+static int pk11_RSA_public_decrypt_low(int flen,
6585+	const unsigned char *from, unsigned char *to, RSA *rsa)
6586+	{
6587+	CK_ULONG bytes_decrypted = flen;
6588+	int retval = -1;
6589+	CK_RV rv;
6590+	CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6591+	CK_MECHANISM *p_mech = &mech_rsa;
6592+	CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
6593+	PK11_SESSION *sp;
6594+
6595+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
6596+		return (-1);
6597+
6598+	(void) check_new_rsa_key_pub(sp, rsa);
6599+
6600+	h_pub_key = sp->opdata_rsa_pub_key;
6601+	if (h_pub_key == CK_INVALID_HANDLE)
6602+		h_pub_key = sp->opdata_rsa_pub_key =
6603+			pk11_get_public_rsa_key(rsa, &sp->opdata_rsa_pub,
6604+			    &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
6605+			    sp->session);
6606+
6607+	if (h_pub_key != CK_INVALID_HANDLE)
6608+		{
6609+		rv = pFuncList->C_VerifyRecoverInit(sp->session,
6610+			p_mech, h_pub_key);
6611+
6612+		if (rv != CKR_OK)
6613+			{
6614+			PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
6615+				PK11_R_VERIFYRECOVERINIT, rv);
6616+			pk11_return_session(sp, OP_RSA);
6617+			return (-1);
6618+			}
6619+
6620+		rv = pFuncList->C_VerifyRecover(sp->session,
6621+			(unsigned char *)from, flen, to, &bytes_decrypted);
6622+
6623+		if (rv != CKR_OK)
6624+			{
6625+			PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
6626+			    PK11_R_VERIFYRECOVER, rv);
6627+			pk11_return_session(sp, OP_RSA);
6628+			return (-1);
6629+			}
6630+		retval = bytes_decrypted;
6631+		}
6632+
6633+	pk11_return_session(sp, OP_RSA);
6634+	return (retval);
6635+	}
6636+
6637+static int pk11_RSA_init(RSA *rsa)
6638+	{
6639+	/*
6640+	 * This flag in the RSA_METHOD enables the new rsa_sign,
6641+	 * rsa_verify functions. See rsa.h for details.
6642+	 */
6643+	rsa->flags |= RSA_FLAG_SIGN_VER;
6644+
6645+	return (1);
6646+	}
6647+
6648+static int pk11_RSA_finish(RSA *rsa)
6649+	{
6650+	/*
6651+	 * Since we are overloading OpenSSL's native RSA_eay_finish() we need
6652+	 * to do the same as in the original function, i.e. to free bignum
6653+	 * structures.
6654+	 */
6655+	if (rsa->_method_mod_n != NULL)
6656+		BN_MONT_CTX_free(rsa->_method_mod_n);
6657+	if (rsa->_method_mod_p != NULL)
6658+		BN_MONT_CTX_free(rsa->_method_mod_p);
6659+	if (rsa->_method_mod_q != NULL)
6660+		BN_MONT_CTX_free(rsa->_method_mod_q);
6661+
6662+	return (1);
6663+	}
6664+
6665+/*
6666+ * Standard engine interface function. Majority codes here are from
6667+ * rsa/rsa_sign.c. We replaced the decrypt function call by C_Sign of PKCS#11.
6668+ * See more details in rsa/rsa_sign.c
6669+ */
6670+static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
6671+	unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
6672+	{
6673+	X509_SIG sig;
6674+	ASN1_TYPE parameter;
6675+	int i, j = 0;
6676+	unsigned char *p, *s = NULL;
6677+	X509_ALGOR algor;
6678+	ASN1_OCTET_STRING digest;
6679+	CK_RV rv;
6680+	CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
6681+	CK_MECHANISM *p_mech = &mech_rsa;
6682+	CK_OBJECT_HANDLE h_priv_key;
6683+	PK11_SESSION *sp = NULL;
6684+	int ret = 0;
6685+	unsigned long ulsiglen;
6686+
6687+	/* Encode the digest */
6688+	/* Special case: SSL signature, just check the length */
6689+	if (type == NID_md5_sha1)
6690+		{
6691+		if (m_len != SSL_SIG_LENGTH)
6692+			{
6693+			PK11err(PK11_F_RSA_SIGN,
6694+				PK11_R_INVALID_MESSAGE_LENGTH);
6695+			goto err;
6696+			}
6697+		i = SSL_SIG_LENGTH;
6698+		s = (unsigned char *)m;
6699+		}
6700+	else
6701+		{
6702+		sig.algor = &algor;
6703+		sig.algor->algorithm = OBJ_nid2obj(type);
6704+		if (sig.algor->algorithm == NULL)
6705+			{
6706+			PK11err(PK11_F_RSA_SIGN,
6707+				PK11_R_UNKNOWN_ALGORITHM_TYPE);
6708+			goto err;
6709+			}
6710+		if (sig.algor->algorithm->length == 0)
6711+			{
6712+			PK11err(PK11_F_RSA_SIGN,
6713+				PK11_R_UNKNOWN_ASN1_OBJECT_ID);
6714+			goto err;
6715+			}
6716+		parameter.type = V_ASN1_NULL;
6717+		parameter.value.ptr = NULL;
6718+		sig.algor->parameter = &parameter;
6719+
6720+		sig.digest = &digest;
6721+		sig.digest->data = (unsigned char *)m;
6722+		sig.digest->length = m_len;
6723+
6724+		i = i2d_X509_SIG(&sig, NULL);
6725+		}
6726+
6727+	j = RSA_size(rsa);
6728+	if ((i - RSA_PKCS1_PADDING) > j)
6729+		{
6730+		PK11err(PK11_F_RSA_SIGN, PK11_R_DIGEST_TOO_BIG);
6731+		goto err;
6732+		}
6733+
6734+	if (type != NID_md5_sha1)
6735+		{
6736+		s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
6737+		if (s == NULL)
6738+			{
6739+			PK11err(PK11_F_RSA_SIGN, PK11_R_MALLOC_FAILURE);
6740+			goto err;
6741+			}
6742+		p = s;
6743+		(void) i2d_X509_SIG(&sig, &p);
6744+		}
6745+
6746+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
6747+		goto err;
6748+
6749+	(void) check_new_rsa_key_priv(sp, rsa);
6750+
6751+	h_priv_key = sp->opdata_rsa_priv_key;
6752+	if (h_priv_key == CK_INVALID_HANDLE)
6753+		h_priv_key = sp->opdata_rsa_priv_key =
6754+			pk11_get_private_rsa_key((RSA *)rsa,
6755+			    &sp->opdata_rsa_priv, &sp->opdata_rsa_d_num,
6756+			    &sp->opdata_rsa_pn_num, &sp->opdata_rsa_pe_num,
6757+			    sp->session);
6758+
6759+	if (h_priv_key != CK_INVALID_HANDLE)
6760+		{
6761+		rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
6762+
6763+		if (rv != CKR_OK)
6764+			{
6765+			PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGNINIT, rv);
6766+			goto err;
6767+			}
6768+
6769+		ulsiglen = j;
6770+		rv = pFuncList->C_Sign(sp->session, s, i, sigret,
6771+			(CK_ULONG_PTR) &ulsiglen);
6772+		*siglen = ulsiglen;
6773+
6774+		if (rv != CKR_OK)
6775+			{
6776+			PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGN, rv);
6777+			goto err;
6778+			}
6779+		ret = 1;
6780+		}
6781+
6782+err:
6783+	if ((type != NID_md5_sha1) && (s != NULL))
6784+		{
6785+		(void) memset(s, 0, (unsigned int)(j + 1));
6786+		OPENSSL_free(s);
6787+		}
6788+
6789+	pk11_return_session(sp, OP_RSA);
6790+	return (ret);
6791+	}
6792+
6793+#if OPENSSL_VERSION_NUMBER < 0x10000000L
6794+static int pk11_RSA_verify(int type, const unsigned char *m,
6795+	unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
6796+	const RSA *rsa)
6797+#else
6798+static int pk11_RSA_verify(int type, const unsigned char *m,
6799+	unsigned int m_len, const unsigned char *sigbuf, unsigned int siglen,
6800+	const RSA *rsa)
6801+#endif
6802+	{
6803+	X509_SIG sig;
6804+	ASN1_TYPE parameter;
6805+	int i, j = 0;
6806+	unsigned char *p, *s = NULL;
6807+	X509_ALGOR algor;
6808+	ASN1_OCTET_STRING digest;
6809+	CK_RV rv;
6810+	CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
6811+	CK_MECHANISM *p_mech = &mech_rsa;
6812+	CK_OBJECT_HANDLE h_pub_key;
6813+	PK11_SESSION *sp = NULL;
6814+	int ret = 0;
6815+
6816+	/* Encode the digest	*/
6817+	/* Special case: SSL signature, just check the length */
6818+	if (type == NID_md5_sha1)
6819+		{
6820+		if (m_len != SSL_SIG_LENGTH)
6821+			{
6822+			PK11err(PK11_F_RSA_VERIFY,
6823+				PK11_R_INVALID_MESSAGE_LENGTH);
6824+			goto err;
6825+			}
6826+		i = SSL_SIG_LENGTH;
6827+		s = (unsigned char *)m;
6828+		}
6829+	else
6830+		{
6831+		sig.algor = &algor;
6832+		sig.algor->algorithm = OBJ_nid2obj(type);
6833+		if (sig.algor->algorithm == NULL)
6834+			{
6835+			PK11err(PK11_F_RSA_VERIFY,
6836+				PK11_R_UNKNOWN_ALGORITHM_TYPE);
6837+			goto err;
6838+			}
6839+		if (sig.algor->algorithm->length == 0)
6840+			{
6841+			PK11err(PK11_F_RSA_VERIFY,
6842+				PK11_R_UNKNOWN_ASN1_OBJECT_ID);
6843+			goto err;
6844+			}
6845+		parameter.type = V_ASN1_NULL;
6846+		parameter.value.ptr = NULL;
6847+		sig.algor->parameter = &parameter;
6848+		sig.digest = &digest;
6849+		sig.digest->data = (unsigned char *)m;
6850+		sig.digest->length = m_len;
6851+		i = i2d_X509_SIG(&sig, NULL);
6852+		}
6853+
6854+	j = RSA_size(rsa);
6855+	if ((i - RSA_PKCS1_PADDING) > j)
6856+		{
6857+		PK11err(PK11_F_RSA_VERIFY, PK11_R_DIGEST_TOO_BIG);
6858+		goto err;
6859+		}
6860+
6861+	if (type != NID_md5_sha1)
6862+		{
6863+		s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
6864+		if (s == NULL)
6865+			{
6866+			PK11err(PK11_F_RSA_VERIFY, PK11_R_MALLOC_FAILURE);
6867+			goto err;
6868+			}
6869+		p = s;
6870+		(void) i2d_X509_SIG(&sig, &p);
6871+		}
6872+
6873+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
6874+		goto err;
6875+
6876+	(void) check_new_rsa_key_pub(sp, rsa);
6877+
6878+	h_pub_key = sp->opdata_rsa_pub_key;
6879+	if (h_pub_key == CK_INVALID_HANDLE)
6880+		h_pub_key = sp->opdata_rsa_pub_key =
6881+			pk11_get_public_rsa_key((RSA *)rsa, &sp->opdata_rsa_pub,
6882+			    &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
6883+			    sp->session);
6884+
6885+	if (h_pub_key != CK_INVALID_HANDLE)
6886+		{
6887+		rv = pFuncList->C_VerifyInit(sp->session, p_mech,
6888+			h_pub_key);
6889+
6890+		if (rv != CKR_OK)
6891+			{
6892+			PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFYINIT,
6893+			    rv);
6894+			goto err;
6895+			}
6896+		rv = pFuncList->C_Verify(sp->session, s, i,
6897+			(CK_BYTE_PTR)sigbuf, (CK_ULONG)siglen);
6898+
6899+		if (rv != CKR_OK)
6900+			{
6901+			PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFY, rv);
6902+			goto err;
6903+			}
6904+		ret = 1;
6905+		}
6906+
6907+err:
6908+	if ((type != NID_md5_sha1) && (s != NULL))
6909+		{
6910+		(void) memset(s, 0, (unsigned int)(j + 1));
6911+		OPENSSL_free(s);
6912+		}
6913+
6914+	pk11_return_session(sp, OP_RSA);
6915+	return (ret);
6916+	}
6917+
6918+static int hndidx_rsa = -1;
6919+
6920+#define	MAXATTR	1024
6921+
6922+/*
6923+ * Load RSA private key from a file or get its PKCS#11 handle if stored in the
6924+ * PKCS#11 token.
6925+ */
6926+/* ARGSUSED */
6927+EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *privkey_file,
6928+	UI_METHOD *ui_method, void *callback_data)
6929+	{
6930+	EVP_PKEY *pkey = NULL;
6931+	FILE *privkey;
6932+	CK_OBJECT_HANDLE  h_priv_key = CK_INVALID_HANDLE;
6933+	RSA *rsa = NULL;
6934+	PK11_SESSION *sp;
6935+	/* Anything else below is needed for the key by reference extension. */
6936+	CK_RV rv;
6937+	CK_BBOOL is_token = TRUE;
6938+	CK_BBOOL rollback = FALSE;
6939+	CK_BYTE attr_data[2][MAXATTR];
6940+	CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
6941+	CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;	/* key in keystore */
6942+
6943+	/* we look for private keys only */
6944+	CK_ATTRIBUTE search_templ[] =
6945+		{
6946+		{CKA_TOKEN, &is_token, sizeof(is_token)},
6947+		{CKA_CLASS, &key_class, sizeof(key_class)},
6948+		{CKA_LABEL, NULL, 0}
6949+		};
6950+
6951+	/*
6952+	 * These public attributes are needed to initialize the OpenSSL RSA
6953+	 * structure with something we can use to look up the key. Note that we
6954+	 * never ask for private components.
6955+	 */
6956+	CK_ATTRIBUTE get_templ[] =
6957+		{
6958+		{CKA_MODULUS, (void *)attr_data[0], MAXATTR},		/* n */
6959+		{CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},	/* e */
6960+		};
6961+
6962+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
6963+		return (NULL);
6964+
6965+	/*
6966+	 * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
6967+	 */
6968+	if (strstr(privkey_file, "pkcs11:") == privkey_file)
6969+		{
6970+		search_templ[2].pValue = strstr(privkey_file, ":") + 1;
6971+		search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
6972+
6973+		if (pk11_token_login(sp->session, &pk11_login_done,
6974+		    CK_TRUE) == 0)
6975+			goto err;
6976+
6977+		/* see find_lock array definition
6978+		   for more info on object locking */
6979+		LOCK_OBJSTORE(OP_RSA);
6980+
6981+		/*
6982+		 * Now let's try to find the key in the token. It is a failure
6983+		 * if we can't find it.
6984+		 */
6985+		if (find_one_object(OP_RSA, sp->session, search_templ, 3,
6986+		    &ks_key) == 0)
6987+			{
6988+			UNLOCK_OBJSTORE(OP_RSA);
6989+			goto err;
6990+			}
6991+
6992+		if (hndidx_rsa == -1)
6993+			hndidx_rsa = RSA_get_ex_new_index(0,
6994+				        "pkcs11 RSA HSM key handle",
6995+					NULL, NULL, NULL);
6996+
6997+		/*
6998+		 * We might have a cache hit which we could confirm
6999+		 * according to the 'n'/'e' params, RSA public pointer
7000+		 * as NULL, and non-NULL RSA private pointer. However,
7001+		 * it is easier just to recreate everything. We expect
7002+		 * the keys to be loaded once and used many times. We
7003+		 * do not check the return value because even in case
7004+		 * of failure the sp structure will have both key
7005+		 * pointer and object handle cleaned and
7006+		 * pk11_destroy_object() reports the failure to the
7007+		 * OpenSSL error message buffer.
7008+		 */
7009+		(void) pk11_destroy_rsa_object_priv(sp, FALSE);
7010+
7011+		sp->opdata_rsa_priv_key = ks_key;
7012+		/* This object shall not be deleted on a cache miss. */
7013+		sp->priv_persistent = CK_TRUE;
7014+
7015+		/*
7016+		 * Cache the RSA private structure pointer. We do not
7017+		 * use it now for key-by-ref keys but let's do it for
7018+		 * consistency reasons.
7019+		 */
7020+		if ((rsa = sp->opdata_rsa_priv = RSA_new_method(e)) == NULL)
7021+			{
7022+			UNLOCK_OBJSTORE(OP_RSA);
7023+			goto err;
7024+			}
7025+
7026+		/*
7027+		 * Now we have to initialize an OpenSSL RSA structure,
7028+		 * everything else is 0 or NULL.
7029+		 */
7030+		rsa->flags = RSA_FLAG_SIGN_VER | RSA_FLAG_EXT_PKEY;
7031+		RSA_set_ex_data(rsa, hndidx_rsa, (void *) ks_key);
7032+
7033+		if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
7034+		    get_templ, 2)) != CKR_OK)
7035+			{
7036+			UNLOCK_OBJSTORE(OP_RSA);
7037+			PK11err_add_data(PK11_F_LOAD_PRIVKEY,
7038+					 PK11_R_GETATTRIBUTVALUE, rv);
7039+			goto err;
7040+			}
7041+
7042+		/*
7043+		 * We do not use pk11_get_private_rsa_key() here so we
7044+		 * must take care of handle management ourselves.
7045+		 */
7046+		KEY_HANDLE_REFHOLD(ks_key, OP_RSA, TRUE, rollback, err);
7047+
7048+		/*
7049+		 * Those are the sensitive components we do not want to export
7050+		 * from the token at all: rsa->(d|p|q|dmp1|dmq1|iqmp).
7051+		 */
7052+		attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
7053+		attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
7054+		/*
7055+		 * Must have 'n'/'e' components in the session structure as
7056+		 * well. They serve as a public look-up key for the private key
7057+		 * in the keystore.
7058+		 */
7059+		attr_to_BN(&get_templ[0], attr_data[0],
7060+			&sp->opdata_rsa_pn_num);
7061+		attr_to_BN(&get_templ[1], attr_data[1],
7062+			&sp->opdata_rsa_pe_num);
7063+
7064+		UNLOCK_OBJSTORE(OP_RSA);
7065+
7066+		if ((pkey = EVP_PKEY_new()) == NULL)
7067+			goto err;
7068+
7069+		if (EVP_PKEY_assign_RSA(pkey, rsa) == 0)
7070+			goto err;
7071+		}
7072+	else if ((privkey = fopen(privkey_file, read_mode_flags)) != NULL)
7073+		{
7074+		pkey = PEM_read_PrivateKey(privkey, NULL, NULL, NULL);
7075+		(void) fclose(privkey);
7076+		if (pkey != NULL)
7077+			{
7078+			rsa = EVP_PKEY_get1_RSA(pkey);
7079+			if (rsa != NULL)
7080+				{
7081+				/*
7082+				 * This will always destroy the RSA
7083+				 * object since we have a new RSA
7084+				 * structure here.
7085+				 */
7086+				(void) check_new_rsa_key_priv(sp, rsa);
7087+				sp->priv_persistent = CK_FALSE;
7088+
7089+				h_priv_key = sp->opdata_rsa_priv_key =
7090+				    pk11_get_private_rsa_key(rsa,
7091+				    &sp->opdata_rsa_priv,
7092+				    &sp->opdata_rsa_d_num,
7093+				    &sp->opdata_rsa_pn_num,
7094+				    &sp->opdata_rsa_pe_num, sp->session);
7095+				if (h_priv_key == CK_INVALID_HANDLE)
7096+					goto err;
7097+				}
7098+			else
7099+				goto err;
7100+			}
7101+		}
7102+
7103+	pk11_return_session(sp, OP_RSA);
7104+	return (pkey);
7105+err:
7106+	pk11_return_session(sp, OP_RSA);
7107+	if (rsa != NULL)
7108+		RSA_free(rsa);
7109+	if (pkey != NULL)
7110+		{
7111+		EVP_PKEY_free(pkey);
7112+		pkey = NULL;
7113+		}
7114+	rollback = rollback;
7115+	return (pkey);
7116+	}
7117+
7118+/*
7119+ * Load RSA public key from a file or get its PKCS#11 handle if stored in the
7120+ * PKCS#11 token.
7121+ */
7122+/* ARGSUSED */
7123+EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
7124+	UI_METHOD *ui_method, void *callback_data)
7125+	{
7126+	EVP_PKEY *pkey = NULL;
7127+	FILE *pubkey;
7128+	CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
7129+	RSA *rsa = NULL;
7130+	PK11_SESSION *sp;
7131+	/* Anything else below is needed for the key by reference extension. */
7132+	CK_RV rv;
7133+	CK_BBOOL is_token = TRUE;
7134+	CK_BYTE attr_data[2][MAXATTR];
7135+	CK_OBJECT_CLASS key_class = CKO_PUBLIC_KEY;
7136+	CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;	/* key in keystore */
7137+
7138+	/* we look for public keys only */
7139+	CK_ATTRIBUTE search_templ[] =
7140+		{
7141+		{CKA_TOKEN, &is_token, sizeof(is_token)},
7142+		{CKA_CLASS, &key_class, sizeof(key_class)},
7143+		{CKA_LABEL, NULL, 0}
7144+		};
7145+
7146+	/*
7147+	 * These public attributes are needed to initialize OpenSSL RSA
7148+	 * structure with something we can use to look up the key.
7149+	 */
7150+	CK_ATTRIBUTE get_templ[] =
7151+		{
7152+		{CKA_MODULUS, (void *)attr_data[0], MAXATTR},		/* n */
7153+		{CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},	/* e */
7154+		};
7155+
7156+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
7157+		return (NULL);
7158+
7159+	/*
7160+	 * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
7161+	 */
7162+	if (strstr(pubkey_file, "pkcs11:") == pubkey_file)
7163+		{
7164+		search_templ[2].pValue = strstr(pubkey_file, ":") + 1;
7165+		search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
7166+
7167+		if (pk11_token_login(sp->session, &pk11_login_done,
7168+		    CK_FALSE) == 0)
7169+			goto err;
7170+
7171+		/* see find_lock array definition
7172+		   for more info on object locking */
7173+		LOCK_OBJSTORE(OP_RSA);
7174+
7175+		/*
7176+		 * Now let's try to find the key in the token. It is a failure
7177+		 * if we can't find it.
7178+		 */
7179+		if (find_one_object(OP_RSA, sp->session, search_templ, 3,
7180+		    &ks_key) == 0)
7181+			{
7182+			UNLOCK_OBJSTORE(OP_RSA);
7183+			goto err;
7184+			}
7185+
7186+		/*
7187+		 * We load a new public key so we will create a new RSA
7188+		 * structure. No cache hit is possible.
7189+		 */
7190+		(void) pk11_destroy_rsa_object_pub(sp, FALSE);
7191+
7192+		sp->opdata_rsa_pub_key = ks_key;
7193+		/* This object shall not be deleted on a cache miss. */
7194+		sp->pub_persistent = CK_TRUE;
7195+
7196+		/*
7197+		 * Cache the RSA public structure pointer.
7198+		 */
7199+		if ((rsa = sp->opdata_rsa_pub = RSA_new_method(e)) == NULL)
7200+			{
7201+			UNLOCK_OBJSTORE(OP_RSA);
7202+			goto err;
7203+			}
7204+
7205+		/*
7206+		 * Now we have to initialize an OpenSSL RSA structure,
7207+		 * everything else is 0 or NULL.
7208+		 */
7209+		rsa->flags = RSA_FLAG_SIGN_VER;
7210+
7211+		if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
7212+		    get_templ, 2)) != CKR_OK)
7213+			{
7214+			UNLOCK_OBJSTORE(OP_RSA);
7215+			PK11err_add_data(PK11_F_LOAD_PUBKEY,
7216+					 PK11_R_GETATTRIBUTVALUE, rv);
7217+			goto err;
7218+			}
7219+
7220+		attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
7221+		attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
7222+
7223+		UNLOCK_OBJSTORE(OP_RSA);
7224+
7225+		if ((pkey = EVP_PKEY_new()) == NULL)
7226+			goto err;
7227+
7228+		if (EVP_PKEY_assign_RSA(pkey, rsa) == 0)
7229+			goto err;
7230+
7231+		/*
7232+		 * Create a session object from it so that when calling
7233+		 * pk11_get_public_rsa_key() the next time, we can find it. The
7234+		 * reason why we do that is that we cannot tell from the RSA
7235+		 * structure (OpenSSL RSA structure does not have any room for
7236+		 * additional data used by the engine, for example) if it bears
7237+		 * a public key stored in the keystore or not so it's better if
7238+		 * we always have a session key. Note that this is different
7239+		 * from what we do for the private keystore objects but in that
7240+		 * case, we can tell from the RSA structure that the keystore
7241+		 * object is in play - the 'd' component is NULL in that case.
7242+		 */
7243+		h_pub_key = sp->opdata_rsa_pub_key =
7244+		    pk11_get_public_rsa_key(rsa,
7245+		    &sp->opdata_rsa_pub, &sp->opdata_rsa_n_num,
7246+		    &sp->opdata_rsa_e_num, sp->session);
7247+		if (h_pub_key == CK_INVALID_HANDLE)
7248+			goto err;
7249+		}
7250+	else if ((pubkey = fopen(pubkey_file, read_mode_flags)) != NULL)
7251+		{
7252+		pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL);
7253+		(void) fclose(pubkey);
7254+		if (pkey != NULL)
7255+			{
7256+			rsa = EVP_PKEY_get1_RSA(pkey);
7257+			if (rsa != NULL)
7258+				{
7259+				/*
7260+				 * This will always destroy the RSA
7261+				 * object since we have a new RSA
7262+				 * structure here.
7263+				 */
7264+				(void) check_new_rsa_key_pub(sp, rsa);
7265+				sp->pub_persistent = CK_FALSE;
7266+
7267+				h_pub_key = sp->opdata_rsa_pub_key =
7268+				    pk11_get_public_rsa_key(rsa,
7269+				    &sp->opdata_rsa_pub, &sp->opdata_rsa_n_num,
7270+				    &sp->opdata_rsa_e_num, sp->session);
7271+				if (h_pub_key == CK_INVALID_HANDLE)
7272+					goto err;
7273+				}
7274+			else
7275+				goto err;
7276+			}
7277+		}
7278+
7279+	pk11_return_session(sp, OP_RSA);
7280+	return (pkey);
7281+err:
7282+	pk11_return_session(sp, OP_RSA);
7283+	if (rsa != NULL)
7284+		RSA_free(rsa);
7285+	if (pkey != NULL)
7286+		{
7287+		EVP_PKEY_free(pkey);
7288+		pkey = NULL;
7289+		}
7290+	return (pkey);
7291+	}
7292+
7293+/*
7294+ * Create a public key object in a session from a given rsa structure.
7295+ * The *rsa_n_num and *rsa_e_num pointers are non-NULL for RSA public keys.
7296+ */
7297+static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA *rsa,
7298+    RSA **key_ptr, BIGNUM **rsa_n_num, BIGNUM **rsa_e_num,
7299+    CK_SESSION_HANDLE session)
7300+	{
7301+	CK_RV rv;
7302+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
7303+	CK_ULONG found;
7304+	CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
7305+	CK_KEY_TYPE k_type = CKK_RSA;
7306+	CK_ULONG ul_key_attr_count = 8;
7307+	CK_BBOOL rollback = FALSE;
7308+
7309+	CK_ATTRIBUTE  a_key_template[] =
7310+		{
7311+		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
7312+		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
7313+		{CKA_TOKEN, &myfalse, sizeof (myfalse)},
7314+		{CKA_ENCRYPT, &mytrue, sizeof (mytrue)},
7315+		{CKA_VERIFY, &mytrue, sizeof (mytrue)},
7316+		{CKA_VERIFY_RECOVER, &mytrue, sizeof (mytrue)},
7317+		{CKA_MODULUS, (void *)NULL, 0},
7318+		{CKA_PUBLIC_EXPONENT, (void *)NULL, 0}
7319+		};
7320+
7321+	int i;
7322+
7323+	a_key_template[0].pValue = &o_key;
7324+	a_key_template[1].pValue = &k_type;
7325+
7326+	a_key_template[6].ulValueLen = BN_num_bytes(rsa->n);
7327+	a_key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
7328+		(size_t)a_key_template[6].ulValueLen);
7329+	if (a_key_template[6].pValue == NULL)
7330+		{
7331+		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
7332+		goto malloc_err;
7333+		}
7334+
7335+	BN_bn2bin(rsa->n, a_key_template[6].pValue);
7336+
7337+	a_key_template[7].ulValueLen = BN_num_bytes(rsa->e);
7338+	a_key_template[7].pValue = (CK_VOID_PTR)OPENSSL_malloc(
7339+		(size_t)a_key_template[7].ulValueLen);
7340+	if (a_key_template[7].pValue == NULL)
7341+		{
7342+		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
7343+		goto malloc_err;
7344+		}
7345+
7346+	BN_bn2bin(rsa->e, a_key_template[7].pValue);
7347+
7348+	/* see find_lock array definition for more info on object locking */
7349+	LOCK_OBJSTORE(OP_RSA);
7350+
7351+	rv = pFuncList->C_FindObjectsInit(session, a_key_template,
7352+		ul_key_attr_count);
7353+
7354+	if (rv != CKR_OK)
7355+		{
7356+		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
7357+		    PK11_R_FINDOBJECTSINIT, rv);
7358+		goto err;
7359+		}
7360+
7361+	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
7362+
7363+	if (rv != CKR_OK)
7364+		{
7365+		(void) pFuncList->C_FindObjectsFinal(session);
7366+		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
7367+		    PK11_R_FINDOBJECTS, rv);
7368+		goto err;
7369+		}
7370+
7371+	rv = pFuncList->C_FindObjectsFinal(session);
7372+
7373+	if (rv != CKR_OK)
7374+		{
7375+		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
7376+		    PK11_R_FINDOBJECTSFINAL, rv);
7377+		goto err;
7378+		}
7379+
7380+	if (found == 0)
7381+		{
7382+		rv = pFuncList->C_CreateObject(session,
7383+			a_key_template, ul_key_attr_count, &h_key);
7384+		if (rv != CKR_OK)
7385+			{
7386+			PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
7387+			    PK11_R_CREATEOBJECT, rv);
7388+			goto err;
7389+			}
7390+		}
7391+
7392+	if (rsa_n_num != NULL)
7393+		if ((*rsa_n_num = BN_dup(rsa->n)) == NULL)
7394+			{
7395+			PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
7396+			rollback = TRUE;
7397+			goto err;
7398+			}
7399+	if (rsa_e_num != NULL)
7400+		if ((*rsa_e_num = BN_dup(rsa->e)) == NULL)
7401+			{
7402+			PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
7403+			BN_free(*rsa_n_num);
7404+			*rsa_n_num = NULL;
7405+			rollback = TRUE;
7406+			goto err;
7407+			}
7408+
7409+	/* LINTED: E_CONSTANT_CONDITION */
7410+	KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
7411+	if (key_ptr != NULL)
7412+		*key_ptr = rsa;
7413+
7414+err:
7415+	if (rollback)
7416+		{
7417+		/*
7418+		 * We do not care about the return value from C_DestroyObject()
7419+		 * since we are doing rollback.
7420+		 */
7421+		if (found == 0)
7422+			(void) pFuncList->C_DestroyObject(session, h_key);
7423+		h_key = CK_INVALID_HANDLE;
7424+		}
7425+
7426+	UNLOCK_OBJSTORE(OP_RSA);
7427+
7428+malloc_err:
7429+	for (i = 6; i <= 7; i++)
7430+		{
7431+		if (a_key_template[i].pValue != NULL)
7432+			{
7433+			OPENSSL_free(a_key_template[i].pValue);
7434+			a_key_template[i].pValue = NULL;
7435+			}
7436+		}
7437+
7438+	return (h_key);
7439+	}
7440+
7441+/*
7442+ * Create a private key object in the session from a given rsa structure.
7443+ * The *rsa_d_num pointer is non-NULL for RSA private keys.
7444+ */
7445+static CK_OBJECT_HANDLE
7446+pk11_get_private_rsa_key(RSA *rsa, RSA **key_ptr, BIGNUM **rsa_d_num,
7447+    BIGNUM **rsa_n_num, BIGNUM **rsa_e_num, CK_SESSION_HANDLE session)
7448+	{
7449+	CK_RV rv;
7450+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
7451+	int i;
7452+	CK_ULONG found;
7453+	CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
7454+	CK_KEY_TYPE k_type = CKK_RSA;
7455+	CK_ULONG ul_key_attr_count = 14;
7456+	CK_BBOOL rollback = FALSE;
7457+
7458+	/* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys */
7459+	CK_ATTRIBUTE  a_key_template[] =
7460+		{
7461+		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
7462+		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
7463+		{CKA_TOKEN, &myfalse, sizeof (myfalse)},
7464+		{CKA_SENSITIVE, &myfalse, sizeof (myfalse)},
7465+		{CKA_DECRYPT, &mytrue, sizeof (mytrue)},
7466+		{CKA_SIGN, &mytrue, sizeof (mytrue)},
7467+		{CKA_MODULUS, (void *)NULL, 0},
7468+		{CKA_PUBLIC_EXPONENT, (void *)NULL, 0},
7469+		{CKA_PRIVATE_EXPONENT, (void *)NULL, 0},
7470+		{CKA_PRIME_1, (void *)NULL, 0},
7471+		{CKA_PRIME_2, (void *)NULL, 0},
7472+		{CKA_EXPONENT_1, (void *)NULL, 0},
7473+		{CKA_EXPONENT_2, (void *)NULL, 0},
7474+		{CKA_COEFFICIENT, (void *)NULL, 0},
7475+		};
7476+
7477+	if ((rsa->flags & RSA_FLAG_EXT_PKEY) != 0) {
7478+		h_key = (CK_OBJECT_HANDLE)RSA_get_ex_data(rsa, hndidx_rsa);
7479+		LOCK_OBJSTORE(OP_RSA);
7480+		goto set;
7481+	}
7482+
7483+	a_key_template[0].pValue = &o_key;
7484+	a_key_template[1].pValue = &k_type;
7485+
7486+	/* Put the private key components into the template */
7487+	if (init_template_value(rsa->n, &a_key_template[6].pValue,
7488+		&a_key_template[6].ulValueLen) == 0 ||
7489+	    init_template_value(rsa->e, &a_key_template[7].pValue,
7490+		&a_key_template[7].ulValueLen) == 0 ||
7491+	    init_template_value(rsa->d, &a_key_template[8].pValue,
7492+		&a_key_template[8].ulValueLen) == 0 ||
7493+	    init_template_value(rsa->p, &a_key_template[9].pValue,
7494+		&a_key_template[9].ulValueLen) == 0 ||
7495+	    init_template_value(rsa->q, &a_key_template[10].pValue,
7496+		&a_key_template[10].ulValueLen) == 0 ||
7497+	    init_template_value(rsa->dmp1, &a_key_template[11].pValue,
7498+		&a_key_template[11].ulValueLen) == 0 ||
7499+	    init_template_value(rsa->dmq1, &a_key_template[12].pValue,
7500+		&a_key_template[12].ulValueLen) == 0 ||
7501+	    init_template_value(rsa->iqmp, &a_key_template[13].pValue,
7502+		&a_key_template[13].ulValueLen) == 0)
7503+		{
7504+		PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
7505+		goto malloc_err;
7506+		}
7507+
7508+	/* see find_lock array definition for more info on object locking */
7509+	LOCK_OBJSTORE(OP_RSA);
7510+
7511+	/*
7512+	 * We are getting the private key but the private 'd'
7513+	 * component is NULL.  That means this is key by reference RSA
7514+	 * key. In that case, we can use only public components for
7515+	 * searching for the private key handle.
7516+	 */
7517+	if (rsa->d == NULL)
7518+		{
7519+		ul_key_attr_count = 8;
7520+		/*
7521+		 * We will perform the search in the token, not in the existing
7522+		 * session keys.
7523+		 */
7524+		a_key_template[2].pValue = &mytrue;
7525+		}
7526+
7527+	rv = pFuncList->C_FindObjectsInit(session, a_key_template,
7528+		ul_key_attr_count);
7529+
7530+	if (rv != CKR_OK)
7531+		{
7532+		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7533+		    PK11_R_FINDOBJECTSINIT, rv);
7534+		goto err;
7535+		}
7536+
7537+	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
7538+
7539+	if (rv != CKR_OK)
7540+		{
7541+		(void) pFuncList->C_FindObjectsFinal(session);
7542+		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7543+		    PK11_R_FINDOBJECTS, rv);
7544+		goto err;
7545+		}
7546+
7547+	rv = pFuncList->C_FindObjectsFinal(session);
7548+
7549+	if (rv != CKR_OK)
7550+		{
7551+		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7552+		    PK11_R_FINDOBJECTSFINAL, rv);
7553+		goto err;
7554+		}
7555+
7556+	if (found == 0)
7557+		{
7558+		/*
7559+		 * We have an RSA structure with 'n'/'e' components
7560+		 * only so we tried to find the private key in the
7561+		 * keystore. If it was really a token key we have a
7562+		 * problem. Note that for other key types we just
7563+		 * create a new session key using the private
7564+		 * components from the RSA structure.
7565+		 */
7566+		if (rsa->d == NULL)
7567+			{
7568+			PK11err(PK11_F_GET_PRIV_RSA_KEY,
7569+			    PK11_R_PRIV_KEY_NOT_FOUND);
7570+			goto err;
7571+			}
7572+
7573+		rv = pFuncList->C_CreateObject(session,
7574+			a_key_template, ul_key_attr_count, &h_key);
7575+		if (rv != CKR_OK)
7576+			{
7577+			PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7578+				PK11_R_CREATEOBJECT, rv);
7579+			goto err;
7580+			}
7581+		}
7582+
7583+set:
7584+	if (rsa_d_num != NULL)
7585+		{
7586+		/*
7587+		 * When RSA keys by reference code is used, we never
7588+		 * extract private components from the keystore. In
7589+		 * that case 'd' was set to NULL and we expect the
7590+		 * application to properly cope with that. It is
7591+		 * documented in openssl(5). In general, if keys by
7592+		 * reference are used we expect it to be used
7593+		 * exclusively using the high level API and then there
7594+		 * is no problem. If the application expects the
7595+		 * private components to be read from the keystore
7596+		 * then that is not a supported way of usage.
7597+		 */
7598+		if (rsa->d != NULL && (*rsa_d_num = BN_dup(rsa->d)) == NULL)
7599+			{
7600+			PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
7601+			rollback = TRUE;
7602+			goto err;
7603+			}
7604+		else
7605+			*rsa_d_num = NULL;
7606+		}
7607+
7608+	/*
7609+	 * For the key by reference code, we need public components as well
7610+	 * since 'd' component is always NULL. For that reason, we always cache
7611+	 * 'n'/'e' components as well.
7612+	 */
7613+	*rsa_n_num = BN_dup(rsa->n);
7614+	*rsa_e_num = BN_dup(rsa->e);
7615+
7616+	/* LINTED: E_CONSTANT_CONDITION */
7617+	KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
7618+	if (key_ptr != NULL)
7619+		*key_ptr = rsa;
7620+
7621+err:
7622+	if (rollback)
7623+		{
7624+		/*
7625+		 * We do not care about the return value from C_DestroyObject()
7626+		 * since we are doing rollback.
7627+		 */
7628+		if (found == 0 &&
7629+		    (rsa->flags & RSA_FLAG_EXT_PKEY) == 0)
7630+			(void) pFuncList->C_DestroyObject(session, h_key);
7631+		h_key = CK_INVALID_HANDLE;
7632+		}
7633+
7634+	UNLOCK_OBJSTORE(OP_RSA);
7635+
7636+malloc_err:
7637+	/*
7638+	 * 6 to 13 entries in the key template are key components.
7639+	 * They need to be freed upon exit or error.
7640+	 */
7641+	for (i = 6; i <= 13; i++)
7642+		{
7643+		if (a_key_template[i].pValue != NULL)
7644+			{
7645+			(void) memset(a_key_template[i].pValue, 0,
7646+				a_key_template[i].ulValueLen);
7647+			OPENSSL_free(a_key_template[i].pValue);
7648+			a_key_template[i].pValue = NULL;
7649+			}
7650+		}
7651+
7652+	return (h_key);
7653+	}
7654+
7655+/*
7656+ * Check for cache miss and clean the object pointer and handle
7657+ * in such case. Return 1 for cache hit, 0 for cache miss.
7658+ */
7659+static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa)
7660+	{
7661+	/*
7662+	 * Provide protection against RSA structure reuse by making the
7663+	 * check for cache hit stronger. Only public components of RSA
7664+	 * key matter here so it is sufficient to compare them with values
7665+	 * cached in PK11_SESSION structure.
7666+	 *
7667+	 * We must check the handle as well since with key by reference, public
7668+	 * components 'n'/'e' are cached in private keys as well. That means we
7669+	 * could have a cache hit in a private key when looking for a public
7670+	 * key. That would not work, you cannot have one PKCS#11 object for
7671+	 * both data signing and verifying.
7672+	 */
7673+	if ((sp->opdata_rsa_pub != rsa) ||
7674+	    (BN_cmp(sp->opdata_rsa_n_num, rsa->n) != 0) ||
7675+	    (BN_cmp(sp->opdata_rsa_e_num, rsa->e) != 0) ||
7676+	    (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE))
7677+		{
7678+		/*
7679+		 * We do not check the return value because even in case of
7680+		 * failure the sp structure will have both key pointer
7681+		 * and object handle cleaned and pk11_destroy_object()
7682+		 * reports the failure to the OpenSSL error message buffer.
7683+		 */
7684+		(void) pk11_destroy_rsa_object_pub(sp, TRUE);
7685+		return (0);
7686+		}
7687+	return (1);
7688+	}
7689+
7690+/*
7691+ * Check for cache miss and clean the object pointer and handle
7692+ * in such case. Return 1 for cache hit, 0 for cache miss.
7693+ */
7694+static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa)
7695+	{
7696+	/*
7697+	 * Provide protection against RSA structure reuse by making
7698+	 * the check for cache hit stronger. Comparing public exponent
7699+	 * of RSA key with value cached in PK11_SESSION structure
7700+	 * should be sufficient. Note that we want to compare the
7701+	 * public component since with the keys by reference
7702+	 * mechanism, private components are not in the RSA
7703+	 * structure. Also, see check_new_rsa_key_pub() about why we
7704+	 * compare the handle as well.
7705+	 */
7706+	if ((sp->opdata_rsa_priv != rsa) ||
7707+	    (BN_cmp(sp->opdata_rsa_pn_num, rsa->n) != 0) ||
7708+	    (BN_cmp(sp->opdata_rsa_pe_num, rsa->e) != 0) ||
7709+	    (sp->opdata_rsa_pn_num == NULL) ||
7710+	    (sp->opdata_rsa_pe_num == NULL) ||
7711+	    (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE))
7712+		{
7713+		/*
7714+		 * We do not check the return value because even in case of
7715+		 * failure the sp structure will have both key pointer
7716+		 * and object handle cleaned and pk11_destroy_object()
7717+		 * reports the failure to the OpenSSL error message buffer.
7718+		 */
7719+		(void) pk11_destroy_rsa_object_priv(sp, TRUE);
7720+		return (0);
7721+		}
7722+	return (1);
7723+	}
7724+#endif
7725+
7726+#ifndef OPENSSL_NO_DSA
7727+/* The DSA function implementation */
7728+/* ARGSUSED */
7729+static int pk11_DSA_init(DSA *dsa)
7730+	{
7731+	return (1);
7732+	}
7733+
7734+/* ARGSUSED */
7735+static int pk11_DSA_finish(DSA *dsa)
7736+	{
7737+	return (1);
7738+	}
7739+
7740+
7741+static DSA_SIG *
7742+pk11_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
7743+	{
7744+	BIGNUM *r = NULL, *s = NULL;
7745+	int i;
7746+	DSA_SIG *dsa_sig = NULL;
7747+
7748+	CK_RV rv;
7749+	CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
7750+	CK_MECHANISM *p_mech = &Mechanism_dsa;
7751+	CK_OBJECT_HANDLE h_priv_key;
7752+
7753+	/*
7754+	 * The signature is the concatenation of r and s,
7755+	 * each is 20 bytes long
7756+	 */
7757+	unsigned char sigret[DSA_SIGNATURE_LEN];
7758+	unsigned long siglen = DSA_SIGNATURE_LEN;
7759+	unsigned int siglen2 = DSA_SIGNATURE_LEN / 2;
7760+
7761+	PK11_SESSION *sp = NULL;
7762+
7763+	if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
7764+		{
7765+		PK11err(PK11_F_DSA_SIGN, PK11_R_MISSING_KEY_COMPONENT);
7766+		goto ret;
7767+		}
7768+
7769+	i = BN_num_bytes(dsa->q); /* should be 20 */
7770+	if (dlen > i)
7771+		{
7772+		PK11err(PK11_F_DSA_SIGN, PK11_R_INVALID_SIGNATURE_LENGTH);
7773+		goto ret;
7774+		}
7775+
7776+	if ((sp = pk11_get_session(OP_DSA)) == NULL)
7777+		goto ret;
7778+
7779+	(void) check_new_dsa_key_priv(sp, dsa);
7780+
7781+	h_priv_key = sp->opdata_dsa_priv_key;
7782+	if (h_priv_key == CK_INVALID_HANDLE)
7783+		h_priv_key = sp->opdata_dsa_priv_key =
7784+			pk11_get_private_dsa_key((DSA *)dsa,
7785+			    &sp->opdata_dsa_priv,
7786+			    &sp->opdata_dsa_priv_num, sp->session);
7787+
7788+	if (h_priv_key != CK_INVALID_HANDLE)
7789+		{
7790+		rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
7791+
7792+		if (rv != CKR_OK)
7793+			{
7794+			PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGNINIT, rv);
7795+			goto ret;
7796+			}
7797+
7798+		(void) memset(sigret, 0, siglen);
7799+		rv = pFuncList->C_Sign(sp->session,
7800+			(unsigned char*) dgst, dlen, sigret,
7801+			(CK_ULONG_PTR) &siglen);
7802+
7803+		if (rv != CKR_OK)
7804+			{
7805+			PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGN, rv);
7806+			goto ret;
7807+			}
7808+		}
7809+
7810+
7811+	if ((s = BN_new()) == NULL)
7812+		{
7813+		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7814+		goto ret;
7815+		}
7816+
7817+	if ((r = BN_new()) == NULL)
7818+		{
7819+		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7820+		goto ret;
7821+		}
7822+
7823+	if ((dsa_sig = DSA_SIG_new()) == NULL)
7824+		{
7825+		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7826+		goto ret;
7827+		}
7828+
7829+	if (BN_bin2bn(sigret, siglen2, r) == NULL ||
7830+	    BN_bin2bn(&sigret[siglen2], siglen2, s) == NULL)
7831+		{
7832+		PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7833+		goto ret;
7834+		}
7835+
7836+	dsa_sig->r = r;
7837+	dsa_sig->s = s;
7838+
7839+ret:
7840+	if (dsa_sig == NULL)
7841+		{
7842+		if (r != NULL)
7843+			BN_free(r);
7844+		if (s != NULL)
7845+			BN_free(s);
7846+		}
7847+
7848+	pk11_return_session(sp, OP_DSA);
7849+	return (dsa_sig);
7850+	}
7851+
7852+static int
7853+pk11_dsa_do_verify(const unsigned char *dgst, int dlen, DSA_SIG *sig,
7854+	DSA *dsa)
7855+	{
7856+	int i;
7857+	CK_RV rv;
7858+	int retval = 0;
7859+	CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
7860+	CK_MECHANISM *p_mech = &Mechanism_dsa;
7861+	CK_OBJECT_HANDLE h_pub_key;
7862+
7863+	unsigned char sigbuf[DSA_SIGNATURE_LEN];
7864+	unsigned long siglen = DSA_SIGNATURE_LEN;
7865+	unsigned long siglen2 = DSA_SIGNATURE_LEN/2;
7866+
7867+	PK11_SESSION *sp = NULL;
7868+
7869+	if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0)
7870+		{
7871+		PK11err(PK11_F_DSA_VERIFY,
7872+			PK11_R_INVALID_DSA_SIGNATURE_R);
7873+		goto ret;
7874+		}
7875+
7876+	if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0)
7877+		{
7878+		PK11err(PK11_F_DSA_VERIFY,
7879+			PK11_R_INVALID_DSA_SIGNATURE_S);
7880+		goto ret;
7881+		}
7882+
7883+	i = BN_num_bytes(dsa->q); /* should be 20 */
7884+
7885+	if (dlen > i)
7886+		{
7887+		PK11err(PK11_F_DSA_VERIFY,
7888+			PK11_R_INVALID_SIGNATURE_LENGTH);
7889+		goto ret;
7890+		}
7891+
7892+	if ((sp = pk11_get_session(OP_DSA)) == NULL)
7893+		goto ret;
7894+
7895+	(void) check_new_dsa_key_pub(sp, dsa);
7896+
7897+	h_pub_key = sp->opdata_dsa_pub_key;
7898+	if (h_pub_key == CK_INVALID_HANDLE)
7899+		h_pub_key = sp->opdata_dsa_pub_key =
7900+			pk11_get_public_dsa_key((DSA *)dsa, &sp->opdata_dsa_pub,
7901+			    &sp->opdata_dsa_pub_num, sp->session);
7902+
7903+	if (h_pub_key != CK_INVALID_HANDLE)
7904+		{
7905+		rv = pFuncList->C_VerifyInit(sp->session, p_mech,
7906+			h_pub_key);
7907+
7908+		if (rv != CKR_OK)
7909+			{
7910+			PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFYINIT,
7911+			    rv);
7912+			goto ret;
7913+			}
7914+
7915+		/*
7916+		 * The representation of each of the two big numbers could
7917+		 * be shorter than DSA_SIGNATURE_LEN/2 bytes so we need
7918+		 * to act accordingly and shift if necessary.
7919+		 */
7920+		(void) memset(sigbuf, 0, siglen);
7921+		BN_bn2bin(sig->r, sigbuf + siglen2 - BN_num_bytes(sig->r));
7922+		BN_bn2bin(sig->s, &sigbuf[siglen2] + siglen2 -
7923+		    BN_num_bytes(sig->s));
7924+
7925+		rv = pFuncList->C_Verify(sp->session,
7926+			(unsigned char *) dgst, dlen, sigbuf, (CK_ULONG)siglen);
7927+
7928+		if (rv != CKR_OK)
7929+			{
7930+			PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFY, rv);
7931+			goto ret;
7932+			}
7933+		}
7934+
7935+	retval = 1;
7936+ret:
7937+
7938+	pk11_return_session(sp, OP_DSA);
7939+	return (retval);
7940+	}
7941+
7942+
7943+/*
7944+ * Create a public key object in a session from a given dsa structure.
7945+ * The *dsa_pub_num pointer is non-NULL for DSA public keys.
7946+ */
7947+static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa,
7948+    DSA **key_ptr, BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session)
7949+	{
7950+	CK_RV rv;
7951+	CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
7952+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
7953+	CK_ULONG found;
7954+	CK_KEY_TYPE k_type = CKK_DSA;
7955+	CK_ULONG ul_key_attr_count = 8;
7956+	CK_BBOOL rollback = FALSE;
7957+	int i;
7958+
7959+	CK_ATTRIBUTE  a_key_template[] =
7960+		{
7961+		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
7962+		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
7963+		{CKA_TOKEN, &myfalse, sizeof (myfalse)},
7964+		{CKA_VERIFY, &mytrue, sizeof (mytrue)},
7965+		{CKA_PRIME, (void *)NULL, 0},		/* p */
7966+		{CKA_SUBPRIME, (void *)NULL, 0},	/* q */
7967+		{CKA_BASE, (void *)NULL, 0},		/* g */
7968+		{CKA_VALUE, (void *)NULL, 0}		/* pub_key - y */
7969+		};
7970+
7971+	a_key_template[0].pValue = &o_key;
7972+	a_key_template[1].pValue = &k_type;
7973+
7974+	if (init_template_value(dsa->p, &a_key_template[4].pValue,
7975+		&a_key_template[4].ulValueLen) == 0 ||
7976+	    init_template_value(dsa->q, &a_key_template[5].pValue,
7977+		&a_key_template[5].ulValueLen) == 0 ||
7978+	    init_template_value(dsa->g, &a_key_template[6].pValue,
7979+		&a_key_template[6].ulValueLen) == 0 ||
7980+	    init_template_value(dsa->pub_key, &a_key_template[7].pValue,
7981+		&a_key_template[7].ulValueLen) == 0)
7982+		{
7983+		PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
7984+		goto malloc_err;
7985+		}
7986+
7987+	/* see find_lock array definition for more info on object locking */
7988+	LOCK_OBJSTORE(OP_DSA);
7989+	rv = pFuncList->C_FindObjectsInit(session, a_key_template,
7990+		ul_key_attr_count);
7991+
7992+	if (rv != CKR_OK)
7993+		{
7994+		PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
7995+		    PK11_R_FINDOBJECTSINIT, rv);
7996+		goto err;
7997+		}
7998+
7999+	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
8000+
8001+	if (rv != CKR_OK)
8002+		{
8003+		(void) pFuncList->C_FindObjectsFinal(session);
8004+		PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
8005+		    PK11_R_FINDOBJECTS, rv);
8006+		goto err;
8007+		}
8008+
8009+	rv = pFuncList->C_FindObjectsFinal(session);
8010+
8011+	if (rv != CKR_OK)
8012+		{
8013+		PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
8014+		    PK11_R_FINDOBJECTSFINAL, rv);
8015+		goto err;
8016+		}
8017+
8018+	if (found == 0)
8019+		{
8020+		rv = pFuncList->C_CreateObject(session,
8021+			a_key_template, ul_key_attr_count, &h_key);
8022+		if (rv != CKR_OK)
8023+			{
8024+			PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
8025+			    PK11_R_CREATEOBJECT, rv);
8026+			goto err;
8027+			}
8028+		}
8029+
8030+	if (dsa_pub_num != NULL)
8031+		if ((*dsa_pub_num = BN_dup(dsa->pub_key)) == NULL)
8032+			{
8033+			PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
8034+			rollback = TRUE;
8035+			goto err;
8036+			}
8037+
8038+	/* LINTED: E_CONSTANT_CONDITION */
8039+	KEY_HANDLE_REFHOLD(h_key, OP_DSA, FALSE, rollback, err);
8040+	if (key_ptr != NULL)
8041+		*key_ptr = dsa;
8042+
8043+err:
8044+	if (rollback)
8045+		{
8046+		/*
8047+		 * We do not care about the return value from C_DestroyObject()
8048+		 * since we are doing rollback.
8049+		 */
8050+		if (found == 0)
8051+			(void) pFuncList->C_DestroyObject(session, h_key);
8052+		h_key = CK_INVALID_HANDLE;
8053+		}
8054+
8055+	UNLOCK_OBJSTORE(OP_DSA);
8056+
8057+malloc_err:
8058+	for (i = 4; i <= 7; i++)
8059+		{
8060+		if (a_key_template[i].pValue != NULL)
8061+			{
8062+			OPENSSL_free(a_key_template[i].pValue);
8063+			a_key_template[i].pValue = NULL;
8064+			}
8065+		}
8066+
8067+	return (h_key);
8068+	}
8069+
8070+/*
8071+ * Create a private key object in the session from a given dsa structure
8072+ * The *dsa_priv_num pointer is non-NULL for DSA private keys.
8073+ */
8074+static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa,
8075+    DSA **key_ptr, BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session)
8076+	{
8077+	CK_RV rv;
8078+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
8079+	CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
8080+	int i;
8081+	CK_ULONG found;
8082+	CK_KEY_TYPE k_type = CKK_DSA;
8083+	CK_ULONG ul_key_attr_count = 9;
8084+	CK_BBOOL rollback = FALSE;
8085+
8086+	/* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys */
8087+	CK_ATTRIBUTE  a_key_template[] =
8088+		{
8089+		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
8090+		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
8091+		{CKA_TOKEN, &myfalse, sizeof (myfalse)},
8092+		{CKA_SENSITIVE, &myfalse, sizeof (myfalse)},
8093+		{CKA_SIGN, &mytrue, sizeof (mytrue)},
8094+		{CKA_PRIME, (void *)NULL, 0},		/* p */
8095+		{CKA_SUBPRIME, (void *)NULL, 0},	/* q */
8096+		{CKA_BASE, (void *)NULL, 0},		/* g */
8097+		{CKA_VALUE, (void *)NULL, 0}		/* priv_key - x */
8098+		};
8099+
8100+	a_key_template[0].pValue = &o_key;
8101+	a_key_template[1].pValue = &k_type;
8102+
8103+	/* Put the private key components into the template */
8104+	if (init_template_value(dsa->p, &a_key_template[5].pValue,
8105+		&a_key_template[5].ulValueLen) == 0 ||
8106+	    init_template_value(dsa->q, &a_key_template[6].pValue,
8107+		&a_key_template[6].ulValueLen) == 0 ||
8108+	    init_template_value(dsa->g, &a_key_template[7].pValue,
8109+		&a_key_template[7].ulValueLen) == 0 ||
8110+	    init_template_value(dsa->priv_key, &a_key_template[8].pValue,
8111+		&a_key_template[8].ulValueLen) == 0)
8112+		{
8113+		PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
8114+		goto malloc_err;
8115+		}
8116+
8117+	/* see find_lock array definition for more info on object locking */
8118+	LOCK_OBJSTORE(OP_DSA);
8119+	rv = pFuncList->C_FindObjectsInit(session, a_key_template,
8120+		ul_key_attr_count);
8121+
8122+	if (rv != CKR_OK)
8123+		{
8124+		PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
8125+		    PK11_R_FINDOBJECTSINIT, rv);
8126+		goto err;
8127+		}
8128+
8129+	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
8130+
8131+	if (rv != CKR_OK)
8132+		{
8133+		(void) pFuncList->C_FindObjectsFinal(session);
8134+		PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
8135+		    PK11_R_FINDOBJECTS, rv);
8136+		goto err;
8137+		}
8138+
8139+	rv = pFuncList->C_FindObjectsFinal(session);
8140+
8141+	if (rv != CKR_OK)
8142+		{
8143+		PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
8144+		    PK11_R_FINDOBJECTSFINAL, rv);
8145+		goto err;
8146+		}
8147+
8148+	if (found == 0)
8149+		{
8150+		rv = pFuncList->C_CreateObject(session,
8151+			a_key_template, ul_key_attr_count, &h_key);
8152+		if (rv != CKR_OK)
8153+			{
8154+			PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
8155+			    PK11_R_CREATEOBJECT, rv);
8156+			goto err;
8157+			}
8158+		}
8159+
8160+	if (dsa_priv_num != NULL)
8161+		if ((*dsa_priv_num = BN_dup(dsa->priv_key)) == NULL)
8162+			{
8163+			PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
8164+			rollback = TRUE;
8165+			goto err;
8166+			}
8167+
8168+	/* LINTED: E_CONSTANT_CONDITION */
8169+	KEY_HANDLE_REFHOLD(h_key, OP_DSA, FALSE, rollback, err);
8170+	if (key_ptr != NULL)
8171+		*key_ptr = dsa;
8172+
8173+err:
8174+	if (rollback)
8175+		{
8176+		/*
8177+		 * We do not care about the return value from C_DestroyObject()
8178+		 * since we are doing rollback.
8179+		 */
8180+		if (found == 0)
8181+			(void) pFuncList->C_DestroyObject(session, h_key);
8182+		h_key = CK_INVALID_HANDLE;
8183+		}
8184+
8185+	UNLOCK_OBJSTORE(OP_DSA);
8186+
8187+malloc_err:
8188+	/*
8189+	 * 5 to 8 entries in the key template are key components.
8190+	 * They need to be freed apon exit or error.
8191+	 */
8192+	for (i = 5; i <= 8; i++)
8193+		{
8194+		if (a_key_template[i].pValue != NULL)
8195+			{
8196+			(void) memset(a_key_template[i].pValue, 0,
8197+				a_key_template[i].ulValueLen);
8198+			OPENSSL_free(a_key_template[i].pValue);
8199+			a_key_template[i].pValue = NULL;
8200+			}
8201+		}
8202+
8203+	return (h_key);
8204+	}
8205+
8206+/*
8207+ * Check for cache miss and clean the object pointer and handle
8208+ * in such case. Return 1 for cache hit, 0 for cache miss.
8209+ */
8210+static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa)
8211+	{
8212+	/*
8213+	 * Provide protection against DSA structure reuse by making the
8214+	 * check for cache hit stronger. Only public key component of DSA
8215+	 * key matters here so it is sufficient to compare it with value
8216+	 * cached in PK11_SESSION structure.
8217+	 */
8218+	if ((sp->opdata_dsa_pub != dsa) ||
8219+	    (BN_cmp(sp->opdata_dsa_pub_num, dsa->pub_key) != 0))
8220+		{
8221+		/*
8222+		 * We do not check the return value because even in case of
8223+		 * failure the sp structure will have both key pointer
8224+		 * and object handle cleaned and pk11_destroy_object()
8225+		 * reports the failure to the OpenSSL error message buffer.
8226+		 */
8227+		(void) pk11_destroy_dsa_object_pub(sp, TRUE);
8228+		return (0);
8229+		}
8230+	return (1);
8231+	}
8232+
8233+/*
8234+ * Check for cache miss and clean the object pointer and handle
8235+ * in such case. Return 1 for cache hit, 0 for cache miss.
8236+ */
8237+static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa)
8238+	{
8239+	/*
8240+	 * Provide protection against DSA structure reuse by making the
8241+	 * check for cache hit stronger. Only private key component of DSA
8242+	 * key matters here so it is sufficient to compare it with value
8243+	 * cached in PK11_SESSION structure.
8244+	 */
8245+	if ((sp->opdata_dsa_priv != dsa) ||
8246+	    (BN_cmp(sp->opdata_dsa_priv_num, dsa->priv_key) != 0))
8247+		{
8248+		/*
8249+		 * We do not check the return value because even in case of
8250+		 * failure the sp structure will have both key pointer
8251+		 * and object handle cleaned and pk11_destroy_object()
8252+		 * reports the failure to the OpenSSL error message buffer.
8253+		 */
8254+		(void) pk11_destroy_dsa_object_priv(sp, TRUE);
8255+		return (0);
8256+		}
8257+	return (1);
8258+	}
8259+#endif
8260+
8261+
8262+#ifndef OPENSSL_NO_DH
8263+/* The DH function implementation */
8264+/* ARGSUSED */
8265+static int pk11_DH_init(DH *dh)
8266+	{
8267+	return (1);
8268+	}
8269+
8270+/* ARGSUSED */
8271+static int pk11_DH_finish(DH *dh)
8272+	{
8273+	return (1);
8274+	}
8275+
8276+/*
8277+ * Generate DH key-pair.
8278+ *
8279+ * Warning: Unlike OpenSSL's DH_generate_key(3) we ignore dh->priv_key
8280+ * and override it even if it is set. OpenSSL does not touch dh->priv_key
8281+ * if set and just computes dh->pub_key. It looks like PKCS#11 standard
8282+ * is not capable of providing this functionality. This could be a problem
8283+ * for applications relying on OpenSSL's semantics.
8284+ */
8285+static int pk11_DH_generate_key(DH *dh)
8286+	{
8287+	CK_ULONG i;
8288+	CK_RV rv, rv1;
8289+	int reuse_mem_len = 0, ret = 0;
8290+	PK11_SESSION *sp = NULL;
8291+	CK_BYTE_PTR reuse_mem;
8292+
8293+	CK_MECHANISM mechanism = {CKM_DH_PKCS_KEY_PAIR_GEN, NULL_PTR, 0};
8294+	CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
8295+	CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
8296+
8297+	CK_ULONG ul_pub_key_attr_count = 3;
8298+	CK_ATTRIBUTE pub_key_template[] =
8299+		{
8300+		{CKA_PRIVATE, &myfalse, sizeof (myfalse)},
8301+		{CKA_PRIME, (void *)NULL, 0},
8302+		{CKA_BASE, (void *)NULL, 0}
8303+		};
8304+
8305+	CK_ULONG ul_priv_key_attr_count = 3;
8306+	CK_ATTRIBUTE priv_key_template[] =
8307+		{
8308+		{CKA_PRIVATE, &myfalse, sizeof (myfalse)},
8309+		{CKA_SENSITIVE, &myfalse, sizeof (myfalse)},
8310+		{CKA_DERIVE, &mytrue, sizeof (mytrue)}
8311+		};
8312+
8313+	CK_ULONG pub_key_attr_result_count = 1;
8314+	CK_ATTRIBUTE pub_key_result[] =
8315+		{
8316+		{CKA_VALUE, (void *)NULL, 0}
8317+		};
8318+
8319+	CK_ULONG priv_key_attr_result_count = 1;
8320+	CK_ATTRIBUTE priv_key_result[] =
8321+		{
8322+		{CKA_VALUE, (void *)NULL, 0}
8323+		};
8324+
8325+	pub_key_template[1].ulValueLen = BN_num_bytes(dh->p);
8326+	if (pub_key_template[1].ulValueLen > 0)
8327+		{
8328+		/*
8329+		 * We must not increase ulValueLen by DH_BUF_RESERVE since that
8330+		 * could cause the same rounding problem. See definition of
8331+		 * DH_BUF_RESERVE above.
8332+		 */
8333+		pub_key_template[1].pValue =
8334+			OPENSSL_malloc(pub_key_template[1].ulValueLen +
8335+			DH_BUF_RESERVE);
8336+		if (pub_key_template[1].pValue == NULL)
8337+			{
8338+			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
8339+			goto err;
8340+			}
8341+
8342+		i = BN_bn2bin(dh->p, pub_key_template[1].pValue);
8343+		}
8344+	else
8345+		goto err;
8346+
8347+	pub_key_template[2].ulValueLen = BN_num_bytes(dh->g);
8348+	if (pub_key_template[2].ulValueLen > 0)
8349+		{
8350+		pub_key_template[2].pValue =
8351+			OPENSSL_malloc(pub_key_template[2].ulValueLen +
8352+			DH_BUF_RESERVE);
8353+		if (pub_key_template[2].pValue == NULL)
8354+			{
8355+			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
8356+			goto err;
8357+			}
8358+
8359+		i = BN_bn2bin(dh->g, pub_key_template[2].pValue);
8360+		}
8361+	else
8362+		goto err;
8363+
8364+	/*
8365+	 * Note: we are only using PK11_SESSION structure for getting
8366+	 *	 a session handle. The objects created in this function are
8367+	 *	 destroyed before return and thus not cached.
8368+	 */
8369+	if ((sp = pk11_get_session(OP_DH)) == NULL)
8370+		goto err;
8371+
8372+	rv = pFuncList->C_GenerateKeyPair(sp->session,
8373+	    &mechanism,
8374+	    pub_key_template,
8375+	    ul_pub_key_attr_count,
8376+	    priv_key_template,
8377+	    ul_priv_key_attr_count,
8378+	    &h_pub_key,
8379+	    &h_priv_key);
8380+	if (rv != CKR_OK)
8381+		{
8382+		PK11err_add_data(PK11_F_DH_GEN_KEY, PK11_R_GEN_KEY, rv);
8383+		goto err;
8384+		}
8385+
8386+	/*
8387+	 * Reuse the larger memory allocated. We know the larger memory
8388+	 * should be sufficient for reuse.
8389+	 */
8390+	if (pub_key_template[1].ulValueLen > pub_key_template[2].ulValueLen)
8391+		{
8392+		reuse_mem = pub_key_template[1].pValue;
8393+		reuse_mem_len = pub_key_template[1].ulValueLen + DH_BUF_RESERVE;
8394+		}
8395+	else
8396+		{
8397+		reuse_mem = pub_key_template[2].pValue;
8398+		reuse_mem_len = pub_key_template[2].ulValueLen + DH_BUF_RESERVE;
8399+		}
8400+
8401+	rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
8402+		pub_key_result, pub_key_attr_result_count);
8403+	rv1 = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
8404+		priv_key_result, priv_key_attr_result_count);
8405+
8406+	if (rv != CKR_OK || rv1 != CKR_OK)
8407+		{
8408+		rv = (rv != CKR_OK) ? rv : rv1;
8409+		PK11err_add_data(PK11_F_DH_GEN_KEY,
8410+		    PK11_R_GETATTRIBUTVALUE, rv);
8411+		goto err;
8412+		}
8413+
8414+	if (((CK_LONG) pub_key_result[0].ulValueLen) <= 0 ||
8415+		((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
8416+		{
8417+		PK11err(PK11_F_DH_GEN_KEY, PK11_R_GETATTRIBUTVALUE);
8418+		goto err;
8419+		}
8420+
8421+	/* Reuse the memory allocated */
8422+	pub_key_result[0].pValue = reuse_mem;
8423+	pub_key_result[0].ulValueLen = reuse_mem_len;
8424+
8425+	rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
8426+		pub_key_result, pub_key_attr_result_count);
8427+
8428+	if (rv != CKR_OK)
8429+		{
8430+		PK11err_add_data(PK11_F_DH_GEN_KEY,
8431+		    PK11_R_GETATTRIBUTVALUE, rv);
8432+		goto err;
8433+		}
8434+
8435+	if (pub_key_result[0].type == CKA_VALUE)
8436+		{
8437+		if (dh->pub_key == NULL)
8438+			if ((dh->pub_key = BN_new()) == NULL)
8439+				{
8440+				PK11err(PK11_F_DH_GEN_KEY,
8441+					PK11_R_MALLOC_FAILURE);
8442+				goto err;
8443+				}
8444+		dh->pub_key = BN_bin2bn(pub_key_result[0].pValue,
8445+			pub_key_result[0].ulValueLen, dh->pub_key);
8446+		if (dh->pub_key == NULL)
8447+			{
8448+			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
8449+			goto err;
8450+			}
8451+		}
8452+
8453+	/* Reuse the memory allocated */
8454+	priv_key_result[0].pValue = reuse_mem;
8455+	priv_key_result[0].ulValueLen = reuse_mem_len;
8456+
8457+	rv = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
8458+		priv_key_result, priv_key_attr_result_count);
8459+
8460+	if (rv != CKR_OK)
8461+		{
8462+		PK11err_add_data(PK11_F_DH_GEN_KEY,
8463+		    PK11_R_GETATTRIBUTVALUE, rv);
8464+		goto err;
8465+		}
8466+
8467+	if (priv_key_result[0].type == CKA_VALUE)
8468+		{
8469+		if (dh->priv_key == NULL)
8470+			if ((dh->priv_key = BN_new()) == NULL)
8471+				{
8472+				PK11err(PK11_F_DH_GEN_KEY,
8473+					PK11_R_MALLOC_FAILURE);
8474+				goto err;
8475+				}
8476+		dh->priv_key = BN_bin2bn(priv_key_result[0].pValue,
8477+			priv_key_result[0].ulValueLen, dh->priv_key);
8478+		if (dh->priv_key == NULL)
8479+			{
8480+			PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
8481+			goto err;
8482+			}
8483+		}
8484+
8485+	ret = 1;
8486+
8487+err:
8488+
8489+	if (h_pub_key != CK_INVALID_HANDLE)
8490+		{
8491+		rv = pFuncList->C_DestroyObject(sp->session, h_pub_key);
8492+		if (rv != CKR_OK)
8493+			{
8494+			PK11err_add_data(PK11_F_DH_GEN_KEY,
8495+			    PK11_R_DESTROYOBJECT, rv);
8496+			}
8497+		}
8498+
8499+	if (h_priv_key != CK_INVALID_HANDLE)
8500+		{
8501+		rv = pFuncList->C_DestroyObject(sp->session, h_priv_key);
8502+		if (rv != CKR_OK)
8503+			{
8504+			PK11err_add_data(PK11_F_DH_GEN_KEY,
8505+			    PK11_R_DESTROYOBJECT, rv);
8506+			}
8507+		}
8508+
8509+	for (i = 1; i <= 2; i++)
8510+		{
8511+		if (pub_key_template[i].pValue != NULL)
8512+			{
8513+			OPENSSL_free(pub_key_template[i].pValue);
8514+			pub_key_template[i].pValue = NULL;
8515+			}
8516+		}
8517+
8518+	pk11_return_session(sp, OP_DH);
8519+	return (ret);
8520+	}
8521+
8522+static int pk11_DH_compute_key(unsigned char *key, const BIGNUM *pub_key,
8523+	DH *dh)
8524+	{
8525+	unsigned int i;
8526+	CK_MECHANISM mechanism = {CKM_DH_PKCS_DERIVE, NULL_PTR, 0};
8527+	CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
8528+	CK_KEY_TYPE key_type = CKK_GENERIC_SECRET;
8529+	CK_OBJECT_HANDLE h_derived_key = CK_INVALID_HANDLE;
8530+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
8531+
8532+	CK_ULONG seclen;
8533+	CK_ULONG ul_priv_key_attr_count = 3;
8534+	CK_ATTRIBUTE priv_key_template[] =
8535+		{
8536+		{CKA_CLASS, (void*) NULL, sizeof (key_class)},
8537+		{CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
8538+		{CKA_VALUE_LEN, &seclen, sizeof (seclen)},
8539+		};
8540+
8541+	CK_ULONG priv_key_attr_result_count = 1;
8542+	CK_ATTRIBUTE priv_key_result[] =
8543+		{
8544+		{CKA_VALUE, (void *)NULL, 0}
8545+		};
8546+
8547+	CK_RV rv;
8548+	int ret = -1;
8549+	PK11_SESSION *sp = NULL;
8550+
8551+	if (dh->priv_key == NULL)
8552+		goto err;
8553+
8554+	priv_key_template[0].pValue = &key_class;
8555+	priv_key_template[1].pValue = &key_type;
8556+	seclen = BN_num_bytes(dh->p);
8557+
8558+	if ((sp = pk11_get_session(OP_DH)) == NULL)
8559+		goto err;
8560+
8561+	mechanism.ulParameterLen = BN_num_bytes(pub_key);
8562+	mechanism.pParameter = OPENSSL_malloc(mechanism.ulParameterLen);
8563+	if (mechanism.pParameter == NULL)
8564+		{
8565+		PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
8566+		goto err;
8567+		}
8568+	BN_bn2bin(pub_key, mechanism.pParameter);
8569+
8570+	(void) check_new_dh_key(sp, dh);
8571+
8572+	h_key = sp->opdata_dh_key;
8573+	if (h_key == CK_INVALID_HANDLE)
8574+		h_key = sp->opdata_dh_key =
8575+			pk11_get_dh_key((DH*) dh, &sp->opdata_dh,
8576+			    &sp->opdata_dh_priv_num, sp->session);
8577+
8578+	if (h_key == CK_INVALID_HANDLE)
8579+		{
8580+		PK11err(PK11_F_DH_COMP_KEY, PK11_R_CREATEOBJECT);
8581+		goto err;
8582+		}
8583+
8584+	rv = pFuncList->C_DeriveKey(sp->session,
8585+	    &mechanism,
8586+	    h_key,
8587+	    priv_key_template,
8588+	    ul_priv_key_attr_count,
8589+	    &h_derived_key);
8590+	if (rv != CKR_OK)
8591+		{
8592+		PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_DERIVEKEY, rv);
8593+		goto err;
8594+		}
8595+
8596+	rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
8597+	    priv_key_result, priv_key_attr_result_count);
8598+
8599+	if (rv != CKR_OK)
8600+		{
8601+		PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
8602+		    rv);
8603+		goto err;
8604+		}
8605+
8606+	if (((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
8607+		{
8608+		PK11err(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE);
8609+		goto err;
8610+		}
8611+	priv_key_result[0].pValue =
8612+		OPENSSL_malloc(priv_key_result[0].ulValueLen);
8613+	if (!priv_key_result[0].pValue)
8614+		{
8615+		PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
8616+		goto err;
8617+		}
8618+
8619+	rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
8620+		priv_key_result, priv_key_attr_result_count);
8621+
8622+	if (rv != CKR_OK)
8623+		{
8624+		PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
8625+		    rv);
8626+		goto err;
8627+		}
8628+
8629+	/*
8630+	 * OpenSSL allocates the output buffer 'key' which is the same
8631+	 * length of the public key. It is long enough for the derived key
8632+	 */
8633+	if (priv_key_result[0].type == CKA_VALUE)
8634+		{
8635+		/*
8636+		 * CKM_DH_PKCS_DERIVE mechanism is not supposed to strip
8637+		 * leading zeros from a computed shared secret. However,
8638+		 * OpenSSL always did it so we must do the same here. The
8639+		 * vagueness of the spec regarding leading zero bytes was
8640+		 * finally cleared with TLS 1.1 (RFC 4346) saying that leading
8641+		 * zeros are stripped before the computed data is used as the
8642+		 * pre-master secret.
8643+		 */
8644+		for (i = 0; i < priv_key_result[0].ulValueLen; ++i)
8645+			{
8646+			if (((char *)priv_key_result[0].pValue)[i] != 0)
8647+				break;
8648+			}
8649+
8650+		(void) memcpy(key, ((char *)priv_key_result[0].pValue) + i,
8651+			priv_key_result[0].ulValueLen - i);
8652+		ret = priv_key_result[0].ulValueLen - i;
8653+		}
8654+
8655+err:
8656+
8657+	if (h_derived_key != CK_INVALID_HANDLE)
8658+		{
8659+		rv = pFuncList->C_DestroyObject(sp->session, h_derived_key);
8660+		if (rv != CKR_OK)
8661+			{
8662+			PK11err_add_data(PK11_F_DH_COMP_KEY,
8663+			    PK11_R_DESTROYOBJECT, rv);
8664+			}
8665+		}
8666+	if (priv_key_result[0].pValue)
8667+		{
8668+		OPENSSL_free(priv_key_result[0].pValue);
8669+		priv_key_result[0].pValue = NULL;
8670+		}
8671+
8672+	if (mechanism.pParameter)
8673+		{
8674+		OPENSSL_free(mechanism.pParameter);
8675+		mechanism.pParameter = NULL;
8676+		}
8677+
8678+	pk11_return_session(sp, OP_DH);
8679+	return (ret);
8680+	}
8681+
8682+
8683+static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh,
8684+	DH **key_ptr, BIGNUM **dh_priv_num, CK_SESSION_HANDLE session)
8685+	{
8686+	CK_RV rv;
8687+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
8688+	CK_OBJECT_CLASS class = CKO_PRIVATE_KEY;
8689+	CK_KEY_TYPE key_type = CKK_DH;
8690+	CK_ULONG found;
8691+	CK_BBOOL rollback = FALSE;
8692+	int i;
8693+
8694+	CK_ULONG ul_key_attr_count = 7;
8695+	CK_ATTRIBUTE key_template[] =
8696+		{
8697+		{CKA_CLASS, (void*) NULL, sizeof (class)},
8698+		{CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
8699+		{CKA_DERIVE, &mytrue, sizeof (mytrue)},
8700+		{CKA_PRIVATE, &myfalse, sizeof (myfalse)},
8701+		{CKA_PRIME, (void *) NULL, 0},
8702+		{CKA_BASE, (void *) NULL, 0},
8703+		{CKA_VALUE, (void *) NULL, 0},
8704+		};
8705+
8706+	key_template[0].pValue = &class;
8707+	key_template[1].pValue = &key_type;
8708+
8709+	key_template[4].ulValueLen = BN_num_bytes(dh->p);
8710+	key_template[4].pValue = (CK_VOID_PTR)OPENSSL_malloc(
8711+		(size_t)key_template[4].ulValueLen);
8712+	if (key_template[4].pValue == NULL)
8713+		{
8714+		PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8715+		goto malloc_err;
8716+		}
8717+
8718+	BN_bn2bin(dh->p, key_template[4].pValue);
8719+
8720+	key_template[5].ulValueLen = BN_num_bytes(dh->g);
8721+	key_template[5].pValue = (CK_VOID_PTR)OPENSSL_malloc(
8722+		(size_t)key_template[5].ulValueLen);
8723+	if (key_template[5].pValue == NULL)
8724+		{
8725+		PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8726+		goto malloc_err;
8727+		}
8728+
8729+	BN_bn2bin(dh->g, key_template[5].pValue);
8730+
8731+	key_template[6].ulValueLen = BN_num_bytes(dh->priv_key);
8732+	key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
8733+		(size_t)key_template[6].ulValueLen);
8734+	if (key_template[6].pValue == NULL)
8735+		{
8736+		PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8737+		goto malloc_err;
8738+		}
8739+
8740+	BN_bn2bin(dh->priv_key, key_template[6].pValue);
8741+
8742+	/* see find_lock array definition for more info on object locking */
8743+	LOCK_OBJSTORE(OP_DH);
8744+	rv = pFuncList->C_FindObjectsInit(session, key_template,
8745+		ul_key_attr_count);
8746+
8747+	if (rv != CKR_OK)
8748+		{
8749+		PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSINIT, rv);
8750+		goto err;
8751+		}
8752+
8753+	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
8754+
8755+	if (rv != CKR_OK)
8756+		{
8757+		(void) pFuncList->C_FindObjectsFinal(session);
8758+		PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTS, rv);
8759+		goto err;
8760+		}
8761+
8762+	rv = pFuncList->C_FindObjectsFinal(session);
8763+
8764+	if (rv != CKR_OK)
8765+		{
8766+		PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSFINAL,
8767+		    rv);
8768+		goto err;
8769+		}
8770+
8771+	if (found == 0)
8772+		{
8773+		rv = pFuncList->C_CreateObject(session,
8774+			key_template, ul_key_attr_count, &h_key);
8775+		if (rv != CKR_OK)
8776+			{
8777+			PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_CREATEOBJECT,
8778+			    rv);
8779+			goto err;
8780+			}
8781+		}
8782+
8783+	if (dh_priv_num != NULL)
8784+		if ((*dh_priv_num = BN_dup(dh->priv_key)) == NULL)
8785+			{
8786+			PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8787+			rollback = TRUE;
8788+			goto err;
8789+			}
8790+
8791+	/* LINTED: E_CONSTANT_CONDITION */
8792+	KEY_HANDLE_REFHOLD(h_key, OP_DH, FALSE, rollback, err);
8793+	if (key_ptr != NULL)
8794+		*key_ptr = dh;
8795+
8796+err:
8797+	if (rollback)
8798+		{
8799+		/*
8800+		 * We do not care about the return value from C_DestroyObject()
8801+		 * since we are doing rollback.
8802+		 */
8803+		if (found == 0)
8804+			(void) pFuncList->C_DestroyObject(session, h_key);
8805+		h_key = CK_INVALID_HANDLE;
8806+		}
8807+
8808+	UNLOCK_OBJSTORE(OP_DH);
8809+
8810+malloc_err:
8811+	for (i = 4; i <= 6; i++)
8812+		{
8813+		if (key_template[i].pValue != NULL)
8814+			{
8815+			OPENSSL_free(key_template[i].pValue);
8816+			key_template[i].pValue = NULL;
8817+			}
8818+		}
8819+
8820+	return (h_key);
8821+	}
8822+
8823+/*
8824+ * Check for cache miss and clean the object pointer and handle
8825+ * in such case. Return 1 for cache hit, 0 for cache miss.
8826+ *
8827+ * Note: we rely on pk11_destroy_dh_key_objects() to set sp->opdata_dh
8828+ *       to CK_INVALID_HANDLE even when it fails to destroy the object.
8829+ */
8830+static int check_new_dh_key(PK11_SESSION *sp, DH *dh)
8831+	{
8832+	/*
8833+	 * Provide protection against DH structure reuse by making the
8834+	 * check for cache hit stronger. Private key component of DH key
8835+	 * is unique so it is sufficient to compare it with value cached
8836+	 * in PK11_SESSION structure.
8837+	 */
8838+	if ((sp->opdata_dh != dh) ||
8839+	    (BN_cmp(sp->opdata_dh_priv_num, dh->priv_key) != 0))
8840+		{
8841+		/*
8842+		 * We do not check the return value because even in case of
8843+		 * failure the sp structure will have both key pointer
8844+		 * and object handle cleaned and pk11_destroy_object()
8845+		 * reports the failure to the OpenSSL error message buffer.
8846+		 */
8847+		(void) pk11_destroy_dh_object(sp, TRUE);
8848+		return (0);
8849+		}
8850+	return (1);
8851+	}
8852+#endif
8853+
8854+/*
8855+ * Local function to simplify key template population
8856+ * Return 0 -- error, 1 -- no error
8857+ */
8858+static int
8859+init_template_value(BIGNUM *bn, CK_VOID_PTR *p_value,
8860+	CK_ULONG *ul_value_len)
8861+	{
8862+	CK_ULONG len = 0;
8863+
8864+	/*
8865+	 * This function can be used on non-initialized BIGNUMs. It is
8866+	 * easier to check that here than individually in the callers.
8867+	 */
8868+	if (bn != NULL)
8869+		len = BN_num_bytes(bn);
8870+
8871+	if (bn == NULL || len == 0)
8872+		return (1);
8873+
8874+	*ul_value_len = len;
8875+	*p_value = (CK_VOID_PTR)OPENSSL_malloc((size_t)*ul_value_len);
8876+	if (*p_value == NULL)
8877+		return (0);
8878+
8879+	BN_bn2bin(bn, *p_value);
8880+
8881+	return (1);
8882+	}
8883+
8884+static void
8885+attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn)
8886+	{
8887+	if (attr->ulValueLen > 0)
8888+		*bn = BN_bin2bn(attr_data, attr->ulValueLen, NULL);
8889+	}
8890+
8891+/*
8892+ * Find one object in the token. It is an error if we can not find the
8893+ * object or if we find more objects based on the template we got.
8894+ * Assume object store locked.
8895+ *
8896+ * Returns:
8897+ *	1 OK
8898+ *	0 no object or more than 1 object found
8899+ */
8900+static int
8901+find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
8902+    CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey)
8903+	{
8904+	CK_RV rv;
8905+	CK_ULONG objcnt;
8906+
8907+	if ((rv = pFuncList->C_FindObjectsInit(s, ptempl, nattr)) != CKR_OK)
8908+		{
8909+		PK11err_add_data(PK11_F_FIND_ONE_OBJECT,
8910+		    PK11_R_FINDOBJECTSINIT, rv);
8911+		return (0);
8912+		}
8913+
8914+	rv = pFuncList->C_FindObjects(s, pkey, 1, &objcnt);
8915+	if (rv != CKR_OK)
8916+		{
8917+		(void) pFuncList->C_FindObjectsFinal(s);
8918+		PK11err_add_data(PK11_F_FIND_ONE_OBJECT, PK11_R_FINDOBJECTS,
8919+		    rv);
8920+		return (0);
8921+		}
8922+
8923+	(void) pFuncList->C_FindObjectsFinal(s);
8924+
8925+	if (objcnt > 1)
8926+		{
8927+		PK11err(PK11_F_FIND_ONE_OBJECT,
8928+		    PK11_R_MORE_THAN_ONE_OBJECT_FOUND);
8929+		return (0);
8930+		}
8931+	else if (objcnt == 0)
8932+		{
8933+		PK11err(PK11_F_FIND_ONE_OBJECT, PK11_R_NO_OBJECT_FOUND);
8934+		return (0);
8935+		}
8936+	return (1);
8937+	}
8938+
8939+/* from uri stuff */
8940+
8941+extern char *pk11_pin;
8942+
8943+static int pk11_get_pin(void);
8944+
8945+static int
8946+pk11_get_pin(void)
8947+{
8948+	char *pin;
8949+
8950+	/* The getpassphrase() function is not MT safe. */
8951+#ifndef NOPTHREADS
8952+	OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
8953+#else
8954+	CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
8955+#endif
8956+	pin = getpassphrase("Enter PIN: ");
8957+	if (pin == NULL)
8958+		{
8959+		PK11err(PK11_F_GET_PIN, PK11_R_COULD_NOT_READ_PIN);
8960+#ifndef NOPTHREADS
8961+		OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
8962+#else
8963+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
8964+#endif
8965+		return (0);
8966+		}
8967+	pk11_pin = BUF_strdup(pin);
8968+	if (pk11_pin == NULL)
8969+		{
8970+		PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_MALLOC_FAILURE);
8971+#ifndef NOPTHREADS
8972+		OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
8973+#else
8974+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
8975+#endif
8976+		return (0);
8977+		}
8978+	memset(pin, 0, strlen(pin));
8979+#ifndef NOPTHREADS
8980+	OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
8981+#else
8982+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
8983+#endif
8984+	return (1);
8985+	}
8986+
8987+/*
8988+ * Log in to the keystore if we are supposed to do that at all. Take care of
8989+ * reading and caching the PIN etc. Log in only once even when called from
8990+ * multiple threads.
8991+ *
8992+ * Returns:
8993+ *	1 on success
8994+ *	0 on failure
8995+ */
8996+static int
8997+pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
8998+    CK_BBOOL is_private)
8999+	{
9000+	CK_RV rv;
9001+
9002+#if 0
9003+	/* doesn't work on the AEP Keyper??? */
9004+	if ((pubkey_token_flags & CKF_TOKEN_INITIALIZED) == 0)
9005+		{
9006+		PK11err(PK11_F_TOKEN_LOGIN,
9007+		    PK11_R_TOKEN_NOT_INITIALIZED);
9008+		return (0);
9009+		}
9010+#endif
9011+
9012+	/*
9013+	 * If login is required or needed but the PIN has not been
9014+	 * even initialized we can bail out right now. Note that we
9015+	 * are supposed to always log in if we are going to access
9016+	 * private keys. However, we may need to log in even for
9017+	 * accessing public keys in case that the CKF_LOGIN_REQUIRED
9018+	 * flag is set.
9019+	 */
9020+	if (((pubkey_token_flags & CKF_LOGIN_REQUIRED) ||
9021+	     (is_private == CK_TRUE)) &&
9022+	    (~pubkey_token_flags & CKF_USER_PIN_INITIALIZED))
9023+		{
9024+		PK11err(PK11_F_TOKEN_LOGIN, PK11_R_TOKEN_PIN_NOT_SET);
9025+		return (0);
9026+		}
9027+
9028+	/*
9029+	 * Note on locking: it is possible that more than one thread
9030+	 * gets into pk11_get_pin() so we must deal with that. We
9031+	 * cannot avoid it since we cannot guard fork() in there with
9032+	 * a lock because we could end up in a dead lock in the
9033+	 * child. Why? Remember we are in a multithreaded environment
9034+	 * so we must lock all mutexes in the prefork function to
9035+	 * avoid a situation in which a thread that did not call
9036+	 * fork() held a lock, making future unlocking impossible. We
9037+	 * lock right before C_Login().
9038+	 */
9039+	if ((pubkey_token_flags & CKF_LOGIN_REQUIRED) ||
9040+	    (is_private == CK_TRUE))
9041+		{
9042+		if (*login_done == CK_FALSE)
9043+			{
9044+			if ((pk11_pin == NULL) && (pk11_get_pin() == 0))
9045+				{
9046+				PK11err(PK11_F_TOKEN_LOGIN,
9047+				    PK11_R_TOKEN_PIN_NOT_PROVIDED);
9048+				return (0);
9049+				}
9050+			}
9051+
9052+		/*
9053+		 * Note that what we are logging into is the keystore from
9054+		 * pubkey_SLOTID because we work with OP_RSA session type here.
9055+		 * That also means that we can work with only one keystore in
9056+		 * the engine.
9057+		 *
9058+		 * We must make sure we do not try to login more than once.
9059+		 * Also, see the comment above on locking strategy.
9060+		 */
9061+
9062+#ifndef NOPTHREADS
9063+		OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
9064+#else
9065+		CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
9066+#endif
9067+		if (*login_done == CK_FALSE)
9068+			{
9069+			if ((rv = pFuncList->C_Login(session,
9070+			    CKU_USER, (CK_UTF8CHAR*)pk11_pin,
9071+			    strlen(pk11_pin))) != CKR_OK)
9072+				{
9073+				PK11err_add_data(PK11_F_TOKEN_LOGIN,
9074+				    PK11_R_TOKEN_LOGIN_FAILED, rv);
9075+				goto err_locked;
9076+				}
9077+
9078+			*login_done = CK_TRUE;
9079+
9080+			}
9081+#ifndef NOPTHREADS
9082+		OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
9083+#else
9084+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
9085+#endif
9086+		}
9087+	else
9088+		{
9089+			/*
9090+			 * If token does not require login we take it as the
9091+			 * login was done.
9092+			 */
9093+			*login_done = CK_TRUE;
9094+		}
9095+
9096+	return (1);
9097+
9098+err_locked:
9099+	if (pk11_pin) {
9100+		memset(pk11_pin, 0, strlen(pk11_pin));
9101+		OPENSSL_free((void*)pk11_pin);
9102+	}
9103+	pk11_pin = NULL;
9104+#ifndef NOPTHREADS
9105+	OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
9106+#else
9107+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
9108+#endif
9109+	return (0);
9110+	}
9111+
9112+/*
9113+ * Log in to the keystore in the child if we were logged in in the
9114+ * parent. There are similarities in the code with pk11_token_login()
9115+ * but still it is quite different so we need a separate function for
9116+ * this.
9117+ *
9118+ * Note that this function is called under the locked session mutex when fork is
9119+ * detected. That means that C_Login() will be called from the child just once.
9120+ *
9121+ * Returns:
9122+ *	1 on success
9123+ *	0 on failure
9124+ */
9125+int
9126+pk11_token_relogin(CK_SESSION_HANDLE session)
9127+	{
9128+	CK_RV rv;
9129+
9130+	if ((pk11_pin == NULL) && (pk11_get_pin() == 0))
9131+		return (0);
9132+
9133+#ifndef NOPTHREADS
9134+	OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
9135+#else
9136+	CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
9137+#endif
9138+	if ((rv = pFuncList->C_Login(session, CKU_USER,
9139+	    (CK_UTF8CHAR_PTR)pk11_pin, strlen(pk11_pin))) != CKR_OK)
9140+		{
9141+		PK11err_add_data(PK11_F_TOKEN_RELOGIN,
9142+		    PK11_R_TOKEN_LOGIN_FAILED, rv);
9143+#ifndef NOPTHREADS
9144+		OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
9145+#else
9146+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
9147+#endif
9148+		return (0);
9149+		}
9150+#ifndef NOPTHREADS
9151+	OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
9152+#else
9153+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
9154+#endif
9155+
9156+	return (1);
9157+	}
9158+
9159+#ifdef	OPENSSL_SYS_WIN32
9160+char *getpassphrase(const char *prompt)
9161+	{
9162+	static char buf[128];
9163+	HANDLE h;
9164+	DWORD cc, mode;
9165+	int cnt;
9166+
9167+	h = GetStdHandle(STD_INPUT_HANDLE);
9168+	fputs(prompt, stderr);
9169+	fflush(stderr);
9170+	fflush(stdout);
9171+	FlushConsoleInputBuffer(h);
9172+	GetConsoleMode(h, &mode);
9173+	SetConsoleMode(h, ENABLE_PROCESSED_INPUT);
9174+
9175+	for (cnt = 0; cnt < sizeof(buf) - 1; cnt++)
9176+		{
9177+		ReadFile(h, buf + cnt, 1, &cc, NULL);
9178+		if (buf[cnt] == '\r')
9179+			break;
9180+		fputc('*', stdout);
9181+		fflush(stderr);
9182+		fflush(stdout);
9183+		}
9184+
9185+	SetConsoleMode(h, mode);
9186+	buf[cnt] = '\0';
9187+	fputs("\n", stderr);
9188+	return buf;
9189+	}
9190+#endif	/* OPENSSL_SYS_WIN32 */
9191+#endif	/* OPENSSL_NO_HW_PK11CA */
9192+#endif	/* OPENSSL_NO_HW_PK11 */
9193+#endif	/* OPENSSL_NO_HW */
9194Index: openssl/crypto/engine/hw_pk11ca.h
9195diff -u /dev/null openssl/crypto/engine/hw_pk11ca.h:1.2.4.2
9196--- /dev/null	Fri Jan  2 13:56:41 2015
9197+++ openssl/crypto/engine/hw_pk11ca.h	Wed Jun 15 21:12:32 2011
9198@@ -0,0 +1,32 @@
9199+/* Redefine all pk11/PK11 external symbols to pk11ca/PK11CA */
9200+
9201+#define token_lock			pk11ca_token_lock
9202+#define find_lock			pk11ca_find_lock
9203+#define active_list			pk11ca_active_list
9204+#define pubkey_token_flags		pk11ca_pubkey_token_flags
9205+#define pubkey_SLOTID			pk11ca_pubkey_SLOTID
9206+#define ERR_pk11_error			ERR_pk11ca_error
9207+#define PK11err_add_data		PK11CAerr_add_data
9208+#define pk11_get_session		pk11ca_get_session
9209+#define pk11_return_session		pk11ca_return_session
9210+#define pk11_active_add			pk11ca_active_add
9211+#define pk11_active_delete		pk11ca_active_delete
9212+#define pk11_active_remove		pk11ca_active_remove
9213+#define pk11_free_active_list		pk11ca_free_active_list
9214+#define pk11_destroy_rsa_key_objects	pk11ca_destroy_rsa_key_objects
9215+#define pk11_destroy_rsa_object_pub	pk11ca_destroy_rsa_object_pub
9216+#define pk11_destroy_rsa_object_priv	pk11ca_destroy_rsa_object_priv
9217+#define pk11_load_privkey		pk11ca_load_privkey
9218+#define pk11_load_pubkey		pk11ca_load_pubkey
9219+#define PK11_RSA			PK11CA_RSA
9220+#define pk11_destroy_dsa_key_objects	pk11ca_destroy_dsa_key_objects
9221+#define pk11_destroy_dsa_object_pub	pk11ca_destroy_dsa_object_pub
9222+#define pk11_destroy_dsa_object_priv	pk11ca_destroy_dsa_object_priv
9223+#define PK11_DSA			PK11CA_DSA
9224+#define pk11_destroy_dh_key_objects	pk11ca_destroy_dh_key_objects
9225+#define pk11_destroy_dh_object		pk11ca_destroy_dh_object
9226+#define PK11_DH				PK11CA_DH
9227+#define pk11_token_relogin		pk11ca_token_relogin
9228+#define pFuncList			pk11ca_pFuncList
9229+#define pk11_pin			pk11ca_pin
9230+#define ENGINE_load_pk11		ENGINE_load_pk11ca
9231Index: openssl/crypto/engine/hw_pk11so.c
9232diff -u /dev/null openssl/crypto/engine/hw_pk11so.c:1.3.4.3
9233--- /dev/null	Fri Jan  2 13:56:41 2015
9234+++ openssl/crypto/engine/hw_pk11so.c	Fri Oct  4 14:45:25 2013
9235@@ -0,0 +1,1775 @@
9236+/*
9237+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
9238+ * Use is subject to license terms.
9239+ */
9240+
9241+/* crypto/engine/hw_pk11.c */
9242+/*
9243+ * This product includes software developed by the OpenSSL Project for
9244+ * use in the OpenSSL Toolkit (http://www.openssl.org/).
9245+ *
9246+ * This project also referenced hw_pkcs11-0.9.7b.patch written by
9247+ * Afchine Madjlessi.
9248+ */
9249+/*
9250+ * ====================================================================
9251+ * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
9252+ *
9253+ * Redistribution and use in source and binary forms, with or without
9254+ * modification, are permitted provided that the following conditions
9255+ * are met:
9256+ *
9257+ * 1. Redistributions of source code must retain the above copyright
9258+ *    notice, this list of conditions and the following disclaimer.
9259+ *
9260+ * 2. Redistributions in binary form must reproduce the above copyright
9261+ *    notice, this list of conditions and the following disclaimer in
9262+ *    the documentation and/or other materials provided with the
9263+ *    distribution.
9264+ *
9265+ * 3. All advertising materials mentioning features or use of this
9266+ *    software must display the following acknowledgment:
9267+ *    "This product includes software developed by the OpenSSL Project
9268+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
9269+ *
9270+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
9271+ *    endorse or promote products derived from this software without
9272+ *    prior written permission. For written permission, please contact
9273+ *    licensing@OpenSSL.org.
9274+ *
9275+ * 5. Products derived from this software may not be called "OpenSSL"
9276+ *    nor may "OpenSSL" appear in their names without prior written
9277+ *    permission of the OpenSSL Project.
9278+ *
9279+ * 6. Redistributions of any form whatsoever must retain the following
9280+ *    acknowledgment:
9281+ *    "This product includes software developed by the OpenSSL Project
9282+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
9283+ *
9284+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
9285+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9286+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
9287+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
9288+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9289+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
9290+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
9291+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
9292+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
9293+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
9294+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
9295+ * OF THE POSSIBILITY OF SUCH DAMAGE.
9296+ * ====================================================================
9297+ *
9298+ * This product includes cryptographic software written by Eric Young
9299+ * (eay@cryptsoft.com).  This product includes software written by Tim
9300+ * Hudson (tjh@cryptsoft.com).
9301+ *
9302+ */
9303+
9304+/* Modified to keep only RNG and RSA Sign */
9305+
9306+#ifdef OPENSSL_NO_RSA
9307+#error RSA is disabled
9308+#endif
9309+
9310+#include <stdio.h>
9311+#include <stdlib.h>
9312+#include <string.h>
9313+#include <sys/types.h>
9314+
9315+#include <openssl/e_os2.h>
9316+#include <openssl/crypto.h>
9317+#include <cryptlib.h>
9318+#include <openssl/engine.h>
9319+#include <openssl/dso.h>
9320+#include <openssl/err.h>
9321+#include <openssl/bn.h>
9322+#include <openssl/md5.h>
9323+#include <openssl/pem.h>
9324+#include <openssl/rsa.h>
9325+#include <openssl/rand.h>
9326+#include <openssl/objects.h>
9327+#include <openssl/x509.h>
9328+
9329+#ifdef OPENSSL_SYS_WIN32
9330+typedef int pid_t;
9331+#define getpid() GetCurrentProcessId()
9332+#define NOPTHREADS
9333+#ifndef NULL_PTR
9334+#define NULL_PTR NULL
9335+#endif
9336+#define CK_DEFINE_FUNCTION(returnType, name) \
9337+	returnType __declspec(dllexport) name
9338+#define CK_DECLARE_FUNCTION(returnType, name) \
9339+	returnType __declspec(dllimport) name
9340+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
9341+	returnType __declspec(dllimport) (* name)
9342+#else
9343+#include <signal.h>
9344+#include <unistd.h>
9345+#include <dlfcn.h>
9346+#endif
9347+
9348+/* Debug mutexes */
9349+/*#undef DEBUG_MUTEX */
9350+#define DEBUG_MUTEX
9351+
9352+#ifndef NOPTHREADS
9353+/* for pthread error check on Linuxes */
9354+#ifdef DEBUG_MUTEX
9355+#define __USE_UNIX98
9356+#endif
9357+#include <pthread.h>
9358+#endif
9359+
9360+#ifndef OPENSSL_NO_HW
9361+#ifndef OPENSSL_NO_HW_PK11
9362+#ifndef OPENSSL_NO_HW_PK11SO
9363+
9364+/* label for debug messages printed on stderr */
9365+#define	PK11_DBG	"PKCS#11 ENGINE DEBUG"
9366+/* prints a lot of debug messages on stderr about slot selection process */
9367+/*#undef	DEBUG_SLOT_SELECTION */
9368+
9369+#ifndef OPENSSL_NO_DSA
9370+#define OPENSSL_NO_DSA
9371+#endif
9372+#ifndef OPENSSL_NO_DH
9373+#define OPENSSL_NO_DH
9374+#endif
9375+
9376+#ifdef OPENSSL_SYS_WIN32
9377+#pragma pack(push, cryptoki, 1)
9378+#include "cryptoki.h"
9379+#include "pkcs11.h"
9380+#pragma pack(pop, cryptoki)
9381+#else
9382+#include "cryptoki.h"
9383+#include "pkcs11.h"
9384+#endif
9385+#include "hw_pk11so.h"
9386+#include "hw_pk11_err.c"
9387+
9388+/*
9389+ * We use this lock to prevent multiple C_Login()s, guard getpassphrase(),
9390+ * uri_struct manipulation, and static token info. All of that is used by the
9391+ * RSA keys by reference feature.
9392+ */
9393+#ifndef NOPTHREADS
9394+pthread_mutex_t *token_lock;
9395+#endif
9396+
9397+/* PKCS#11 session caches and their locks for all operation types */
9398+static PK11_CACHE session_cache[OP_MAX];
9399+
9400+/*
9401+ * We cache the flags so that we do not have to run C_GetTokenInfo() again when
9402+ * logging into the token.
9403+ */
9404+CK_FLAGS pubkey_token_flags;
9405+
9406+/*
9407+ * As stated in v2.20, 11.7 Object Management Function, in section for
9408+ * C_FindObjectsInit(), at most one search operation may be active at a given
9409+ * time in a given session. Therefore, C_Find{,Init,Final}Objects() should be
9410+ * grouped together to form one atomic search operation. This is already
9411+ * ensured by the property of unique PKCS#11 session handle used for each
9412+ * PK11_SESSION object.
9413+ *
9414+ * This is however not the biggest concern - maintaining consistency of the
9415+ * underlying object store is more important. The same section of the spec also
9416+ * says that one thread can be in the middle of a search operation while another
9417+ * thread destroys the object matching the search template which would result in
9418+ * invalid handle returned from the search operation.
9419+ *
9420+ * Hence, the following locks are used for both protection of the object stores.
9421+ * They are also used for active list protection.
9422+ */
9423+#ifndef NOPTHREADS
9424+pthread_mutex_t *find_lock[OP_MAX] = { NULL };
9425+#endif
9426+
9427+/*
9428+ * lists of asymmetric key handles which are active (referenced by at least one
9429+ * PK11_SESSION structure, either held by a thread or present in free_session
9430+ * list) for given algorithm type
9431+ */
9432+PK11_active *active_list[OP_MAX] = { NULL };
9433+
9434+/*
9435+ * Create all secret key objects in a global session so that they are available
9436+ * to use for other sessions. These other sessions may be opened or closed
9437+ * without losing the secret key objects.
9438+ */
9439+static CK_SESSION_HANDLE	global_session = CK_INVALID_HANDLE;
9440+
9441+/* ENGINE level stuff */
9442+static int pk11_init(ENGINE *e);
9443+static int pk11_library_init(ENGINE *e);
9444+static int pk11_finish(ENGINE *e);
9445+static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
9446+static int pk11_destroy(ENGINE *e);
9447+
9448+/* RAND stuff */
9449+static void pk11_rand_seed(const void *buf, int num);
9450+static void pk11_rand_add(const void *buf, int num, double add_entropy);
9451+static void pk11_rand_cleanup(void);
9452+static int pk11_rand_bytes(unsigned char *buf, int num);
9453+static int pk11_rand_status(void);
9454+
9455+/* These functions are also used in other files */
9456+PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
9457+void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
9458+
9459+/* active list manipulation functions used in this file */
9460+extern int pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type);
9461+extern void pk11_free_active_list(PK11_OPTYPE type);
9462+
9463+int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
9464+int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
9465+int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
9466+
9467+/* Local helper functions */
9468+static int pk11_free_all_sessions(void);
9469+static int pk11_free_session_list(PK11_OPTYPE optype);
9470+static int pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype);
9471+static int pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
9472+	CK_BBOOL persistent);
9473+static const char *get_PK11_LIBNAME(void);
9474+static void free_PK11_LIBNAME(void);
9475+static long set_PK11_LIBNAME(const char *name);
9476+
9477+static int pk11_choose_slots(int *any_slot_found);
9478+
9479+static int pk11_init_all_locks(void);
9480+static void pk11_free_all_locks(void);
9481+
9482+#define	TRY_OBJ_DESTROY(sp, obj_hdl, retval, uselock, alg_type, priv)	\
9483+	{								\
9484+	if (uselock)							\
9485+		LOCK_OBJSTORE(alg_type);				\
9486+	if (pk11_active_delete(obj_hdl, alg_type) == 1)			\
9487+		{							\
9488+		  retval = pk11_destroy_object(sp->session, obj_hdl,	\
9489+		  priv ? sp->priv_persistent : sp->pub_persistent);	\
9490+		}							\
9491+	if (uselock)							\
9492+		UNLOCK_OBJSTORE(alg_type);				\
9493+	}
9494+
9495+static CK_BBOOL pk11_have_rsa	= CK_FALSE;
9496+static CK_BBOOL pk11_have_random = CK_FALSE;
9497+
9498+/*
9499+ * Initialization function. Sets up various PKCS#11 library components.
9500+ * The definitions for control commands specific to this engine
9501+ */
9502+#define PK11_CMD_SO_PATH		ENGINE_CMD_BASE
9503+#define PK11_CMD_PIN			(ENGINE_CMD_BASE+1)
9504+#define PK11_CMD_SLOT			(ENGINE_CMD_BASE+2)
9505+static const ENGINE_CMD_DEFN pk11_cmd_defns[] =
9506+	{
9507+		{
9508+		PK11_CMD_SO_PATH,
9509+		"SO_PATH",
9510+		"Specifies the path to the 'pkcs#11' shared library",
9511+		ENGINE_CMD_FLAG_STRING
9512+		},
9513+		{
9514+		PK11_CMD_PIN,
9515+		"PIN",
9516+		"Specifies the pin code",
9517+		ENGINE_CMD_FLAG_STRING
9518+		},
9519+		{
9520+		PK11_CMD_SLOT,
9521+		"SLOT",
9522+		"Specifies the slot (default is auto select)",
9523+		ENGINE_CMD_FLAG_NUMERIC,
9524+		},
9525+		{0, NULL, NULL, 0}
9526+	};
9527+
9528+
9529+static RAND_METHOD pk11_random =
9530+	{
9531+	pk11_rand_seed,
9532+	pk11_rand_bytes,
9533+	pk11_rand_cleanup,
9534+	pk11_rand_add,
9535+	pk11_rand_bytes,
9536+	pk11_rand_status
9537+	};
9538+
9539+
9540+/* Constants used when creating the ENGINE */
9541+#ifdef OPENSSL_NO_HW_PK11CA
9542+#error "can't load both crypto-accelerator and sign-only PKCS#11 engines"
9543+#endif
9544+static const char *engine_pk11_id = "pkcs11";
9545+static const char *engine_pk11_name = "PKCS #11 engine support (sign only)";
9546+
9547+CK_FUNCTION_LIST_PTR pFuncList = NULL;
9548+static const char PK11_GET_FUNCTION_LIST[] = "C_GetFunctionList";
9549+
9550+/*
9551+ * This is a static string constant for the DSO file name and the function
9552+ * symbol names to bind to. We set it in the Configure script based on whether
9553+ * this is 32 or 64 bit build.
9554+ */
9555+static const char def_PK11_LIBNAME[] = PK11_LIB_LOCATION;
9556+
9557+/* Needed in hw_pk11_pub.c as well so that's why it is not static. */
9558+CK_SLOT_ID pubkey_SLOTID = 0;
9559+static CK_SLOT_ID rand_SLOTID = 0;
9560+static CK_SLOT_ID SLOTID = 0;
9561+char *pk11_pin = NULL;
9562+static CK_BBOOL pk11_library_initialized = FALSE;
9563+static CK_BBOOL pk11_atfork_initialized = FALSE;
9564+static int pk11_pid = 0;
9565+
9566+static DSO *pk11_dso = NULL;
9567+
9568+/* allocate and initialize all locks used by the engine itself */
9569+static int pk11_init_all_locks(void)
9570+	{
9571+#ifndef NOPTHREADS
9572+	int type;
9573+	pthread_mutexattr_t attr;
9574+
9575+	if (pthread_mutexattr_init(&attr) != 0)
9576+	{
9577+		PK11err(PK11_F_INIT_ALL_LOCKS, 100);
9578+		return (0);
9579+	}
9580+
9581+#ifdef DEBUG_MUTEX
9582+	if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0)
9583+	{
9584+		PK11err(PK11_F_INIT_ALL_LOCKS, 101);
9585+		return (0);
9586+	}
9587+#endif
9588+
9589+	if ((token_lock = OPENSSL_malloc(sizeof (pthread_mutex_t))) == NULL)
9590+		goto malloc_err;
9591+	(void) pthread_mutex_init(token_lock, &attr);
9592+
9593+	find_lock[OP_RSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
9594+	if (find_lock[OP_RSA] == NULL)
9595+		goto malloc_err;
9596+	(void) pthread_mutex_init(find_lock[OP_RSA], &attr);
9597+
9598+	for (type = 0; type < OP_MAX; type++)
9599+		{
9600+		session_cache[type].lock =
9601+		    OPENSSL_malloc(sizeof (pthread_mutex_t));
9602+		if (session_cache[type].lock == NULL)
9603+			goto malloc_err;
9604+		(void) pthread_mutex_init(session_cache[type].lock, &attr);
9605+		}
9606+
9607+	return (1);
9608+
9609+malloc_err:
9610+	pk11_free_all_locks();
9611+	PK11err(PK11_F_INIT_ALL_LOCKS, PK11_R_MALLOC_FAILURE);
9612+	return (0);
9613+#else
9614+	return (1);
9615+#endif
9616+	}
9617+
9618+static void pk11_free_all_locks(void)
9619+	{
9620+#ifndef NOPTHREADS
9621+	int type;
9622+
9623+	if (token_lock != NULL)
9624+		{
9625+		(void) pthread_mutex_destroy(token_lock);
9626+		OPENSSL_free(token_lock);
9627+		token_lock = NULL;
9628+		}
9629+
9630+	if (find_lock[OP_RSA] != NULL)
9631+		{
9632+		(void) pthread_mutex_destroy(find_lock[OP_RSA]);
9633+		OPENSSL_free(find_lock[OP_RSA]);
9634+		find_lock[OP_RSA] = NULL;
9635+		}
9636+
9637+	for (type = 0; type < OP_MAX; type++)
9638+		{
9639+		if (session_cache[type].lock != NULL)
9640+			{
9641+			(void) pthread_mutex_destroy(session_cache[type].lock);
9642+			OPENSSL_free(session_cache[type].lock);
9643+			session_cache[type].lock = NULL;
9644+			}
9645+		}
9646+#endif
9647+	}
9648+
9649+/*
9650+ * This internal function is used by ENGINE_pk11() and "dynamic" ENGINE support.
9651+ */
9652+static int bind_pk11(ENGINE *e)
9653+	{
9654+	if (!pk11_library_initialized)
9655+		if (!pk11_library_init(e))
9656+			return (0);
9657+
9658+	if (!ENGINE_set_id(e, engine_pk11_id) ||
9659+	    !ENGINE_set_name(e, engine_pk11_name))
9660+		return (0);
9661+
9662+	if (pk11_have_rsa == CK_TRUE)
9663+		{
9664+		if (!ENGINE_set_RSA(e, PK11_RSA()) ||
9665+		    !ENGINE_set_load_privkey_function(e, pk11_load_privkey) ||
9666+		    !ENGINE_set_load_pubkey_function(e, pk11_load_pubkey))
9667+			return (0);
9668+#ifdef	DEBUG_SLOT_SELECTION
9669+		fprintf(stderr, "%s: registered RSA\n", PK11_DBG);
9670+#endif	/* DEBUG_SLOT_SELECTION */
9671+		}
9672+
9673+	if (pk11_have_random)
9674+		{
9675+		if (!ENGINE_set_RAND(e, &pk11_random))
9676+			return (0);
9677+#ifdef	DEBUG_SLOT_SELECTION
9678+		fprintf(stderr, "%s: registered random\n", PK11_DBG);
9679+#endif	/* DEBUG_SLOT_SELECTION */
9680+		}
9681+	if (!ENGINE_set_init_function(e, pk11_init) ||
9682+	    !ENGINE_set_destroy_function(e, pk11_destroy) ||
9683+	    !ENGINE_set_finish_function(e, pk11_finish) ||
9684+	    !ENGINE_set_ctrl_function(e, pk11_ctrl) ||
9685+	    !ENGINE_set_cmd_defns(e, pk11_cmd_defns))
9686+		return (0);
9687+
9688+	/* Ensure the pk11 error handling is set up */
9689+	ERR_load_pk11_strings();
9690+
9691+	return (1);
9692+	}
9693+
9694+/* Dynamic engine support is disabled at a higher level for Solaris */
9695+#ifdef	ENGINE_DYNAMIC_SUPPORT
9696+#error	"dynamic engine not supported"
9697+static int bind_helper(ENGINE *e, const char *id)
9698+	{
9699+	if (id && (strcmp(id, engine_pk11_id) != 0))
9700+		return (0);
9701+
9702+	if (!bind_pk11(e))
9703+		return (0);
9704+
9705+	return (1);
9706+	}
9707+
9708+IMPLEMENT_DYNAMIC_CHECK_FN()
9709+IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
9710+
9711+#else
9712+static ENGINE *engine_pk11(void)
9713+	{
9714+	ENGINE *ret = ENGINE_new();
9715+
9716+	if (!ret)
9717+		return (NULL);
9718+
9719+	if (!bind_pk11(ret))
9720+		{
9721+		ENGINE_free(ret);
9722+		return (NULL);
9723+		}
9724+
9725+	return (ret);
9726+	}
9727+
9728+void
9729+ENGINE_load_pk11(void)
9730+	{
9731+	ENGINE *e_pk11 = NULL;
9732+
9733+	/*
9734+	 * Do not use dynamic PKCS#11 library on Solaris due to
9735+	 * security reasons. We will link it in statically.
9736+	 */
9737+	/* Attempt to load PKCS#11 library */
9738+	if (!pk11_dso)
9739+		pk11_dso = DSO_load(NULL, get_PK11_LIBNAME(), NULL, 0);
9740+
9741+	if (pk11_dso == NULL)
9742+		{
9743+		PK11err(PK11_F_LOAD, PK11_R_DSO_FAILURE);
9744+		return;
9745+		}
9746+
9747+	e_pk11 = engine_pk11();
9748+	if (!e_pk11)
9749+		{
9750+		DSO_free(pk11_dso);
9751+		pk11_dso = NULL;
9752+		return;
9753+		}
9754+
9755+	/*
9756+	 * At this point, the pk11 shared library is either dynamically
9757+	 * loaded or statically linked in. So, initialize the pk11
9758+	 * library before calling ENGINE_set_default since the latter
9759+	 * needs cipher and digest algorithm information
9760+	 */
9761+	if (!pk11_library_init(e_pk11))
9762+		{
9763+		DSO_free(pk11_dso);
9764+		pk11_dso = NULL;
9765+		ENGINE_free(e_pk11);
9766+		return;
9767+		}
9768+
9769+	ENGINE_add(e_pk11);
9770+
9771+	ENGINE_free(e_pk11);
9772+	ERR_clear_error();
9773+	}
9774+#endif	/* ENGINE_DYNAMIC_SUPPORT */
9775+
9776+/*
9777+ * These are the static string constants for the DSO file name and
9778+ * the function symbol names to bind to.
9779+ */
9780+static const char *PK11_LIBNAME = NULL;
9781+
9782+static const char *get_PK11_LIBNAME(void)
9783+	{
9784+	if (PK11_LIBNAME)
9785+		return (PK11_LIBNAME);
9786+
9787+	return (def_PK11_LIBNAME);
9788+	}
9789+
9790+static void free_PK11_LIBNAME(void)
9791+	{
9792+	if (PK11_LIBNAME)
9793+		OPENSSL_free((void*)PK11_LIBNAME);
9794+
9795+	PK11_LIBNAME = NULL;
9796+	}
9797+
9798+static long set_PK11_LIBNAME(const char *name)
9799+	{
9800+	free_PK11_LIBNAME();
9801+
9802+	return ((PK11_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
9803+	}
9804+
9805+/* acquire all engine specific mutexes before fork */
9806+static void pk11_fork_prepare(void)
9807+	{
9808+#ifndef NOPTHREADS
9809+	int i;
9810+
9811+	if (!pk11_library_initialized)
9812+		return;
9813+
9814+	LOCK_OBJSTORE(OP_RSA);
9815+	OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
9816+	for (i = 0; i < OP_MAX; i++)
9817+		{
9818+		OPENSSL_assert(pthread_mutex_lock(session_cache[i].lock) == 0);
9819+		}
9820+#endif
9821+	}
9822+
9823+/* release all engine specific mutexes */
9824+static void pk11_fork_parent(void)
9825+	{
9826+#ifndef NOPTHREADS
9827+	int i;
9828+
9829+	if (!pk11_library_initialized)
9830+		return;
9831+
9832+	for (i = OP_MAX - 1; i >= 0; i--)
9833+		{
9834+		OPENSSL_assert(pthread_mutex_unlock(session_cache[i].lock) == 0);
9835+		}
9836+	UNLOCK_OBJSTORE(OP_RSA);
9837+	OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
9838+#endif
9839+	}
9840+
9841+/*
9842+ * same situation as in parent - we need to unlock all locks to make them
9843+ * accessible to all threads.
9844+ */
9845+static void pk11_fork_child(void)
9846+	{
9847+#ifndef NOPTHREADS
9848+	int i;
9849+
9850+	if (!pk11_library_initialized)
9851+		return;
9852+
9853+	for (i = OP_MAX - 1; i >= 0; i--)
9854+		{
9855+		OPENSSL_assert(pthread_mutex_unlock(session_cache[i].lock) == 0);
9856+		}
9857+	UNLOCK_OBJSTORE(OP_RSA);
9858+	OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
9859+#endif
9860+	}
9861+
9862+/* Initialization function for the pk11 engine */
9863+static int pk11_init(ENGINE *e)
9864+{
9865+	return (pk11_library_init(e));
9866+}
9867+
9868+static CK_C_INITIALIZE_ARGS pk11_init_args =
9869+	{
9870+	NULL_PTR,		/* CreateMutex */
9871+	NULL_PTR,		/* DestroyMutex */
9872+	NULL_PTR,		/* LockMutex */
9873+	NULL_PTR,		/* UnlockMutex */
9874+	CKF_OS_LOCKING_OK,	/* flags */
9875+	NULL_PTR,		/* pReserved */
9876+	};
9877+
9878+/*
9879+ * Initialization function. Sets up various PKCS#11 library components.
9880+ * It selects a slot based on predefined critiera. In the process, it also
9881+ * count how many ciphers and digests to support. Since the cipher and
9882+ * digest information is needed when setting default engine, this function
9883+ * needs to be called before calling ENGINE_set_default.
9884+ */
9885+/* ARGSUSED */
9886+static int pk11_library_init(ENGINE *e)
9887+	{
9888+	CK_C_GetFunctionList p;
9889+	CK_RV rv = CKR_OK;
9890+	CK_INFO info;
9891+	int any_slot_found;
9892+	int i;
9893+#ifndef OPENSSL_SYS_WIN32
9894+	struct sigaction sigint_act, sigterm_act, sighup_act;
9895+#endif
9896+
9897+	/*
9898+	 * pk11_library_initialized is set to 0 in pk11_finish() which
9899+	 * is called from ENGINE_finish(). However, if there is still
9900+	 * at least one existing functional reference to the engine
9901+	 * (see engine(3) for more information), pk11_finish() is
9902+	 * skipped. For example, this can happen if an application
9903+	 * forgets to clear one cipher context. In case of a fork()
9904+	 * when the application is finishing the engine so that it can
9905+	 * be reinitialized in the child, forgotten functional
9906+	 * reference causes pk11_library_initialized to stay 1. In
9907+	 * that case we need the PID check so that we properly
9908+	 * initialize the engine again.
9909+	 */
9910+	if (pk11_library_initialized)
9911+		{
9912+		if (pk11_pid == getpid())
9913+			{
9914+			return (1);
9915+			}
9916+		else
9917+			{
9918+			global_session = CK_INVALID_HANDLE;
9919+			/*
9920+			 * free the locks first to prevent memory leak in case
9921+			 * the application calls fork() without finishing the
9922+			 * engine first.
9923+			 */
9924+			pk11_free_all_locks();
9925+			}
9926+		}
9927+
9928+	if (pk11_dso == NULL)
9929+		{
9930+		PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
9931+		goto err;
9932+		}
9933+
9934+	/* get the C_GetFunctionList function from the loaded library */
9935+	p = (CK_C_GetFunctionList)DSO_bind_func(pk11_dso,
9936+		PK11_GET_FUNCTION_LIST);
9937+	if (!p)
9938+		{
9939+		PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
9940+		goto err;
9941+		}
9942+
9943+	/* get the full function list from the loaded library */
9944+	rv = p(&pFuncList);
9945+	if (rv != CKR_OK)
9946+		{
9947+		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE, rv);
9948+		goto err;
9949+		}
9950+
9951+#ifndef OPENSSL_SYS_WIN32
9952+	/* Not all PKCS#11 library are signal safe! */
9953+
9954+	(void) memset(&sigint_act, 0, sizeof(sigint_act));
9955+	(void) memset(&sigterm_act, 0, sizeof(sigterm_act));
9956+	(void) memset(&sighup_act, 0, sizeof(sighup_act));
9957+	(void) sigaction(SIGINT, NULL, &sigint_act);
9958+	(void) sigaction(SIGTERM, NULL, &sigterm_act);
9959+	(void) sigaction(SIGHUP, NULL, &sighup_act);
9960+#endif
9961+	rv = pFuncList->C_Initialize((CK_VOID_PTR)&pk11_init_args);
9962+#ifndef OPENSSL_SYS_WIN32
9963+	(void) sigaction(SIGINT, &sigint_act, NULL);
9964+	(void) sigaction(SIGTERM, &sigterm_act, NULL);
9965+	(void) sigaction(SIGHUP, &sighup_act, NULL);
9966+#endif
9967+	if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
9968+		{
9969+		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_INITIALIZE, rv);
9970+		goto err;
9971+		}
9972+
9973+	rv = pFuncList->C_GetInfo(&info);
9974+	if (rv != CKR_OK)
9975+		{
9976+		PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_GETINFO, rv);
9977+		goto err;
9978+		}
9979+
9980+	if (pk11_choose_slots(&any_slot_found) == 0)
9981+		goto err;
9982+
9983+	/*
9984+	 * The library we use, set in def_PK11_LIBNAME, may not offer any
9985+	 * slot(s). In that case, we must not proceed but we must not return an
9986+	 * error. The reason is that applications that try to set up the PKCS#11
9987+	 * engine don't exit on error during the engine initialization just
9988+	 * because no slot was present.
9989+	 */
9990+	if (any_slot_found == 0)
9991+		return (1);
9992+
9993+	if (global_session == CK_INVALID_HANDLE)
9994+		{
9995+		/* Open the global_session for the new process */
9996+		rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
9997+			NULL_PTR, NULL_PTR, &global_session);
9998+		if (rv != CKR_OK)
9999+			{
10000+			PK11err_add_data(PK11_F_LIBRARY_INIT,
10001+			    PK11_R_OPENSESSION, rv);
10002+			goto err;
10003+			}
10004+		}
10005+
10006+	pk11_library_initialized = TRUE;
10007+	pk11_pid = getpid();
10008+	/*
10009+	 * if initialization of the locks fails pk11_init_all_locks()
10010+	 * will do the cleanup.
10011+	 */
10012+	if (!pk11_init_all_locks())
10013+		goto err;
10014+	for (i = 0; i < OP_MAX; i++)
10015+		session_cache[i].head = NULL;
10016+	/*
10017+	 * initialize active lists. We only use active lists
10018+	 * for asymmetric ciphers.
10019+	 */
10020+	for (i = 0; i < OP_MAX; i++)
10021+		active_list[i] = NULL;
10022+
10023+#ifndef NOPTHREADS
10024+	if (!pk11_atfork_initialized)
10025+		{
10026+		if (pthread_atfork(pk11_fork_prepare, pk11_fork_parent,
10027+		    pk11_fork_child) != 0)
10028+			{
10029+			PK11err(PK11_F_LIBRARY_INIT, PK11_R_ATFORK_FAILED);
10030+			goto err;
10031+			}
10032+		pk11_atfork_initialized = TRUE;
10033+		}
10034+#endif
10035+
10036+	return (1);
10037+
10038+err:
10039+	return (0);
10040+	}
10041+
10042+/* Destructor (complements the "ENGINE_pk11()" constructor) */
10043+/* ARGSUSED */
10044+static int pk11_destroy(ENGINE *e)
10045+	{
10046+	free_PK11_LIBNAME();
10047+	ERR_unload_pk11_strings();
10048+	if (pk11_pin) {
10049+		memset(pk11_pin, 0, strlen(pk11_pin));
10050+		OPENSSL_free((void*)pk11_pin);
10051+	}
10052+	pk11_pin = NULL;
10053+	return (1);
10054+	}
10055+
10056+/*
10057+ * Termination function to clean up the session, the token, and the pk11
10058+ * library.
10059+ */
10060+/* ARGSUSED */
10061+static int pk11_finish(ENGINE *e)
10062+	{
10063+	int i;
10064+
10065+	if (pk11_pin) {
10066+		memset(pk11_pin, 0, strlen(pk11_pin));
10067+		OPENSSL_free((void*)pk11_pin);
10068+	}
10069+	pk11_pin = NULL;
10070+
10071+	if (pk11_dso == NULL)
10072+		{
10073+		PK11err(PK11_F_FINISH, PK11_R_NOT_LOADED);
10074+		goto err;
10075+		}
10076+
10077+	OPENSSL_assert(pFuncList != NULL);
10078+
10079+	if (pk11_free_all_sessions() == 0)
10080+		goto err;
10081+
10082+	/* free all active lists */
10083+	for (i = 0; i < OP_MAX; i++)
10084+		pk11_free_active_list(i);
10085+
10086+	pFuncList->C_CloseSession(global_session);
10087+	global_session = CK_INVALID_HANDLE;
10088+
10089+	/*
10090+	 * Since we are part of a library (libcrypto.so), calling this function
10091+	 * may have side-effects.
10092+	 */
10093+#if 0
10094+	pFuncList->C_Finalize(NULL);
10095+#endif
10096+
10097+	if (!DSO_free(pk11_dso))
10098+		{
10099+		PK11err(PK11_F_FINISH, PK11_R_DSO_FAILURE);
10100+		goto err;
10101+		}
10102+	pk11_dso = NULL;
10103+	pFuncList = NULL;
10104+	pk11_library_initialized = FALSE;
10105+	pk11_pid = 0;
10106+	/*
10107+	 * There is no way how to unregister atfork handlers (other than
10108+	 * unloading the library) so we just free the locks. For this reason
10109+	 * the atfork handlers check if the engine is initialized and bail out
10110+	 * immediately if not. This is necessary in case a process finishes
10111+	 * the engine before calling fork().
10112+	 */
10113+	pk11_free_all_locks();
10114+
10115+	return (1);
10116+
10117+err:
10118+	return (0);
10119+	}
10120+
10121+/* Standard engine interface function to set the dynamic library path */
10122+/* ARGSUSED */
10123+static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
10124+	{
10125+	int initialized = ((pk11_dso == NULL) ? 0 : 1);
10126+
10127+	switch (cmd)
10128+		{
10129+	case PK11_CMD_SO_PATH:
10130+		if (p == NULL)
10131+			{
10132+			PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
10133+			return (0);
10134+			}
10135+
10136+		if (initialized)
10137+			{
10138+			PK11err(PK11_F_CTRL, PK11_R_ALREADY_LOADED);
10139+			return (0);
10140+			}
10141+
10142+		return (set_PK11_LIBNAME((const char *)p));
10143+	case PK11_CMD_PIN:
10144+		if (pk11_pin) {
10145+			memset(pk11_pin, 0, strlen(pk11_pin));
10146+			OPENSSL_free((void*)pk11_pin);
10147+		}
10148+		pk11_pin = NULL;
10149+
10150+		if (p == NULL)
10151+			{
10152+			PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
10153+			return (0);
10154+			}
10155+
10156+		pk11_pin = BUF_strdup(p);
10157+		if (pk11_pin == NULL)
10158+			{
10159+			PK11err(PK11_F_GET_SESSION, PK11_R_MALLOC_FAILURE);
10160+			return (0);
10161+			}
10162+		return (1);
10163+	case PK11_CMD_SLOT:
10164+		SLOTID = (CK_SLOT_ID)i;
10165+#ifdef DEBUG_SLOT_SELECTION
10166+		fprintf(stderr, "%s: slot set\n", PK11_DBG);
10167+#endif
10168+		return (1);
10169+	default:
10170+		break;
10171+		}
10172+
10173+	PK11err(PK11_F_CTRL, PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED);
10174+
10175+	return (0);
10176+	}
10177+
10178+
10179+/* Required function by the engine random interface. It does nothing here */
10180+static void pk11_rand_cleanup(void)
10181+	{
10182+	return;
10183+	}
10184+
10185+/* ARGSUSED */
10186+static void pk11_rand_add(const void *buf, int num, double add)
10187+	{
10188+	PK11_SESSION *sp;
10189+
10190+	if ((sp = pk11_get_session(OP_RAND)) == NULL)
10191+		return;
10192+
10193+	/*
10194+	 * Ignore any errors (e.g. CKR_RANDOM_SEED_NOT_SUPPORTED) since
10195+	 * the calling functions do not care anyway
10196+	 */
10197+	pFuncList->C_SeedRandom(sp->session, (unsigned char *) buf, num);
10198+	pk11_return_session(sp, OP_RAND);
10199+
10200+	return;
10201+	}
10202+
10203+static void pk11_rand_seed(const void *buf, int num)
10204+	{
10205+	pk11_rand_add(buf, num, 0);
10206+	}
10207+
10208+static int pk11_rand_bytes(unsigned char *buf, int num)
10209+	{
10210+	CK_RV rv;
10211+	PK11_SESSION *sp;
10212+
10213+	if ((sp = pk11_get_session(OP_RAND)) == NULL)
10214+		return (0);
10215+
10216+	rv = pFuncList->C_GenerateRandom(sp->session, buf, num);
10217+	if (rv != CKR_OK)
10218+		{
10219+		PK11err_add_data(PK11_F_RAND_BYTES, PK11_R_GENERATERANDOM, rv);
10220+		pk11_return_session(sp, OP_RAND);
10221+		return (0);
10222+		}
10223+
10224+	pk11_return_session(sp, OP_RAND);
10225+	return (1);
10226+	}
10227+
10228+/* Required function by the engine random interface. It does nothing here */
10229+static int pk11_rand_status(void)
10230+	{
10231+	return (1);
10232+	}
10233+
10234+/* Free all BIGNUM structures from PK11_SESSION. */
10235+static void pk11_free_nums(PK11_SESSION *sp, PK11_OPTYPE optype)
10236+	{
10237+	switch (optype)
10238+		{
10239+		case OP_RSA:
10240+			if (sp->opdata_rsa_n_num != NULL)
10241+				{
10242+				BN_free(sp->opdata_rsa_n_num);
10243+				sp->opdata_rsa_n_num = NULL;
10244+				}
10245+			if (sp->opdata_rsa_e_num != NULL)
10246+				{
10247+				BN_free(sp->opdata_rsa_e_num);
10248+				sp->opdata_rsa_e_num = NULL;
10249+				}
10250+			if (sp->opdata_rsa_pn_num != NULL)
10251+				{
10252+				BN_free(sp->opdata_rsa_pn_num);
10253+				sp->opdata_rsa_pn_num = NULL;
10254+				}
10255+			if (sp->opdata_rsa_pe_num != NULL)
10256+				{
10257+				BN_free(sp->opdata_rsa_pe_num);
10258+				sp->opdata_rsa_pe_num = NULL;
10259+				}
10260+			if (sp->opdata_rsa_d_num != NULL)
10261+				{
10262+				BN_free(sp->opdata_rsa_d_num);
10263+				sp->opdata_rsa_d_num = NULL;
10264+				}
10265+			break;
10266+		default:
10267+			break;
10268+		}
10269+	}
10270+
10271+/*
10272+ * Get new PK11_SESSION structure ready for use. Every process must have
10273+ * its own freelist of PK11_SESSION structures so handle fork() here
10274+ * by destroying the old and creating new freelist.
10275+ * The returned PK11_SESSION structure is disconnected from the freelist.
10276+ */
10277+PK11_SESSION *
10278+pk11_get_session(PK11_OPTYPE optype)
10279+	{
10280+	PK11_SESSION *sp = NULL, *sp1, *freelist;
10281+#ifndef NOPTHREADS
10282+	pthread_mutex_t *freelist_lock = NULL;
10283+#endif
10284+	static pid_t pid = 0;
10285+	pid_t new_pid;
10286+	CK_RV rv;
10287+
10288+	switch (optype)
10289+		{
10290+		case OP_RSA:
10291+		case OP_DSA:
10292+		case OP_DH:
10293+		case OP_RAND:
10294+		case OP_DIGEST:
10295+		case OP_CIPHER:
10296+#ifndef NOPTHREADS
10297+			freelist_lock = session_cache[optype].lock;
10298+#endif
10299+			break;
10300+		default:
10301+			PK11err(PK11_F_GET_SESSION,
10302+				PK11_R_INVALID_OPERATION_TYPE);
10303+			return (NULL);
10304+		}
10305+#ifndef NOPTHREADS
10306+	OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
10307+#else
10308+	CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
10309+#endif
10310+
10311+	/*
10312+	 * Will use it to find out if we forked. We cannot use the PID field in
10313+	 * the session structure because we could get a newly allocated session
10314+	 * here, with no PID information.
10315+	 */
10316+	if (pid == 0)
10317+		pid = getpid();
10318+
10319+	freelist = session_cache[optype].head;
10320+	sp = freelist;
10321+
10322+	/*
10323+	 * If the free list is empty, allocate new unitialized (filled
10324+	 * with zeroes) PK11_SESSION structure otherwise return first
10325+	 * structure from the freelist.
10326+	 */
10327+	if (sp == NULL)
10328+		{
10329+		if ((sp = OPENSSL_malloc(sizeof (PK11_SESSION))) == NULL)
10330+			{
10331+			PK11err(PK11_F_GET_SESSION,
10332+				PK11_R_MALLOC_FAILURE);
10333+			goto err;
10334+			}
10335+		(void) memset(sp, 0, sizeof (PK11_SESSION));
10336+
10337+		/*
10338+		 * It is a new session so it will look like a cache miss to the
10339+		 * code below. So, we must not try to to destroy its members so
10340+		 * mark them as unused.
10341+		 */
10342+		sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
10343+		sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
10344+		}
10345+	else
10346+		{
10347+		freelist = sp->next;
10348+		}
10349+
10350+	/*
10351+	 * Check whether we have forked. In that case, we must get rid of all
10352+	 * inherited sessions and start allocating new ones.
10353+	 */
10354+	if (pid != (new_pid = getpid()))
10355+		{
10356+		pid = new_pid;
10357+
10358+		/*
10359+		 * We are a new process and thus need to free any inherited
10360+		 * PK11_SESSION objects aside from the first session (sp) which
10361+		 * is the only PK11_SESSION structure we will reuse (for the
10362+		 * head of the list).
10363+		 */
10364+		while ((sp1 = freelist) != NULL)
10365+			{
10366+			freelist = sp1->next;
10367+			/*
10368+			 * NOTE: we do not want to call pk11_free_all_sessions()
10369+			 * here because it would close underlying PKCS#11
10370+			 * sessions and destroy all objects.
10371+			 */
10372+			pk11_free_nums(sp1, optype);
10373+			OPENSSL_free(sp1);
10374+			}
10375+
10376+		/* we have to free the active list as well. */
10377+		pk11_free_active_list(optype);
10378+
10379+		/* Initialize the process */
10380+		rv = pFuncList->C_Initialize((CK_VOID_PTR)&pk11_init_args);
10381+		if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
10382+			{
10383+			PK11err_add_data(PK11_F_GET_SESSION, PK11_R_INITIALIZE,
10384+			    rv);
10385+			OPENSSL_free(sp);
10386+			sp = NULL;
10387+			goto err;
10388+			}
10389+
10390+		/*
10391+		 * Choose slot here since the slot table is different on this
10392+		 * process. If we are here then we must have found at least one
10393+		 * usable slot before so we don't need to check any_slot_found.
10394+		 * See pk11_library_init()'s usage of this function for more
10395+		 * information.
10396+		 */
10397+		if (pk11_choose_slots(NULL) == 0)
10398+			goto err;
10399+
10400+		/* Open the global_session for the new process */
10401+		rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
10402+			NULL_PTR, NULL_PTR, &global_session);
10403+		if (rv != CKR_OK)
10404+			{
10405+			PK11err_add_data(PK11_F_GET_SESSION, PK11_R_OPENSESSION,
10406+			    rv);
10407+			OPENSSL_free(sp);
10408+			sp = NULL;
10409+			goto err;
10410+			}
10411+
10412+		/*
10413+		 * It is an inherited session from our parent so it needs
10414+		 * re-initialization.
10415+		 */
10416+		if (pk11_setup_session(sp, optype) == 0)
10417+			{
10418+			OPENSSL_free(sp);
10419+			sp = NULL;
10420+			goto err;
10421+			}
10422+		if (pk11_token_relogin(sp->session) == 0)
10423+			{
10424+			/*
10425+			 * We will keep the session in the cache list and let
10426+			 * the caller cope with the situation.
10427+			 */
10428+			freelist = sp;
10429+			sp = NULL;
10430+			goto err;
10431+			}
10432+		}
10433+
10434+	if (sp->pid == 0)
10435+		{
10436+		/* It is a new session and needs initialization. */
10437+		if (pk11_setup_session(sp, optype) == 0)
10438+			{
10439+			OPENSSL_free(sp);
10440+			sp = NULL;
10441+			}
10442+		}
10443+
10444+	/* set new head for the list of PK11_SESSION objects */
10445+	session_cache[optype].head = freelist;
10446+
10447+err:
10448+	if (sp != NULL)
10449+		sp->next = NULL;
10450+
10451+#ifndef NOPTHREADS
10452+	OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
10453+#else
10454+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
10455+#endif
10456+
10457+	return (sp);
10458+	}
10459+
10460+
10461+void
10462+pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype)
10463+	{
10464+#ifndef NOPTHREADS
10465+	pthread_mutex_t *freelist_lock;
10466+#endif
10467+	PK11_SESSION *freelist;
10468+
10469+	/*
10470+	 * If this is a session from the parent it will be taken care of and
10471+	 * freed in pk11_get_session() as part of the post-fork clean up the
10472+	 * next time we will ask for a new session.
10473+	 */
10474+	if (sp == NULL || sp->pid != getpid())
10475+		return;
10476+
10477+	switch (optype)
10478+		{
10479+		case OP_RSA:
10480+		case OP_DSA:
10481+		case OP_DH:
10482+		case OP_RAND:
10483+		case OP_DIGEST:
10484+		case OP_CIPHER:
10485+#ifndef NOPTHREADS
10486+			freelist_lock = session_cache[optype].lock;
10487+#endif
10488+			break;
10489+		default:
10490+			PK11err(PK11_F_RETURN_SESSION,
10491+				PK11_R_INVALID_OPERATION_TYPE);
10492+			return;
10493+		}
10494+
10495+#ifndef NOPTHREADS
10496+	OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
10497+#else
10498+	CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
10499+#endif
10500+	freelist = session_cache[optype].head;
10501+	sp->next = freelist;
10502+	session_cache[optype].head = sp;
10503+#ifndef NOPTHREADS
10504+	OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
10505+#else
10506+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
10507+#endif
10508+	}
10509+
10510+
10511+/* Destroy all objects. This function is called when the engine is finished */
10512+static int pk11_free_all_sessions()
10513+	{
10514+	int ret = 1;
10515+	int type;
10516+
10517+	(void) pk11_destroy_rsa_key_objects(NULL);
10518+
10519+	/*
10520+	 * We try to release as much as we can but any error means that we will
10521+	 * return 0 on exit.
10522+	 */
10523+	for (type = 0; type < OP_MAX; type++)
10524+		{
10525+		if (pk11_free_session_list(type) == 0)
10526+			ret = 0;
10527+		}
10528+
10529+	return (ret);
10530+	}
10531+
10532+/*
10533+ * Destroy session structures from the linked list specified. Free as many
10534+ * sessions as possible but any failure in C_CloseSession() means that we
10535+ * return an error on return.
10536+ */
10537+static int pk11_free_session_list(PK11_OPTYPE optype)
10538+	{
10539+	CK_RV rv;
10540+	PK11_SESSION *sp = NULL;
10541+	PK11_SESSION *freelist = NULL;
10542+	pid_t mypid = getpid();
10543+#ifndef NOPTHREADS
10544+	pthread_mutex_t *freelist_lock;
10545+#endif
10546+	int ret = 1;
10547+
10548+	switch (optype)
10549+		{
10550+		case OP_RSA:
10551+		case OP_DSA:
10552+		case OP_DH:
10553+		case OP_RAND:
10554+		case OP_DIGEST:
10555+		case OP_CIPHER:
10556+#ifndef NOPTHREADS
10557+			freelist_lock = session_cache[optype].lock;
10558+#endif
10559+			break;
10560+		default:
10561+			PK11err(PK11_F_FREE_ALL_SESSIONS,
10562+				PK11_R_INVALID_OPERATION_TYPE);
10563+			return (0);
10564+		}
10565+
10566+#ifndef NOPTHREADS
10567+	OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
10568+#else
10569+	CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
10570+#endif
10571+	freelist = session_cache[optype].head;
10572+	while ((sp = freelist) != NULL)
10573+		{
10574+		if (sp->session != CK_INVALID_HANDLE && sp->pid == mypid)
10575+			{
10576+			rv = pFuncList->C_CloseSession(sp->session);
10577+			if (rv != CKR_OK)
10578+				{
10579+				PK11err_add_data(PK11_F_FREE_ALL_SESSIONS,
10580+					PK11_R_CLOSESESSION, rv);
10581+				ret = 0;
10582+				}
10583+			}
10584+		freelist = sp->next;
10585+		pk11_free_nums(sp, optype);
10586+		OPENSSL_free(sp);
10587+		}
10588+
10589+#ifndef NOPTHREADS
10590+	OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
10591+#else
10592+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
10593+#endif
10594+	return (ret);
10595+	}
10596+
10597+
10598+static int
10599+pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype)
10600+	{
10601+	CK_RV rv;
10602+	CK_SLOT_ID myslot;
10603+
10604+	switch (optype)
10605+		{
10606+		case OP_RSA:
10607+			myslot = pubkey_SLOTID;
10608+			break;
10609+		case OP_RAND:
10610+			myslot = rand_SLOTID;
10611+			break;
10612+		default:
10613+			PK11err(PK11_F_SETUP_SESSION,
10614+			    PK11_R_INVALID_OPERATION_TYPE);
10615+			return (0);
10616+		}
10617+
10618+	sp->session = CK_INVALID_HANDLE;
10619+#ifdef	DEBUG_SLOT_SELECTION
10620+	fprintf(stderr, "%s: myslot=%d optype=%d\n", PK11_DBG, myslot, optype);
10621+#endif	/* DEBUG_SLOT_SELECTION */
10622+	rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
10623+		NULL_PTR, NULL_PTR, &sp->session);
10624+	if (rv == CKR_CRYPTOKI_NOT_INITIALIZED)
10625+		{
10626+		/*
10627+		 * We are probably a child process so force the
10628+		 * reinitialize of the session
10629+		 */
10630+		pk11_library_initialized = FALSE;
10631+		if (!pk11_library_init(NULL))
10632+			return (0);
10633+		rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
10634+			NULL_PTR, NULL_PTR, &sp->session);
10635+		}
10636+	if (rv != CKR_OK)
10637+		{
10638+		PK11err_add_data(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION, rv);
10639+		return (0);
10640+		}
10641+
10642+	sp->pid = getpid();
10643+
10644+	if (optype == OP_RSA)
10645+		{
10646+		sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
10647+		sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
10648+		sp->opdata_rsa_pub = NULL;
10649+		sp->opdata_rsa_n_num = NULL;
10650+		sp->opdata_rsa_e_num = NULL;
10651+		sp->opdata_rsa_priv = NULL;
10652+		sp->opdata_rsa_pn_num = NULL;
10653+		sp->opdata_rsa_pe_num = NULL;
10654+		sp->opdata_rsa_d_num = NULL;
10655+		}
10656+
10657+	/*
10658+	 * We always initialize the session as containing a non-persistent
10659+	 * object. The key load functions set it to persistent if that is so.
10660+	 */
10661+	sp->pub_persistent = CK_FALSE;
10662+	sp->priv_persistent = CK_FALSE;
10663+	return (1);
10664+	}
10665+
10666+/* Destroy RSA public key from single session. */
10667+int
10668+pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
10669+	{
10670+	int ret = 0;
10671+
10672+	if (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE)
10673+		{
10674+		TRY_OBJ_DESTROY(sp, sp->opdata_rsa_pub_key,
10675+		    ret, uselock, OP_RSA, CK_FALSE);
10676+		sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
10677+		sp->opdata_rsa_pub = NULL;
10678+		if (sp->opdata_rsa_n_num != NULL)
10679+			{
10680+			BN_free(sp->opdata_rsa_n_num);
10681+			sp->opdata_rsa_n_num = NULL;
10682+			}
10683+		if (sp->opdata_rsa_e_num != NULL)
10684+			{
10685+			BN_free(sp->opdata_rsa_e_num);
10686+			sp->opdata_rsa_e_num = NULL;
10687+			}
10688+		}
10689+
10690+	return (ret);
10691+	}
10692+
10693+/* Destroy RSA private key from single session. */
10694+int
10695+pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
10696+	{
10697+	int ret = 0;
10698+
10699+	if (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE)
10700+		{
10701+		TRY_OBJ_DESTROY(sp, sp->opdata_rsa_priv_key,
10702+		    ret, uselock, OP_RSA, CK_TRUE);
10703+		sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
10704+		sp->opdata_rsa_priv = NULL;
10705+		if (sp->opdata_rsa_d_num != NULL)
10706+			{
10707+			BN_free(sp->opdata_rsa_d_num);
10708+			sp->opdata_rsa_d_num = NULL;
10709+			}
10710+
10711+		/*
10712+		 * For the RSA key by reference code, public components 'n'/'e'
10713+		 * are the key components we use to check for the cache hit. We
10714+		 * must free those as well.
10715+		 */
10716+		if (sp->opdata_rsa_pn_num != NULL)
10717+			{
10718+			BN_free(sp->opdata_rsa_pn_num);
10719+			sp->opdata_rsa_pn_num = NULL;
10720+			}
10721+		if (sp->opdata_rsa_pe_num != NULL)
10722+			{
10723+			BN_free(sp->opdata_rsa_pe_num);
10724+			sp->opdata_rsa_pe_num = NULL;
10725+			}
10726+		}
10727+
10728+	return (ret);
10729+	}
10730+
10731+/*
10732+ * Destroy RSA key object wrapper. If session is NULL, try to destroy all
10733+ * objects in the free list.
10734+ */
10735+int
10736+pk11_destroy_rsa_key_objects(PK11_SESSION *session)
10737+	{
10738+	int ret = 1;
10739+	PK11_SESSION *sp = NULL;
10740+	PK11_SESSION *local_free_session;
10741+	CK_BBOOL uselock = TRUE;
10742+
10743+	if (session != NULL)
10744+		local_free_session = session;
10745+	else
10746+		{
10747+#ifndef NOPTHREADS
10748+		OPENSSL_assert(pthread_mutex_lock(session_cache[OP_RSA].lock) == 0);
10749+#else
10750+		CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
10751+#endif
10752+		local_free_session = session_cache[OP_RSA].head;
10753+		uselock = FALSE;
10754+		}
10755+
10756+	/*
10757+	 * go through the list of sessions and delete key objects
10758+	 */
10759+	while ((sp = local_free_session) != NULL)
10760+		{
10761+		local_free_session = sp->next;
10762+
10763+		/*
10764+		 * Do not terminate list traversal if one of the
10765+		 * destroy operations fails.
10766+		 */
10767+		if (pk11_destroy_rsa_object_pub(sp, uselock) == 0)
10768+			{
10769+			ret = 0;
10770+			continue;
10771+			}
10772+		if (pk11_destroy_rsa_object_priv(sp, uselock) == 0)
10773+			{
10774+			ret = 0;
10775+			continue;
10776+			}
10777+		}
10778+
10779+#ifndef NOPTHREADS
10780+	if (session == NULL)
10781+		OPENSSL_assert(pthread_mutex_unlock(session_cache[OP_RSA].lock) == 0);
10782+#else
10783+	if (session == NULL)
10784+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
10785+#endif
10786+
10787+	return (ret);
10788+	}
10789+
10790+static int
10791+pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
10792+	CK_BBOOL persistent)
10793+	{
10794+	CK_RV rv;
10795+
10796+	/*
10797+	 * We never try to destroy persistent objects which are the objects
10798+	 * stored in the keystore. Also, we always use read-only sessions so
10799+	 * C_DestroyObject() would be returning CKR_SESSION_READ_ONLY here.
10800+	 */
10801+	if (persistent == CK_TRUE)
10802+		return (1);
10803+
10804+	rv = pFuncList->C_DestroyObject(session, oh);
10805+	if (rv != CKR_OK)
10806+		{
10807+		PK11err_add_data(PK11_F_DESTROY_OBJECT, PK11_R_DESTROYOBJECT,
10808+		    rv);
10809+		return (0);
10810+		}
10811+
10812+	return (1);
10813+	}
10814+
10815+
10816+/*
10817+ * Public key mechanisms optionally supported
10818+ *
10819+ * CKM_RSA_PKCS
10820+ *
10821+ * The first slot that supports at least one of those mechanisms is chosen as a
10822+ * public key slot.
10823+ *
10824+ * The output of this function is a set of global variables indicating which
10825+ * mechanisms from RSA, DSA, DH and RAND are present, and also two arrays of
10826+ * mechanisms, one for symmetric ciphers and one for digests. Also, 3 global
10827+ * variables carry information about which slot was chosen for (a) public key
10828+ * mechanisms, (b) random operations, and (c) symmetric ciphers and digests.
10829+ */
10830+static int
10831+pk11_choose_slots(int *any_slot_found)
10832+	{
10833+	CK_SLOT_ID_PTR pSlotList = NULL_PTR;
10834+	CK_ULONG ulSlotCount = 0;
10835+	CK_MECHANISM_INFO mech_info;
10836+	CK_TOKEN_INFO token_info;
10837+	unsigned int i;
10838+	CK_RV rv;
10839+	CK_SLOT_ID best_slot_sofar = 0;
10840+	CK_BBOOL found_candidate_slot = CK_FALSE;
10841+	CK_SLOT_ID current_slot = 0;
10842+
10843+	/* let's initialize the output parameter */
10844+	if (any_slot_found != NULL)
10845+		*any_slot_found = 0;
10846+
10847+	/* Get slot list for memory allocation */
10848+	rv = pFuncList->C_GetSlotList(CK_FALSE, NULL_PTR, &ulSlotCount);
10849+
10850+	if (rv != CKR_OK)
10851+		{
10852+		PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
10853+		return (0);
10854+		}
10855+
10856+	/* it's not an error if we didn't find any providers */
10857+	if (ulSlotCount == 0)
10858+		{
10859+#ifdef	DEBUG_SLOT_SELECTION
10860+		fprintf(stderr, "%s: no crypto providers found\n", PK11_DBG);
10861+#endif	/* DEBUG_SLOT_SELECTION */
10862+		return (1);
10863+		}
10864+
10865+	pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
10866+
10867+	if (pSlotList == NULL)
10868+		{
10869+		PK11err(PK11_F_CHOOSE_SLOT, PK11_R_MALLOC_FAILURE);
10870+		return (0);
10871+		}
10872+
10873+	/* Get the slot list for processing */
10874+	rv = pFuncList->C_GetSlotList(CK_FALSE, pSlotList, &ulSlotCount);
10875+	if (rv != CKR_OK)
10876+		{
10877+		PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
10878+		OPENSSL_free(pSlotList);
10879+		return (0);
10880+		}
10881+
10882+#ifdef	DEBUG_SLOT_SELECTION
10883+	fprintf(stderr, "%s: provider: %s\n", PK11_DBG, def_PK11_LIBNAME);
10884+	fprintf(stderr, "%s: number of slots: %d\n", PK11_DBG, ulSlotCount);
10885+
10886+	fprintf(stderr, "%s: == checking rand slots ==\n", PK11_DBG);
10887+#endif	/* DEBUG_SLOT_SELECTION */
10888+	for (i = 0; i < ulSlotCount; i++)
10889+		{
10890+		current_slot = pSlotList[i];
10891+
10892+#ifdef	DEBUG_SLOT_SELECTION
10893+	fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
10894+#endif	/* DEBUG_SLOT_SELECTION */
10895+		/* Check if slot has random support. */
10896+		rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
10897+		if (rv != CKR_OK)
10898+			continue;
10899+
10900+#ifdef	DEBUG_SLOT_SELECTION
10901+	fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
10902+#endif	/* DEBUG_SLOT_SELECTION */
10903+
10904+		if (token_info.flags & CKF_RNG)
10905+			{
10906+#ifdef	DEBUG_SLOT_SELECTION
10907+	fprintf(stderr, "%s: this token has CKF_RNG flag\n", PK11_DBG);
10908+#endif	/* DEBUG_SLOT_SELECTION */
10909+			pk11_have_random = CK_TRUE;
10910+			rand_SLOTID = current_slot;
10911+			break;
10912+			}
10913+		}
10914+
10915+#ifdef	DEBUG_SLOT_SELECTION
10916+	fprintf(stderr, "%s: == checking pubkey slots ==\n", PK11_DBG);
10917+#endif	/* DEBUG_SLOT_SELECTION */
10918+
10919+	pubkey_SLOTID = pSlotList[0];
10920+	for (i = 0; i < ulSlotCount; i++)
10921+		{
10922+		CK_BBOOL slot_has_rsa = CK_FALSE;
10923+		current_slot = pSlotList[i];
10924+
10925+#ifdef	DEBUG_SLOT_SELECTION
10926+	fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
10927+#endif	/* DEBUG_SLOT_SELECTION */
10928+		rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
10929+		if (rv != CKR_OK)
10930+			continue;
10931+
10932+#ifdef	DEBUG_SLOT_SELECTION
10933+	fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
10934+#endif	/* DEBUG_SLOT_SELECTION */
10935+
10936+		/*
10937+		 * Check if this slot is capable of signing with CKM_RSA_PKCS.
10938+		 */
10939+		rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS,
10940+			&mech_info);
10941+
10942+		if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN)))
10943+			{
10944+			slot_has_rsa = CK_TRUE;
10945+			}
10946+
10947+		if (!found_candidate_slot && slot_has_rsa)
10948+			{
10949+#ifdef	DEBUG_SLOT_SELECTION
10950+			fprintf(stderr,
10951+			    "%s: potential slot: %d\n", PK11_DBG, current_slot);
10952+#endif	/* DEBUG_SLOT_SELECTION */
10953+			best_slot_sofar = current_slot;
10954+			pk11_have_rsa = slot_has_rsa;
10955+			found_candidate_slot = CK_TRUE;
10956+			/*
10957+			 * Cache the flags for later use. We might
10958+			 * need those if RSA keys by reference feature
10959+			 * is used.
10960+			 */
10961+			pubkey_token_flags = token_info.flags;
10962+#ifdef	DEBUG_SLOT_SELECTION
10963+			fprintf(stderr,
10964+			    "%s: setting found_candidate_slot to CK_TRUE\n",
10965+			    PK11_DBG);
10966+			fprintf(stderr,
10967+			    "%s: best so far slot: %d\n", PK11_DBG,
10968+			    best_slot_sofar);
10969+			fprintf(stderr, "%s: pubkey flags changed to "
10970+			    "%lu.\n", PK11_DBG, pubkey_token_flags);
10971+			}
10972+		else
10973+			{
10974+			fprintf(stderr,
10975+			    "%s: no rsa\n", PK11_DBG);
10976+			}
10977+#else
10978+			} /* if */
10979+#endif	/* DEBUG_SLOT_SELECTION */
10980+		} /* for */
10981+
10982+	if (found_candidate_slot == CK_TRUE)
10983+		{
10984+		pubkey_SLOTID = best_slot_sofar;
10985+		}
10986+
10987+	/*SLOTID = pSlotList[0];*/
10988+
10989+#ifdef	DEBUG_SLOT_SELECTION
10990+	fprintf(stderr,
10991+	    "%s: chosen pubkey slot: %d\n", PK11_DBG, pubkey_SLOTID);
10992+	fprintf(stderr,
10993+	    "%s: chosen rand slot: %d\n", PK11_DBG, rand_SLOTID);
10994+	fprintf(stderr,
10995+	    "%s: pk11_have_rsa %d\n", PK11_DBG, pk11_have_rsa);
10996+	fprintf(stderr,
10997+	    "%s: pk11_have_random %d\n", PK11_DBG, pk11_have_random);
10998+#endif	/* DEBUG_SLOT_SELECTION */
10999+
11000+	if (pSlotList != NULL)
11001+		OPENSSL_free(pSlotList);
11002+
11003+	if (any_slot_found != NULL)
11004+		*any_slot_found = 1;
11005+	return (1);
11006+	}
11007+
11008+#endif	/* OPENSSL_NO_HW_PK11SO */
11009+#endif	/* OPENSSL_NO_HW_PK11 */
11010+#endif	/* OPENSSL_NO_HW */
11011Index: openssl/crypto/engine/hw_pk11so.h
11012diff -u /dev/null openssl/crypto/engine/hw_pk11so.h:1.2.4.2
11013--- /dev/null	Fri Jan  2 13:56:41 2015
11014+++ openssl/crypto/engine/hw_pk11so.h	Wed Jun 15 21:12:32 2011
11015@@ -0,0 +1,32 @@
11016+/* Redefine all pk11/PK11 external symbols to pk11so/PK11SO */
11017+
11018+#define token_lock			pk11so_token_lock
11019+#define find_lock			pk11so_find_lock
11020+#define active_list			pk11so_active_list
11021+#define pubkey_token_flags		pk11so_pubkey_token_flags
11022+#define pubkey_SLOTID			pk11so_pubkey_SLOTID
11023+#define ERR_pk11_error			ERR_pk11so_error
11024+#define PK11err_add_data		PK11SOerr_add_data
11025+#define pk11_get_session		pk11so_get_session
11026+#define pk11_return_session		pk11so_return_session
11027+#define pk11_active_add			pk11so_active_add
11028+#define pk11_active_delete		pk11so_active_delete
11029+#define pk11_active_remove		pk11so_active_remove
11030+#define pk11_free_active_list		pk11so_free_active_list
11031+#define pk11_destroy_rsa_key_objects	pk11so_destroy_rsa_key_objects
11032+#define pk11_destroy_rsa_object_pub	pk11so_destroy_rsa_object_pub
11033+#define pk11_destroy_rsa_object_priv	pk11so_destroy_rsa_object_priv
11034+#define pk11_load_privkey		pk11so_load_privkey
11035+#define pk11_load_pubkey		pk11so_load_pubkey
11036+#define PK11_RSA			PK11SO_RSA
11037+#define pk11_destroy_dsa_key_objects	pk11so_destroy_dsa_key_objects
11038+#define pk11_destroy_dsa_object_pub	pk11so_destroy_dsa_object_pub
11039+#define pk11_destroy_dsa_object_priv	pk11so_destroy_dsa_object_priv
11040+#define PK11_DSA			PK11SO_DSA
11041+#define pk11_destroy_dh_key_objects	pk11so_destroy_dh_key_objects
11042+#define pk11_destroy_dh_object		pk11so_destroy_dh_object
11043+#define PK11_DH				PK11SO_DH
11044+#define pk11_token_relogin		pk11so_token_relogin
11045+#define pFuncList			pk11so_pFuncList
11046+#define pk11_pin			pk11so_pin
11047+#define ENGINE_load_pk11		ENGINE_load_pk11so
11048Index: openssl/crypto/engine/hw_pk11so_pub.c
11049diff -u /dev/null openssl/crypto/engine/hw_pk11so_pub.c:1.2.4.6
11050--- /dev/null	Fri Jan  2 13:56:41 2015
11051+++ openssl/crypto/engine/hw_pk11so_pub.c	Fri Oct  4 14:45:25 2013
11052@@ -0,0 +1,1642 @@
11053+/*
11054+ * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
11055+ * Use is subject to license terms.
11056+ */
11057+
11058+/* crypto/engine/hw_pk11_pub.c */
11059+/*
11060+ * This product includes software developed by the OpenSSL Project for
11061+ * use in the OpenSSL Toolkit (http://www.openssl.org/).
11062+ *
11063+ * This project also referenced hw_pkcs11-0.9.7b.patch written by
11064+ * Afchine Madjlessi.
11065+ */
11066+/*
11067+ * ====================================================================
11068+ * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
11069+ *
11070+ * Redistribution and use in source and binary forms, with or without
11071+ * modification, are permitted provided that the following conditions
11072+ * are met:
11073+ *
11074+ * 1. Redistributions of source code must retain the above copyright
11075+ *    notice, this list of conditions and the following disclaimer.
11076+ *
11077+ * 2. Redistributions in binary form must reproduce the above copyright
11078+ *    notice, this list of conditions and the following disclaimer in
11079+ *    the documentation and/or other materials provided with the
11080+ *    distribution.
11081+ *
11082+ * 3. All advertising materials mentioning features or use of this
11083+ *    software must display the following acknowledgment:
11084+ *    "This product includes software developed by the OpenSSL Project
11085+ *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
11086+ *
11087+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
11088+ *    endorse or promote products derived from this software without
11089+ *    prior written permission. For written permission, please contact
11090+ *    licensing@OpenSSL.org.
11091+ *
11092+ * 5. Products derived from this software may not be called "OpenSSL"
11093+ *    nor may "OpenSSL" appear in their names without prior written
11094+ *    permission of the OpenSSL Project.
11095+ *
11096+ * 6. Redistributions of any form whatsoever must retain the following
11097+ *    acknowledgment:
11098+ *    "This product includes software developed by the OpenSSL Project
11099+ *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
11100+ *
11101+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
11102+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
11103+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
11104+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
11105+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
11106+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
11107+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
11108+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
11109+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
11110+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
11111+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
11112+ * OF THE POSSIBILITY OF SUCH DAMAGE.
11113+ * ====================================================================
11114+ *
11115+ * This product includes cryptographic software written by Eric Young
11116+ * (eay@cryptsoft.com).  This product includes software written by Tim
11117+ * Hudson (tjh@cryptsoft.com).
11118+ *
11119+ */
11120+
11121+/* Modified to keep only RNG and RSA Sign */
11122+
11123+#ifdef OPENSSL_NO_RSA
11124+#error RSA is disabled
11125+#endif
11126+
11127+#include <stdio.h>
11128+#include <stdlib.h>
11129+#include <string.h>
11130+#include <sys/types.h>
11131+
11132+#include <openssl/e_os2.h>
11133+#include <openssl/crypto.h>
11134+#include <cryptlib.h>
11135+#include <openssl/engine.h>
11136+#include <openssl/dso.h>
11137+#include <openssl/err.h>
11138+#include <openssl/bn.h>
11139+#include <openssl/pem.h>
11140+#include <openssl/rsa.h>
11141+#include <openssl/rand.h>
11142+#include <openssl/objects.h>
11143+#include <openssl/x509.h>
11144+
11145+#ifdef OPENSSL_SYS_WIN32
11146+#define NOPTHREADS
11147+typedef int pid_t;
11148+#define HAVE_GETPASSPHRASE
11149+static char *getpassphrase(const char *prompt);
11150+#ifndef NULL_PTR
11151+#define NULL_PTR NULL
11152+#endif
11153+#define CK_DEFINE_FUNCTION(returnType, name) \
11154+	returnType __declspec(dllexport) name
11155+#define CK_DECLARE_FUNCTION(returnType, name) \
11156+	returnType __declspec(dllimport) name
11157+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
11158+	returnType __declspec(dllimport) (* name)
11159+#else
11160+#include <unistd.h>
11161+#endif
11162+
11163+#ifndef NOPTHREADS
11164+#include <pthread.h>
11165+#endif
11166+
11167+#ifndef OPENSSL_NO_HW
11168+#ifndef OPENSSL_NO_HW_PK11
11169+#ifndef OPENSSL_NO_HW_PK11SO
11170+
11171+#ifdef OPENSSL_SYS_WIN32
11172+#pragma pack(push, cryptoki, 1)
11173+#include "cryptoki.h"
11174+#include "pkcs11.h"
11175+#pragma pack(pop, cryptoki)
11176+#else
11177+#include "cryptoki.h"
11178+#include "pkcs11.h"
11179+#endif
11180+#include "hw_pk11so.h"
11181+#include "hw_pk11_err.h"
11182+
11183+static CK_BBOOL pk11_login_done = CK_FALSE;
11184+extern CK_SLOT_ID pubkey_SLOTID;
11185+#ifndef NOPTHREADS
11186+extern pthread_mutex_t *token_lock;
11187+#endif
11188+
11189+#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun)))
11190+#define getpassphrase(x)	getpass(x)
11191+#endif
11192+
11193+/* RSA stuff */
11194+static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
11195+	unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
11196+EVP_PKEY *pk11_load_privkey(ENGINE*, const char *privkey_file,
11197+	UI_METHOD *ui_method, void *callback_data);
11198+EVP_PKEY *pk11_load_pubkey(ENGINE*, const char *pubkey_file,
11199+	UI_METHOD *ui_method, void *callback_data);
11200+
11201+static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA* rsa, RSA** key_ptr,
11202+	BIGNUM **rsa_n_num, BIGNUM **rsa_e_num, CK_SESSION_HANDLE session);
11203+static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa, RSA** key_ptr,
11204+	BIGNUM **rsa_d_num, BIGNUM **rsa_n_num, BIGNUM **rsa_e_num,
11205+	CK_SESSION_HANDLE session);
11206+
11207+static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa);
11208+static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa);
11209+
11210+static int find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
11211+	CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey);
11212+static int init_template_value(BIGNUM *bn, CK_VOID_PTR *pValue,
11213+	CK_ULONG *ulValueLen);
11214+static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn);
11215+
11216+static int pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
11217+	CK_BBOOL is_private);
11218+
11219+/* Read mode string to be used for fopen() */
11220+#if SOLARIS_OPENSSL
11221+static char *read_mode_flags = "rF";
11222+#else
11223+static char *read_mode_flags = "r";
11224+#endif
11225+
11226+/*
11227+ * increment/create reference for an asymmetric key handle via active list
11228+ * manipulation. If active list operation fails, unlock (if locked), set error
11229+ * variable and jump to the specified label.
11230+ */
11231+#define	KEY_HANDLE_REFHOLD(key_handle, alg_type, unlock, var, label)	\
11232+	{								\
11233+	if (pk11_active_add(key_handle, alg_type) < 0)			\
11234+		{							\
11235+		var = TRUE;						\
11236+		if (unlock)						\
11237+			UNLOCK_OBJSTORE(alg_type);			\
11238+		goto label;						\
11239+		}							\
11240+	}
11241+
11242+/*
11243+ * Find active list entry according to object handle and return pointer to the
11244+ * entry otherwise return NULL.
11245+ *
11246+ * This function presumes it is called with lock protecting the active list
11247+ * held.
11248+ */
11249+static PK11_active *pk11_active_find(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
11250+	{
11251+	PK11_active *entry;
11252+
11253+	for (entry = active_list[type]; entry != NULL; entry = entry->next)
11254+		if (entry->h == h)
11255+			return (entry);
11256+
11257+	return (NULL);
11258+	}
11259+
11260+/*
11261+ * Search for an entry in the active list using PKCS#11 object handle as a
11262+ * search key and return refcnt of the found/created entry or -1 in case of
11263+ * failure.
11264+ *
11265+ * This function presumes it is called with lock protecting the active list
11266+ * held.
11267+ */
11268+int
11269+pk11_active_add(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
11270+	{
11271+	PK11_active *entry = NULL;
11272+
11273+	if (h == CK_INVALID_HANDLE)
11274+		{
11275+		PK11err(PK11_F_ACTIVE_ADD, PK11_R_INVALID_HANDLE);
11276+		return (-1);
11277+		}
11278+
11279+	/* search for entry in the active list */
11280+	if ((entry = pk11_active_find(h, type)) != NULL)
11281+		entry->refcnt++;
11282+	else
11283+		{
11284+		/* not found, create new entry and add it to the list */
11285+		entry = OPENSSL_malloc(sizeof (PK11_active));
11286+		if (entry == NULL)
11287+			{
11288+			PK11err(PK11_F_ACTIVE_ADD, PK11_R_MALLOC_FAILURE);
11289+			return (-1);
11290+			}
11291+		entry->h = h;
11292+		entry->refcnt = 1;
11293+		entry->prev = NULL;
11294+		entry->next = NULL;
11295+		/* connect the newly created entry to the list */
11296+		if (active_list[type] == NULL)
11297+			active_list[type] = entry;
11298+		else /* make the entry first in the list */
11299+			{
11300+			entry->next = active_list[type];
11301+			active_list[type]->prev = entry;
11302+			active_list[type] = entry;
11303+			}
11304+		}
11305+
11306+	return (entry->refcnt);
11307+	}
11308+
11309+/*
11310+ * Remove active list entry from the list and free it.
11311+ *
11312+ * This function presumes it is called with lock protecting the active list
11313+ * held.
11314+ */
11315+void
11316+pk11_active_remove(PK11_active *entry, PK11_OPTYPE type)
11317+	{
11318+	PK11_active *prev_entry;
11319+
11320+	/* remove the entry from the list and free it */
11321+	if ((prev_entry = entry->prev) != NULL)
11322+		{
11323+		prev_entry->next = entry->next;
11324+		if (entry->next != NULL)
11325+			entry->next->prev = prev_entry;
11326+		}
11327+	else
11328+		{
11329+		active_list[type] = entry->next;
11330+		/* we were the first but not the only one */
11331+		if (entry->next != NULL)
11332+			entry->next->prev = NULL;
11333+		}
11334+
11335+	/* sanitization */
11336+	entry->h = CK_INVALID_HANDLE;
11337+	entry->prev = NULL;
11338+	entry->next = NULL;
11339+	OPENSSL_free(entry);
11340+	}
11341+
11342+/* Free all entries from the active list. */
11343+void
11344+pk11_free_active_list(PK11_OPTYPE type)
11345+	{
11346+	PK11_active *entry;
11347+
11348+	/* only for asymmetric types since only they have C_Find* locks. */
11349+	switch (type)
11350+		{
11351+		case OP_RSA:
11352+			break;
11353+		default:
11354+			return;
11355+		}
11356+
11357+	/* see find_lock array definition for more info on object locking */
11358+	LOCK_OBJSTORE(type);
11359+	while ((entry = active_list[type]) != NULL)
11360+		pk11_active_remove(entry, type);
11361+	UNLOCK_OBJSTORE(type);
11362+	}
11363+
11364+/*
11365+ * Search for active list entry associated with given PKCS#11 object handle,
11366+ * decrement its refcnt and if it drops to 0, disconnect the entry and free it.
11367+ *
11368+ * Return 1 if the PKCS#11 object associated with the entry has no references,
11369+ * return 0 if there is at least one reference, -1 on error.
11370+ *
11371+ * This function presumes it is called with lock protecting the active list
11372+ * held.
11373+ */
11374+int
11375+pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
11376+	{
11377+	PK11_active *entry = NULL;
11378+
11379+	if ((entry = pk11_active_find(h, type)) == NULL)
11380+		{
11381+		PK11err(PK11_F_ACTIVE_DELETE, PK11_R_INVALID_HANDLE);
11382+		return (-1);
11383+		}
11384+
11385+	OPENSSL_assert(entry->refcnt > 0);
11386+	entry->refcnt--;
11387+	if (entry->refcnt == 0)
11388+		{
11389+		pk11_active_remove(entry, type);
11390+		return (1);
11391+		}
11392+
11393+	return (0);
11394+	}
11395+
11396+/* Our internal RSA_METHOD that we provide pointers to */
11397+static RSA_METHOD pk11_rsa;
11398+
11399+RSA_METHOD *
11400+PK11_RSA(void)
11401+	{
11402+	const RSA_METHOD *rsa;
11403+
11404+	if (pk11_rsa.name == NULL)
11405+		{
11406+		rsa = RSA_PKCS1_SSLeay();
11407+		memcpy(&pk11_rsa, rsa, sizeof(*rsa));
11408+		pk11_rsa.name = "PKCS#11 RSA method";
11409+		pk11_rsa.rsa_sign = pk11_RSA_sign;
11410+		}
11411+	return (&pk11_rsa);
11412+	}
11413+
11414+/* Size of an SSL signature: MD5+SHA1 */
11415+#define	SSL_SIG_LENGTH		36
11416+
11417+static CK_BBOOL mytrue = TRUE;
11418+static CK_BBOOL myfalse = FALSE;
11419+
11420+/*
11421+ * Standard engine interface function. Majority codes here are from
11422+ * rsa/rsa_sign.c. We replaced the decrypt function call by C_Sign of PKCS#11.
11423+ * See more details in rsa/rsa_sign.c
11424+ */
11425+static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
11426+	unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
11427+	{
11428+	X509_SIG sig;
11429+	ASN1_TYPE parameter;
11430+	int i, j = 0;
11431+	unsigned char *p, *s = NULL;
11432+	X509_ALGOR algor;
11433+	ASN1_OCTET_STRING digest;
11434+	CK_RV rv;
11435+	CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
11436+	CK_MECHANISM *p_mech = &mech_rsa;
11437+	CK_OBJECT_HANDLE h_priv_key;
11438+	PK11_SESSION *sp = NULL;
11439+	int ret = 0;
11440+	unsigned long ulsiglen;
11441+
11442+	/* Encode the digest */
11443+	/* Special case: SSL signature, just check the length */
11444+	if (type == NID_md5_sha1)
11445+		{
11446+		if (m_len != SSL_SIG_LENGTH)
11447+			{
11448+			PK11err(PK11_F_RSA_SIGN,
11449+				PK11_R_INVALID_MESSAGE_LENGTH);
11450+			goto err;
11451+			}
11452+		i = SSL_SIG_LENGTH;
11453+		s = (unsigned char *)m;
11454+		}
11455+	else
11456+		{
11457+		sig.algor = &algor;
11458+		sig.algor->algorithm = OBJ_nid2obj(type);
11459+		if (sig.algor->algorithm == NULL)
11460+			{
11461+			PK11err(PK11_F_RSA_SIGN,
11462+				PK11_R_UNKNOWN_ALGORITHM_TYPE);
11463+			goto err;
11464+			}
11465+		if (sig.algor->algorithm->length == 0)
11466+			{
11467+			PK11err(PK11_F_RSA_SIGN,
11468+				PK11_R_UNKNOWN_ASN1_OBJECT_ID);
11469+			goto err;
11470+			}
11471+		parameter.type = V_ASN1_NULL;
11472+		parameter.value.ptr = NULL;
11473+		sig.algor->parameter = &parameter;
11474+
11475+		sig.digest = &digest;
11476+		sig.digest->data = (unsigned char *)m;
11477+		sig.digest->length = m_len;
11478+
11479+		i = i2d_X509_SIG(&sig, NULL);
11480+		}
11481+
11482+	j = RSA_size(rsa);
11483+	if ((i - RSA_PKCS1_PADDING) > j)
11484+		{
11485+		PK11err(PK11_F_RSA_SIGN, PK11_R_DIGEST_TOO_BIG);
11486+		goto err;
11487+		}
11488+
11489+	if (type != NID_md5_sha1)
11490+		{
11491+		s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
11492+		if (s == NULL)
11493+			{
11494+			PK11err(PK11_F_RSA_SIGN, PK11_R_MALLOC_FAILURE);
11495+			goto err;
11496+			}
11497+		p = s;
11498+		(void) i2d_X509_SIG(&sig, &p);
11499+		}
11500+
11501+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
11502+		goto err;
11503+
11504+	(void) check_new_rsa_key_priv(sp, rsa);
11505+
11506+	h_priv_key = sp->opdata_rsa_priv_key;
11507+	if (h_priv_key == CK_INVALID_HANDLE)
11508+		h_priv_key = sp->opdata_rsa_priv_key =
11509+			pk11_get_private_rsa_key((RSA *)rsa,
11510+			    &sp->opdata_rsa_priv, &sp->opdata_rsa_d_num,
11511+			    &sp->opdata_rsa_pn_num, &sp->opdata_rsa_pe_num,
11512+			    sp->session);
11513+
11514+	if (h_priv_key != CK_INVALID_HANDLE)
11515+		{
11516+		rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
11517+
11518+		if (rv != CKR_OK)
11519+			{
11520+			PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGNINIT, rv);
11521+			goto err;
11522+			}
11523+
11524+		ulsiglen = j;
11525+		rv = pFuncList->C_Sign(sp->session, s, i, sigret,
11526+			(CK_ULONG_PTR) &ulsiglen);
11527+		*siglen = ulsiglen;
11528+
11529+		if (rv != CKR_OK)
11530+			{
11531+			PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGN, rv);
11532+			goto err;
11533+			}
11534+		ret = 1;
11535+		}
11536+
11537+err:
11538+	if ((type != NID_md5_sha1) && (s != NULL))
11539+		{
11540+		(void) memset(s, 0, (unsigned int)(j + 1));
11541+		OPENSSL_free(s);
11542+		}
11543+
11544+	pk11_return_session(sp, OP_RSA);
11545+	return (ret);
11546+	}
11547+
11548+static int hndidx_rsa = -1;
11549+
11550+#define	MAXATTR	1024
11551+
11552+/*
11553+ * Load RSA private key from a file or get its PKCS#11 handle if stored in the
11554+ * PKCS#11 token.
11555+ */
11556+/* ARGSUSED */
11557+EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *privkey_file,
11558+	UI_METHOD *ui_method, void *callback_data)
11559+	{
11560+	EVP_PKEY *pkey = NULL;
11561+	FILE *privkey;
11562+	CK_OBJECT_HANDLE  h_priv_key = CK_INVALID_HANDLE;
11563+	RSA *rsa = NULL;
11564+	PK11_SESSION *sp;
11565+	/* Anything else below is needed for the key by reference extension. */
11566+	CK_RV rv;
11567+	CK_BBOOL is_token = TRUE;
11568+	CK_BBOOL rollback = FALSE;
11569+	CK_BYTE attr_data[2][MAXATTR];
11570+	CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
11571+	CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;	/* key in keystore */
11572+
11573+	/* we look for private keys only */
11574+	CK_ATTRIBUTE search_templ[] =
11575+		{
11576+		{CKA_TOKEN, &is_token, sizeof(is_token)},
11577+		{CKA_CLASS, &key_class, sizeof(key_class)},
11578+		{CKA_LABEL, NULL, 0}
11579+		};
11580+
11581+	/*
11582+	 * These public attributes are needed to initialize the OpenSSL RSA
11583+	 * structure with something we can use to look up the key. Note that we
11584+	 * never ask for private components.
11585+	 */
11586+	CK_ATTRIBUTE get_templ[] =
11587+		{
11588+		{CKA_MODULUS, (void *)attr_data[0], MAXATTR},		/* n */
11589+		{CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},	/* e */
11590+		};
11591+
11592+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
11593+		return (NULL);
11594+
11595+	/*
11596+	 * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
11597+	 */
11598+	if (strstr(privkey_file, "pkcs11:") == privkey_file)
11599+		{
11600+		search_templ[2].pValue = strstr(privkey_file, ":") + 1;
11601+		search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
11602+
11603+		if (pk11_token_login(sp->session, &pk11_login_done,
11604+		    CK_TRUE) == 0)
11605+			goto err;
11606+
11607+		/* see find_lock array definition
11608+		   for more info on object locking */
11609+		LOCK_OBJSTORE(OP_RSA);
11610+
11611+		/*
11612+		 * Now let's try to find the key in the token. It is a failure
11613+		 * if we can't find it.
11614+		 */
11615+		if (find_one_object(OP_RSA, sp->session, search_templ, 3,
11616+		    &ks_key) == 0)
11617+			{
11618+			UNLOCK_OBJSTORE(OP_RSA);
11619+			goto err;
11620+			}
11621+
11622+		if (hndidx_rsa == -1)
11623+			hndidx_rsa = RSA_get_ex_new_index(0,
11624+				        "pkcs11 RSA HSM key handle",
11625+					NULL, NULL, NULL);
11626+
11627+		/*
11628+		 * We might have a cache hit which we could confirm
11629+		 * according to the 'n'/'e' params, RSA public pointer
11630+		 * as NULL, and non-NULL RSA private pointer. However,
11631+		 * it is easier just to recreate everything. We expect
11632+		 * the keys to be loaded once and used many times. We
11633+		 * do not check the return value because even in case
11634+		 * of failure the sp structure will have both key
11635+		 * pointer and object handle cleaned and
11636+		 * pk11_destroy_object() reports the failure to the
11637+		 * OpenSSL error message buffer.
11638+		 */
11639+		(void) pk11_destroy_rsa_object_priv(sp, FALSE);
11640+
11641+		sp->opdata_rsa_priv_key = ks_key;
11642+		/* This object shall not be deleted on a cache miss. */
11643+		sp->priv_persistent = CK_TRUE;
11644+
11645+		/*
11646+		 * Cache the RSA private structure pointer. We do not
11647+		 * use it now for key-by-ref keys but let's do it for
11648+		 * consistency reasons.
11649+		 */
11650+		if ((rsa = sp->opdata_rsa_priv = RSA_new_method(e)) == NULL)
11651+			{
11652+			UNLOCK_OBJSTORE(OP_RSA);
11653+			goto err;
11654+			}
11655+
11656+		/*
11657+		 * Now we have to initialize an OpenSSL RSA structure,
11658+		 * everything else is 0 or NULL.
11659+		 */
11660+		rsa->flags = RSA_FLAG_SIGN_VER | RSA_FLAG_EXT_PKEY;
11661+		RSA_set_ex_data(rsa, hndidx_rsa, (void *) ks_key);
11662+
11663+		if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
11664+		    get_templ, 2)) != CKR_OK)
11665+			{
11666+			UNLOCK_OBJSTORE(OP_RSA);
11667+			PK11err_add_data(PK11_F_LOAD_PRIVKEY,
11668+					 PK11_R_GETATTRIBUTVALUE, rv);
11669+			goto err;
11670+			}
11671+
11672+		/*
11673+		 * We do not use pk11_get_private_rsa_key() here so we
11674+		 * must take care of handle management ourselves.
11675+		 */
11676+		KEY_HANDLE_REFHOLD(ks_key, OP_RSA, TRUE, rollback, err);
11677+
11678+		/*
11679+		 * Those are the sensitive components we do not want to export
11680+		 * from the token at all: rsa->(d|p|q|dmp1|dmq1|iqmp).
11681+		 */
11682+		attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
11683+		attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
11684+		/*
11685+		 * Must have 'n'/'e' components in the session structure as
11686+		 * well. They serve as a public look-up key for the private key
11687+		 * in the keystore.
11688+		 */
11689+		attr_to_BN(&get_templ[0], attr_data[0],
11690+			&sp->opdata_rsa_pn_num);
11691+		attr_to_BN(&get_templ[1], attr_data[1],
11692+			&sp->opdata_rsa_pe_num);
11693+
11694+		UNLOCK_OBJSTORE(OP_RSA);
11695+
11696+		if ((pkey = EVP_PKEY_new()) == NULL)
11697+			goto err;
11698+
11699+		if (EVP_PKEY_assign_RSA(pkey, rsa) == 0)
11700+			goto err;
11701+		}
11702+	else if ((privkey = fopen(privkey_file, read_mode_flags)) != NULL)
11703+		{
11704+		pkey = PEM_read_PrivateKey(privkey, NULL, NULL, NULL);
11705+		(void) fclose(privkey);
11706+		if (pkey != NULL)
11707+			{
11708+			rsa = EVP_PKEY_get1_RSA(pkey);
11709+			if (rsa != NULL)
11710+				{
11711+				/*
11712+				 * This will always destroy the RSA
11713+				 * object since we have a new RSA
11714+				 * structure here.
11715+				 */
11716+				(void) check_new_rsa_key_priv(sp, rsa);
11717+				sp->priv_persistent = CK_FALSE;
11718+
11719+				h_priv_key = sp->opdata_rsa_priv_key =
11720+				    pk11_get_private_rsa_key(rsa,
11721+				    &sp->opdata_rsa_priv,
11722+				    &sp->opdata_rsa_d_num,
11723+				    &sp->opdata_rsa_pn_num,
11724+				    &sp->opdata_rsa_pe_num, sp->session);
11725+				if (h_priv_key == CK_INVALID_HANDLE)
11726+					goto err;
11727+				}
11728+			else
11729+				goto err;
11730+			}
11731+		}
11732+
11733+	pk11_return_session(sp, OP_RSA);
11734+	return (pkey);
11735+err:
11736+	pk11_return_session(sp, OP_RSA);
11737+	if (rsa != NULL)
11738+		RSA_free(rsa);
11739+	if (pkey != NULL)
11740+		{
11741+		EVP_PKEY_free(pkey);
11742+		pkey = NULL;
11743+		}
11744+	rollback = rollback;
11745+	return (pkey);
11746+	}
11747+
11748+/*
11749+ * Load RSA public key from a file or get its PKCS#11 handle if stored in the
11750+ * PKCS#11 token.
11751+ */
11752+/* ARGSUSED */
11753+EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
11754+	UI_METHOD *ui_method, void *callback_data)
11755+	{
11756+	EVP_PKEY *pkey = NULL;
11757+	FILE *pubkey;
11758+	CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
11759+	RSA *rsa = NULL;
11760+	PK11_SESSION *sp;
11761+	/* Anything else below is needed for the key by reference extension. */
11762+	CK_RV rv;
11763+	CK_BBOOL is_token = TRUE;
11764+	CK_BYTE attr_data[2][MAXATTR];
11765+	CK_OBJECT_CLASS key_class = CKO_PUBLIC_KEY;
11766+	CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;	/* key in keystore */
11767+
11768+	/* we look for public keys only */
11769+	CK_ATTRIBUTE search_templ[] =
11770+		{
11771+		{CKA_TOKEN, &is_token, sizeof(is_token)},
11772+		{CKA_CLASS, &key_class, sizeof(key_class)},
11773+		{CKA_LABEL, NULL, 0}
11774+		};
11775+
11776+	/*
11777+	 * These public attributes are needed to initialize OpenSSL RSA
11778+	 * structure with something we can use to look up the key.
11779+	 */
11780+	CK_ATTRIBUTE get_templ[] =
11781+		{
11782+		{CKA_MODULUS, (void *)attr_data[0], MAXATTR},		/* n */
11783+		{CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},	/* e */
11784+		};
11785+
11786+	if ((sp = pk11_get_session(OP_RSA)) == NULL)
11787+		return (NULL);
11788+
11789+	/*
11790+	 * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
11791+	 */
11792+	if (strstr(pubkey_file, "pkcs11:") == pubkey_file)
11793+		{
11794+		search_templ[2].pValue = strstr(pubkey_file, ":") + 1;
11795+		search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
11796+
11797+		if (pk11_token_login(sp->session, &pk11_login_done,
11798+		    CK_FALSE) == 0)
11799+			goto err;
11800+
11801+		/* see find_lock array definition
11802+		   for more info on object locking */
11803+		LOCK_OBJSTORE(OP_RSA);
11804+
11805+		/*
11806+		 * Now let's try to find the key in the token. It is a failure
11807+		 * if we can't find it.
11808+		 */
11809+		if (find_one_object(OP_RSA, sp->session, search_templ, 3,
11810+		    &ks_key) == 0)
11811+			{
11812+			UNLOCK_OBJSTORE(OP_RSA);
11813+			goto err;
11814+			}
11815+
11816+		/*
11817+		 * We load a new public key so we will create a new RSA
11818+		 * structure. No cache hit is possible.
11819+		 */
11820+		(void) pk11_destroy_rsa_object_pub(sp, FALSE);
11821+
11822+		sp->opdata_rsa_pub_key = ks_key;
11823+		/* This object shall not be deleted on a cache miss. */
11824+		sp->pub_persistent = CK_TRUE;
11825+
11826+		/*
11827+		 * Cache the RSA public structure pointer.
11828+		 */
11829+		if ((rsa = sp->opdata_rsa_pub = RSA_new_method(e)) == NULL)
11830+			{
11831+			UNLOCK_OBJSTORE(OP_RSA);
11832+			goto err;
11833+			}
11834+
11835+		/*
11836+		 * Now we have to initialize an OpenSSL RSA structure,
11837+		 * everything else is 0 or NULL.
11838+		 */
11839+		rsa->flags = RSA_FLAG_SIGN_VER;
11840+
11841+		if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
11842+		    get_templ, 2)) != CKR_OK)
11843+			{
11844+			UNLOCK_OBJSTORE(OP_RSA);
11845+			PK11err_add_data(PK11_F_LOAD_PUBKEY,
11846+					 PK11_R_GETATTRIBUTVALUE, rv);
11847+			goto err;
11848+			}
11849+
11850+		attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
11851+		attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
11852+
11853+		UNLOCK_OBJSTORE(OP_RSA);
11854+
11855+		if ((pkey = EVP_PKEY_new()) == NULL)
11856+			goto err;
11857+
11858+		if (EVP_PKEY_assign_RSA(pkey, rsa) == 0)
11859+			goto err;
11860+
11861+		/*
11862+		 * Create a session object from it so that when calling
11863+		 * pk11_get_public_rsa_key() the next time, we can find it. The
11864+		 * reason why we do that is that we cannot tell from the RSA
11865+		 * structure (OpenSSL RSA structure does not have any room for
11866+		 * additional data used by the engine, for example) if it bears
11867+		 * a public key stored in the keystore or not so it's better if
11868+		 * we always have a session key. Note that this is different
11869+		 * from what we do for the private keystore objects but in that
11870+		 * case, we can tell from the RSA structure that the keystore
11871+		 * object is in play - the 'd' component is NULL in that case.
11872+		 */
11873+		h_pub_key = sp->opdata_rsa_pub_key =
11874+		    pk11_get_public_rsa_key(rsa,
11875+		    &sp->opdata_rsa_pub, &sp->opdata_rsa_n_num,
11876+		    &sp->opdata_rsa_e_num, sp->session);
11877+		if (h_pub_key == CK_INVALID_HANDLE)
11878+			goto err;
11879+		}
11880+	else if ((pubkey = fopen(pubkey_file, read_mode_flags)) != NULL)
11881+		{
11882+		pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL);
11883+		(void) fclose(pubkey);
11884+		if (pkey != NULL)
11885+			{
11886+			rsa = EVP_PKEY_get1_RSA(pkey);
11887+			if (rsa != NULL)
11888+				{
11889+				/*
11890+				 * This will always destroy the RSA
11891+				 * object since we have a new RSA
11892+				 * structure here.
11893+				 */
11894+				(void) check_new_rsa_key_pub(sp, rsa);
11895+				sp->pub_persistent = CK_FALSE;
11896+
11897+				h_pub_key = sp->opdata_rsa_pub_key =
11898+				    pk11_get_public_rsa_key(rsa,
11899+				    &sp->opdata_rsa_pub, &sp->opdata_rsa_n_num,
11900+				    &sp->opdata_rsa_e_num, sp->session);
11901+				if (h_pub_key == CK_INVALID_HANDLE)
11902+					goto err;
11903+				}
11904+			else
11905+				goto err;
11906+			}
11907+		}
11908+
11909+	pk11_return_session(sp, OP_RSA);
11910+	return (pkey);
11911+err:
11912+	pk11_return_session(sp, OP_RSA);
11913+	if (rsa != NULL)
11914+		RSA_free(rsa);
11915+	if (pkey != NULL)
11916+		{
11917+		EVP_PKEY_free(pkey);
11918+		pkey = NULL;
11919+		}
11920+	return (pkey);
11921+	}
11922+
11923+/*
11924+ * Create a public key object in a session from a given rsa structure.
11925+ * The *rsa_n_num and *rsa_e_num pointers are non-NULL for RSA public keys.
11926+ */
11927+static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA *rsa,
11928+    RSA **key_ptr, BIGNUM **rsa_n_num, BIGNUM **rsa_e_num,
11929+    CK_SESSION_HANDLE session)
11930+	{
11931+	CK_RV rv;
11932+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
11933+	CK_ULONG found;
11934+	CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
11935+	CK_KEY_TYPE k_type = CKK_RSA;
11936+	CK_ULONG ul_key_attr_count = 8;
11937+	CK_BBOOL rollback = FALSE;
11938+
11939+	CK_ATTRIBUTE  a_key_template[] =
11940+		{
11941+		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
11942+		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
11943+		{CKA_TOKEN, &myfalse, sizeof (myfalse)},
11944+		{CKA_ENCRYPT, &mytrue, sizeof (mytrue)},
11945+		{CKA_VERIFY, &mytrue, sizeof (mytrue)},
11946+		{CKA_VERIFY_RECOVER, &mytrue, sizeof (mytrue)},
11947+		{CKA_MODULUS, (void *)NULL, 0},
11948+		{CKA_PUBLIC_EXPONENT, (void *)NULL, 0}
11949+		};
11950+
11951+	int i;
11952+
11953+	a_key_template[0].pValue = &o_key;
11954+	a_key_template[1].pValue = &k_type;
11955+
11956+	a_key_template[6].ulValueLen = BN_num_bytes(rsa->n);
11957+	a_key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
11958+		(size_t)a_key_template[6].ulValueLen);
11959+	if (a_key_template[6].pValue == NULL)
11960+		{
11961+		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
11962+		goto malloc_err;
11963+		}
11964+
11965+	BN_bn2bin(rsa->n, a_key_template[6].pValue);
11966+
11967+	a_key_template[7].ulValueLen = BN_num_bytes(rsa->e);
11968+	a_key_template[7].pValue = (CK_VOID_PTR)OPENSSL_malloc(
11969+		(size_t)a_key_template[7].ulValueLen);
11970+	if (a_key_template[7].pValue == NULL)
11971+		{
11972+		PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
11973+		goto malloc_err;
11974+		}
11975+
11976+	BN_bn2bin(rsa->e, a_key_template[7].pValue);
11977+
11978+	/* see find_lock array definition for more info on object locking */
11979+	LOCK_OBJSTORE(OP_RSA);
11980+
11981+	rv = pFuncList->C_FindObjectsInit(session, a_key_template,
11982+		ul_key_attr_count);
11983+
11984+	if (rv != CKR_OK)
11985+		{
11986+		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
11987+		    PK11_R_FINDOBJECTSINIT, rv);
11988+		goto err;
11989+		}
11990+
11991+	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
11992+
11993+	if (rv != CKR_OK)
11994+		{
11995+		(void) pFuncList->C_FindObjectsFinal(session);
11996+		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
11997+		    PK11_R_FINDOBJECTS, rv);
11998+		goto err;
11999+		}
12000+
12001+	rv = pFuncList->C_FindObjectsFinal(session);
12002+
12003+	if (rv != CKR_OK)
12004+		{
12005+		PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
12006+		    PK11_R_FINDOBJECTSFINAL, rv);
12007+		goto err;
12008+		}
12009+
12010+	if (found == 0)
12011+		{
12012+		rv = pFuncList->C_CreateObject(session,
12013+			a_key_template, ul_key_attr_count, &h_key);
12014+		if (rv != CKR_OK)
12015+			{
12016+			PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
12017+			    PK11_R_CREATEOBJECT, rv);
12018+			goto err;
12019+			}
12020+		}
12021+
12022+	if (rsa_n_num != NULL)
12023+		if ((*rsa_n_num = BN_dup(rsa->n)) == NULL)
12024+			{
12025+			PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
12026+			rollback = TRUE;
12027+			goto err;
12028+			}
12029+	if (rsa_e_num != NULL)
12030+		if ((*rsa_e_num = BN_dup(rsa->e)) == NULL)
12031+			{
12032+			PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
12033+			BN_free(*rsa_n_num);
12034+			*rsa_n_num = NULL;
12035+			rollback = TRUE;
12036+			goto err;
12037+			}
12038+
12039+	/* LINTED: E_CONSTANT_CONDITION */
12040+	KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
12041+	if (key_ptr != NULL)
12042+		*key_ptr = rsa;
12043+
12044+err:
12045+	if (rollback)
12046+		{
12047+		/*
12048+		 * We do not care about the return value from C_DestroyObject()
12049+		 * since we are doing rollback.
12050+		 */
12051+		if (found == 0)
12052+			(void) pFuncList->C_DestroyObject(session, h_key);
12053+		h_key = CK_INVALID_HANDLE;
12054+		}
12055+
12056+	UNLOCK_OBJSTORE(OP_RSA);
12057+
12058+malloc_err:
12059+	for (i = 6; i <= 7; i++)
12060+		{
12061+		if (a_key_template[i].pValue != NULL)
12062+			{
12063+			OPENSSL_free(a_key_template[i].pValue);
12064+			a_key_template[i].pValue = NULL;
12065+			}
12066+		}
12067+
12068+	return (h_key);
12069+	}
12070+
12071+/*
12072+ * Create a private key object in the session from a given rsa structure.
12073+ * The *rsa_d_num pointer is non-NULL for RSA private keys.
12074+ */
12075+static CK_OBJECT_HANDLE
12076+pk11_get_private_rsa_key(RSA *rsa, RSA **key_ptr, BIGNUM **rsa_d_num,
12077+    BIGNUM **rsa_n_num, BIGNUM **rsa_e_num, CK_SESSION_HANDLE session)
12078+	{
12079+	CK_RV rv;
12080+	CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
12081+	int i;
12082+	CK_ULONG found;
12083+	CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
12084+	CK_KEY_TYPE k_type = CKK_RSA;
12085+	CK_ULONG ul_key_attr_count = 14;
12086+	CK_BBOOL rollback = FALSE;
12087+
12088+	/* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys */
12089+	CK_ATTRIBUTE  a_key_template[] =
12090+		{
12091+		{CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
12092+		{CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
12093+		{CKA_TOKEN, &myfalse, sizeof (myfalse)},
12094+		{CKA_SENSITIVE, &myfalse, sizeof (myfalse)},
12095+		{CKA_DECRYPT, &mytrue, sizeof (mytrue)},
12096+		{CKA_SIGN, &mytrue, sizeof (mytrue)},
12097+		{CKA_MODULUS, (void *)NULL, 0},
12098+		{CKA_PUBLIC_EXPONENT, (void *)NULL, 0},
12099+		{CKA_PRIVATE_EXPONENT, (void *)NULL, 0},
12100+		{CKA_PRIME_1, (void *)NULL, 0},
12101+		{CKA_PRIME_2, (void *)NULL, 0},
12102+		{CKA_EXPONENT_1, (void *)NULL, 0},
12103+		{CKA_EXPONENT_2, (void *)NULL, 0},
12104+		{CKA_COEFFICIENT, (void *)NULL, 0},
12105+		};
12106+
12107+	if ((rsa->flags & RSA_FLAG_EXT_PKEY) != 0) {
12108+		h_key = (CK_OBJECT_HANDLE)RSA_get_ex_data(rsa, hndidx_rsa);
12109+		LOCK_OBJSTORE(OP_RSA);
12110+		goto set;
12111+	}
12112+
12113+	a_key_template[0].pValue = &o_key;
12114+	a_key_template[1].pValue = &k_type;
12115+
12116+	/* Put the private key components into the template */
12117+	if (init_template_value(rsa->n, &a_key_template[6].pValue,
12118+		&a_key_template[6].ulValueLen) == 0 ||
12119+	    init_template_value(rsa->e, &a_key_template[7].pValue,
12120+		&a_key_template[7].ulValueLen) == 0 ||
12121+	    init_template_value(rsa->d, &a_key_template[8].pValue,
12122+		&a_key_template[8].ulValueLen) == 0 ||
12123+	    init_template_value(rsa->p, &a_key_template[9].pValue,
12124+		&a_key_template[9].ulValueLen) == 0 ||
12125+	    init_template_value(rsa->q, &a_key_template[10].pValue,
12126+		&a_key_template[10].ulValueLen) == 0 ||
12127+	    init_template_value(rsa->dmp1, &a_key_template[11].pValue,
12128+		&a_key_template[11].ulValueLen) == 0 ||
12129+	    init_template_value(rsa->dmq1, &a_key_template[12].pValue,
12130+		&a_key_template[12].ulValueLen) == 0 ||
12131+	    init_template_value(rsa->iqmp, &a_key_template[13].pValue,
12132+		&a_key_template[13].ulValueLen) == 0)
12133+		{
12134+		PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
12135+		goto malloc_err;
12136+		}
12137+
12138+	/* see find_lock array definition for more info on object locking */
12139+	LOCK_OBJSTORE(OP_RSA);
12140+
12141+	/*
12142+	 * We are getting the private key but the private 'd'
12143+	 * component is NULL.  That means this is key by reference RSA
12144+	 * key. In that case, we can use only public components for
12145+	 * searching for the private key handle.
12146+	 */
12147+	if (rsa->d == NULL)
12148+		{
12149+		ul_key_attr_count = 8;
12150+		/*
12151+		 * We will perform the search in the token, not in the existing
12152+		 * session keys.
12153+		 */
12154+		a_key_template[2].pValue = &mytrue;
12155+		}
12156+
12157+	rv = pFuncList->C_FindObjectsInit(session, a_key_template,
12158+		ul_key_attr_count);
12159+
12160+	if (rv != CKR_OK)
12161+		{
12162+		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
12163+		    PK11_R_FINDOBJECTSINIT, rv);
12164+		goto err;
12165+		}
12166+
12167+	rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
12168+
12169+	if (rv != CKR_OK)
12170+		{
12171+		(void) pFuncList->C_FindObjectsFinal(session);
12172+		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
12173+		    PK11_R_FINDOBJECTS, rv);
12174+		goto err;
12175+		}
12176+
12177+	rv = pFuncList->C_FindObjectsFinal(session);
12178+
12179+	if (rv != CKR_OK)
12180+		{
12181+		PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
12182+		    PK11_R_FINDOBJECTSFINAL, rv);
12183+		goto err;
12184+		}
12185+
12186+	if (found == 0)
12187+		{
12188+		/*
12189+		 * We have an RSA structure with 'n'/'e' components
12190+		 * only so we tried to find the private key in the
12191+		 * keystore. If it was really a token key we have a
12192+		 * problem. Note that for other key types we just
12193+		 * create a new session key using the private
12194+		 * components from the RSA structure.
12195+		 */
12196+		if (rsa->d == NULL)
12197+			{
12198+			PK11err(PK11_F_GET_PRIV_RSA_KEY,
12199+			    PK11_R_PRIV_KEY_NOT_FOUND);
12200+			goto err;
12201+			}
12202+
12203+		rv = pFuncList->C_CreateObject(session,
12204+			a_key_template, ul_key_attr_count, &h_key);
12205+		if (rv != CKR_OK)
12206+			{
12207+			PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
12208+				PK11_R_CREATEOBJECT, rv);
12209+			goto err;
12210+			}
12211+		}
12212+
12213+set:
12214+	if (rsa_d_num != NULL)
12215+		{
12216+		/*
12217+		 * When RSA keys by reference code is used, we never
12218+		 * extract private components from the keystore. In
12219+		 * that case 'd' was set to NULL and we expect the
12220+		 * application to properly cope with that. It is
12221+		 * documented in openssl(5). In general, if keys by
12222+		 * reference are used we expect it to be used
12223+		 * exclusively using the high level API and then there
12224+		 * is no problem. If the application expects the
12225+		 * private components to be read from the keystore
12226+		 * then that is not a supported way of usage.
12227+		 */
12228+		if (rsa->d != NULL && (*rsa_d_num = BN_dup(rsa->d)) == NULL)
12229+			{
12230+			PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
12231+			rollback = TRUE;
12232+			goto err;
12233+			}
12234+		else
12235+			*rsa_d_num = NULL;
12236+		}
12237+
12238+	/*
12239+	 * For the key by reference code, we need public components as well
12240+	 * since 'd' component is always NULL. For that reason, we always cache
12241+	 * 'n'/'e' components as well.
12242+	 */
12243+	*rsa_n_num = BN_dup(rsa->n);
12244+	*rsa_e_num = BN_dup(rsa->e);
12245+
12246+	/* LINTED: E_CONSTANT_CONDITION */
12247+	KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
12248+	if (key_ptr != NULL)
12249+		*key_ptr = rsa;
12250+
12251+err:
12252+	if (rollback)
12253+		{
12254+		/*
12255+		 * We do not care about the return value from C_DestroyObject()
12256+		 * since we are doing rollback.
12257+		 */
12258+		if (found == 0 &&
12259+		    (rsa->flags & RSA_FLAG_EXT_PKEY) == 0)
12260+			(void) pFuncList->C_DestroyObject(session, h_key);
12261+		h_key = CK_INVALID_HANDLE;
12262+		}
12263+
12264+	UNLOCK_OBJSTORE(OP_RSA);
12265+
12266+malloc_err:
12267+	/*
12268+	 * 6 to 13 entries in the key template are key components.
12269+	 * They need to be freed upon exit or error.
12270+	 */
12271+	for (i = 6; i <= 13; i++)
12272+		{
12273+		if (a_key_template[i].pValue != NULL)
12274+			{
12275+			(void) memset(a_key_template[i].pValue, 0,
12276+				a_key_template[i].ulValueLen);
12277+			OPENSSL_free(a_key_template[i].pValue);
12278+			a_key_template[i].pValue = NULL;
12279+			}
12280+		}
12281+
12282+	return (h_key);
12283+	}
12284+
12285+/*
12286+ * Check for cache miss and clean the object pointer and handle
12287+ * in such case. Return 1 for cache hit, 0 for cache miss.
12288+ */
12289+static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa)
12290+	{
12291+	/*
12292+	 * Provide protection against RSA structure reuse by making the
12293+	 * check for cache hit stronger. Only public components of RSA
12294+	 * key matter here so it is sufficient to compare them with values
12295+	 * cached in PK11_SESSION structure.
12296+	 *
12297+	 * We must check the handle as well since with key by reference, public
12298+	 * components 'n'/'e' are cached in private keys as well. That means we
12299+	 * could have a cache hit in a private key when looking for a public
12300+	 * key. That would not work, you cannot have one PKCS#11 object for
12301+	 * both data signing and verifying.
12302+	 */
12303+	if ((sp->opdata_rsa_pub != rsa) ||
12304+	    (BN_cmp(sp->opdata_rsa_n_num, rsa->n) != 0) ||
12305+	    (BN_cmp(sp->opdata_rsa_e_num, rsa->e) != 0) ||
12306+	    (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE))
12307+		{
12308+		/*
12309+		 * We do not check the return value because even in case of
12310+		 * failure the sp structure will have both key pointer
12311+		 * and object handle cleaned and pk11_destroy_object()
12312+		 * reports the failure to the OpenSSL error message buffer.
12313+		 */
12314+		(void) pk11_destroy_rsa_object_pub(sp, TRUE);
12315+		return (0);
12316+		}
12317+	return (1);
12318+	}
12319+
12320+/*
12321+ * Check for cache miss and clean the object pointer and handle
12322+ * in such case. Return 1 for cache hit, 0 for cache miss.
12323+ */
12324+static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa)
12325+	{
12326+	/*
12327+	 * Provide protection against RSA structure reuse by making
12328+	 * the check for cache hit stronger. Comparing public exponent
12329+	 * of RSA key with value cached in PK11_SESSION structure
12330+	 * should be sufficient. Note that we want to compare the
12331+	 * public component since with the keys by reference
12332+	 * mechanism, private components are not in the RSA
12333+	 * structure. Also, see check_new_rsa_key_pub() about why we
12334+	 * compare the handle as well.
12335+	 */
12336+	if ((sp->opdata_rsa_priv != rsa) ||
12337+	    (BN_cmp(sp->opdata_rsa_pn_num, rsa->n) != 0) ||
12338+	    (BN_cmp(sp->opdata_rsa_pe_num, rsa->e) != 0) ||
12339+	    (sp->opdata_rsa_pn_num == NULL) ||
12340+	    (sp->opdata_rsa_pe_num == NULL) ||
12341+	    (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE))
12342+		{
12343+		/*
12344+		 * We do not check the return value because even in case of
12345+		 * failure the sp structure will have both key pointer
12346+		 * and object handle cleaned and pk11_destroy_object()
12347+		 * reports the failure to the OpenSSL error message buffer.
12348+		 */
12349+		(void) pk11_destroy_rsa_object_priv(sp, TRUE);
12350+		return (0);
12351+		}
12352+	return (1);
12353+	}
12354+
12355+/*
12356+ * Local function to simplify key template population
12357+ * Return 0 -- error, 1 -- no error
12358+ */
12359+static int
12360+init_template_value(BIGNUM *bn, CK_VOID_PTR *p_value,
12361+	CK_ULONG *ul_value_len)
12362+	{
12363+	CK_ULONG len = 0;
12364+
12365+	/*
12366+	 * This function can be used on non-initialized BIGNUMs. It is
12367+	 * easier to check that here than individually in the callers.
12368+	 */
12369+	if (bn != NULL)
12370+		len = BN_num_bytes(bn);
12371+
12372+	if (bn == NULL || len == 0)
12373+		return (1);
12374+
12375+	*ul_value_len = len;
12376+	*p_value = (CK_VOID_PTR)OPENSSL_malloc((size_t)*ul_value_len);
12377+	if (*p_value == NULL)
12378+		return (0);
12379+
12380+	BN_bn2bin(bn, *p_value);
12381+
12382+	return (1);
12383+	}
12384+
12385+static void
12386+attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn)
12387+	{
12388+	if (attr->ulValueLen > 0)
12389+		*bn = BN_bin2bn(attr_data, attr->ulValueLen, NULL);
12390+	}
12391+
12392+/*
12393+ * Find one object in the token. It is an error if we can not find the
12394+ * object or if we find more objects based on the template we got.
12395+ * Assume object store locked.
12396+ *
12397+ * Returns:
12398+ *	1 OK
12399+ *	0 no object or more than 1 object found
12400+ */
12401+static int
12402+find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
12403+    CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey)
12404+	{
12405+	CK_RV rv;
12406+	CK_ULONG objcnt;
12407+
12408+	if ((rv = pFuncList->C_FindObjectsInit(s, ptempl, nattr)) != CKR_OK)
12409+		{
12410+		PK11err_add_data(PK11_F_FIND_ONE_OBJECT,
12411+		    PK11_R_FINDOBJECTSINIT, rv);
12412+		return (0);
12413+		}
12414+
12415+	rv = pFuncList->C_FindObjects(s, pkey, 1, &objcnt);
12416+	if (rv != CKR_OK)
12417+		{
12418+		(void) pFuncList->C_FindObjectsFinal(s);
12419+		PK11err_add_data(PK11_F_FIND_ONE_OBJECT, PK11_R_FINDOBJECTS,
12420+		    rv);
12421+		return (0);
12422+		}
12423+
12424+	(void) pFuncList->C_FindObjectsFinal(s);
12425+
12426+	if (objcnt > 1)
12427+		{
12428+		PK11err(PK11_F_FIND_ONE_OBJECT,
12429+		    PK11_R_MORE_THAN_ONE_OBJECT_FOUND);
12430+		return (0);
12431+		}
12432+	else if (objcnt == 0)
12433+		{
12434+		PK11err(PK11_F_FIND_ONE_OBJECT, PK11_R_NO_OBJECT_FOUND);
12435+		return (0);
12436+		}
12437+	return (1);
12438+	}
12439+
12440+/* from uri stuff */
12441+
12442+extern char *pk11_pin;
12443+
12444+static int pk11_get_pin(void);
12445+
12446+static int
12447+pk11_get_pin(void)
12448+{
12449+	char *pin;
12450+
12451+	/* The getpassphrase() function is not MT safe. */
12452+#ifndef NOPTHREADS
12453+	OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
12454+#else
12455+	CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
12456+#endif
12457+	pin = getpassphrase("Enter PIN: ");
12458+	if (pin == NULL)
12459+		{
12460+		PK11err(PK11_F_GET_PIN, PK11_R_COULD_NOT_READ_PIN);
12461+#ifndef NOPTHREADS
12462+		OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12463+#else
12464+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12465+#endif
12466+		return (0);
12467+		}
12468+	pk11_pin = BUF_strdup(pin);
12469+	if (pk11_pin == NULL)
12470+		{
12471+		PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_MALLOC_FAILURE);
12472+#ifndef NOPTHREADS
12473+		OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12474+#else
12475+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12476+#endif
12477+		return (0);
12478+		}
12479+	memset(pin, 0, strlen(pin));
12480+#ifndef NOPTHREADS
12481+	OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12482+#else
12483+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12484+#endif
12485+	return (1);
12486+	}
12487+
12488+/*
12489+ * Log in to the keystore if we are supposed to do that at all. Take care of
12490+ * reading and caching the PIN etc. Log in only once even when called from
12491+ * multiple threads.
12492+ *
12493+ * Returns:
12494+ *	1 on success
12495+ *	0 on failure
12496+ */
12497+static int
12498+pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
12499+    CK_BBOOL is_private)
12500+	{
12501+	CK_RV rv;
12502+
12503+#if 0
12504+	/* doesn't work on the AEP Keyper??? */
12505+	if ((pubkey_token_flags & CKF_TOKEN_INITIALIZED) == 0)
12506+		{
12507+		PK11err(PK11_F_TOKEN_LOGIN,
12508+		    PK11_R_TOKEN_NOT_INITIALIZED);
12509+		return (0);
12510+		}
12511+#endif
12512+
12513+	/*
12514+	 * If login is required or needed but the PIN has not been
12515+	 * even initialized we can bail out right now. Note that we
12516+	 * are supposed to always log in if we are going to access
12517+	 * private keys. However, we may need to log in even for
12518+	 * accessing public keys in case that the CKF_LOGIN_REQUIRED
12519+	 * flag is set.
12520+	 */
12521+	if (((pubkey_token_flags & CKF_LOGIN_REQUIRED) ||
12522+	     (is_private == CK_TRUE)) &&
12523+	    (~pubkey_token_flags & CKF_USER_PIN_INITIALIZED))
12524+		{
12525+		PK11err(PK11_F_TOKEN_LOGIN, PK11_R_TOKEN_PIN_NOT_SET);
12526+		return (0);
12527+		}
12528+
12529+	/*
12530+	 * Note on locking: it is possible that more than one thread
12531+	 * gets into pk11_get_pin() so we must deal with that. We
12532+	 * cannot avoid it since we cannot guard fork() in there with
12533+	 * a lock because we could end up in a dead lock in the
12534+	 * child. Why? Remember we are in a multithreaded environment
12535+	 * so we must lock all mutexes in the prefork function to
12536+	 * avoid a situation in which a thread that did not call
12537+	 * fork() held a lock, making future unlocking impossible. We
12538+	 * lock right before C_Login().
12539+	 */
12540+	if ((pubkey_token_flags & CKF_LOGIN_REQUIRED) ||
12541+	    (is_private == CK_TRUE))
12542+		{
12543+		if (*login_done == CK_FALSE)
12544+			{
12545+			if ((pk11_pin == NULL) && (pk11_get_pin() == 0))
12546+				{
12547+				PK11err(PK11_F_TOKEN_LOGIN,
12548+				    PK11_R_TOKEN_PIN_NOT_PROVIDED);
12549+				return (0);
12550+				}
12551+			}
12552+
12553+		/*
12554+		 * Note that what we are logging into is the keystore from
12555+		 * pubkey_SLOTID because we work with OP_RSA session type here.
12556+		 * That also means that we can work with only one keystore in
12557+		 * the engine.
12558+		 *
12559+		 * We must make sure we do not try to login more than once.
12560+		 * Also, see the comment above on locking strategy.
12561+		 */
12562+
12563+#ifndef NOPTHREADS
12564+		OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
12565+#else
12566+		CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
12567+#endif
12568+		if (*login_done == CK_FALSE)
12569+			{
12570+			if ((rv = pFuncList->C_Login(session,
12571+			    CKU_USER, (CK_UTF8CHAR*)pk11_pin,
12572+			    strlen(pk11_pin))) != CKR_OK)
12573+				{
12574+				PK11err_add_data(PK11_F_TOKEN_LOGIN,
12575+				    PK11_R_TOKEN_LOGIN_FAILED, rv);
12576+				goto err_locked;
12577+				}
12578+
12579+			*login_done = CK_TRUE;
12580+
12581+			}
12582+#ifndef NOPTHREADS
12583+		OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12584+#else
12585+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12586+#endif
12587+		}
12588+	else
12589+		{
12590+			/*
12591+			 * If token does not require login we take it as the
12592+			 * login was done.
12593+			 */
12594+			*login_done = CK_TRUE;
12595+		}
12596+
12597+	return (1);
12598+
12599+err_locked:
12600+	if (pk11_pin) {
12601+		memset(pk11_pin, 0, strlen(pk11_pin));
12602+		OPENSSL_free((void*)pk11_pin);
12603+	}
12604+	pk11_pin = NULL;
12605+#ifndef NOPTHREADS
12606+	OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12607+#else
12608+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12609+#endif
12610+	return (0);
12611+	}
12612+
12613+/*
12614+ * Log in to the keystore in the child if we were logged in in the
12615+ * parent. There are similarities in the code with pk11_token_login()
12616+ * but still it is quite different so we need a separate function for
12617+ * this.
12618+ *
12619+ * Note that this function is called under the locked session mutex when fork is
12620+ * detected. That means that C_Login() will be called from the child just once.
12621+ *
12622+ * Returns:
12623+ *	1 on success
12624+ *	0 on failure
12625+ */
12626+int
12627+pk11_token_relogin(CK_SESSION_HANDLE session)
12628+	{
12629+	CK_RV rv;
12630+
12631+	if ((pk11_pin == NULL) && (pk11_get_pin() == 0))
12632+		return (0);
12633+
12634+#ifndef NOPTHREADS
12635+	OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
12636+#else
12637+	CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
12638+#endif
12639+	if ((rv = pFuncList->C_Login(session, CKU_USER,
12640+	    (CK_UTF8CHAR_PTR)pk11_pin, strlen(pk11_pin))) != CKR_OK)
12641+		{
12642+		PK11err_add_data(PK11_F_TOKEN_RELOGIN,
12643+		    PK11_R_TOKEN_LOGIN_FAILED, rv);
12644+#ifndef NOPTHREADS
12645+		OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12646+#else
12647+		CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12648+#endif
12649+		return (0);
12650+		}
12651+#ifndef NOPTHREADS
12652+	OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12653+#else
12654+	CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12655+#endif
12656+
12657+	return (1);
12658+	}
12659+
12660+#ifdef	OPENSSL_SYS_WIN32
12661+char *getpassphrase(const char *prompt)
12662+	{
12663+	static char buf[128];
12664+	HANDLE h;
12665+	DWORD cc, mode;
12666+	int cnt;
12667+
12668+	h = GetStdHandle(STD_INPUT_HANDLE);
12669+	fputs(prompt, stderr);
12670+	fflush(stderr);
12671+	fflush(stdout);
12672+	FlushConsoleInputBuffer(h);
12673+	GetConsoleMode(h, &mode);
12674+	SetConsoleMode(h, ENABLE_PROCESSED_INPUT);
12675+
12676+	for (cnt = 0; cnt < sizeof(buf) - 1; cnt++)
12677+		{
12678+		ReadFile(h, buf + cnt, 1, &cc, NULL);
12679+		if (buf[cnt] == '\r')
12680+			break;
12681+		fputc('*', stdout);
12682+		fflush(stderr);
12683+		fflush(stdout);
12684+		}
12685+
12686+	SetConsoleMode(h, mode);
12687+	buf[cnt] = '\0';
12688+	fputs("\n", stderr);
12689+	return buf;
12690+	}
12691+#endif	/* OPENSSL_SYS_WIN32 */
12692+#endif	/* OPENSSL_NO_HW_PK11SO */
12693+#endif	/* OPENSSL_NO_HW_PK11 */
12694+#endif	/* OPENSSL_NO_HW */
12695Index: openssl/crypto/engine/pkcs11.h
12696diff -u /dev/null openssl/crypto/engine/pkcs11.h:1.1.1.1
12697--- /dev/null	Fri Jan  2 13:56:41 2015
12698+++ openssl/crypto/engine/pkcs11.h	Wed Oct 24 23:27:09 2007
12699@@ -0,0 +1,299 @@
12700+/* pkcs11.h include file for PKCS #11. */
12701+/* Revision: 1.1.1.1  */
12702+
12703+/* License to copy and use this software is granted provided that it is
12704+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
12705+ * (Cryptoki)" in all material mentioning or referencing this software.
12706+
12707+ * License is also granted to make and use derivative works provided that
12708+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
12709+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
12710+ * referencing the derived work.
12711+
12712+ * RSA Security Inc. makes no representations concerning either the
12713+ * merchantability of this software or the suitability of this software for
12714+ * any particular purpose. It is provided "as is" without express or implied
12715+ * warranty of any kind.
12716+ */
12717+
12718+#ifndef _PKCS11_H_
12719+#define _PKCS11_H_ 1
12720+
12721+#ifdef __cplusplus
12722+extern "C" {
12723+#endif
12724+
12725+/* Before including this file (pkcs11.h) (or pkcs11t.h by
12726+ * itself), 6 platform-specific macros must be defined.  These
12727+ * macros are described below, and typical definitions for them
12728+ * are also given.  Be advised that these definitions can depend
12729+ * on both the platform and the compiler used (and possibly also
12730+ * on whether a Cryptoki library is linked statically or
12731+ * dynamically).
12732+ *
12733+ * In addition to defining these 6 macros, the packing convention
12734+ * for Cryptoki structures should be set.  The Cryptoki
12735+ * convention on packing is that structures should be 1-byte
12736+ * aligned.
12737+ *
12738+ * If you're using Microsoft Developer Studio 5.0 to produce
12739+ * Win32 stuff, this might be done by using the following
12740+ * preprocessor directive before including pkcs11.h or pkcs11t.h:
12741+ *
12742+ * #pragma pack(push, cryptoki, 1)
12743+ *
12744+ * and using the following preprocessor directive after including
12745+ * pkcs11.h or pkcs11t.h:
12746+ *
12747+ * #pragma pack(pop, cryptoki)
12748+ *
12749+ * If you're using an earlier version of Microsoft Developer
12750+ * Studio to produce Win16 stuff, this might be done by using
12751+ * the following preprocessor directive before including
12752+ * pkcs11.h or pkcs11t.h:
12753+ *
12754+ * #pragma pack(1)
12755+ *
12756+ * In a UNIX environment, you're on your own for this.  You might
12757+ * not need to do (or be able to do!) anything.
12758+ *
12759+ *
12760+ * Now for the macros:
12761+ *
12762+ *
12763+ * 1. CK_PTR: The indirection string for making a pointer to an
12764+ * object.  It can be used like this:
12765+ *
12766+ * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
12767+ *
12768+ * If you're using Microsoft Developer Studio 5.0 to produce
12769+ * Win32 stuff, it might be defined by:
12770+ *
12771+ * #define CK_PTR *
12772+ *
12773+ * If you're using an earlier version of Microsoft Developer
12774+ * Studio to produce Win16 stuff, it might be defined by:
12775+ *
12776+ * #define CK_PTR far *
12777+ *
12778+ * In a typical UNIX environment, it might be defined by:
12779+ *
12780+ * #define CK_PTR *
12781+ *
12782+ *
12783+ * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
12784+ * an exportable Cryptoki library function definition out of a
12785+ * return type and a function name.  It should be used in the
12786+ * following fashion to define the exposed Cryptoki functions in
12787+ * a Cryptoki library:
12788+ *
12789+ * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
12790+ *   CK_VOID_PTR pReserved
12791+ * )
12792+ * {
12793+ *   ...
12794+ * }
12795+ *
12796+ * If you're using Microsoft Developer Studio 5.0 to define a
12797+ * function in a Win32 Cryptoki .dll, it might be defined by:
12798+ *
12799+ * #define CK_DEFINE_FUNCTION(returnType, name) \
12800+ *   returnType __declspec(dllexport) name
12801+ *
12802+ * If you're using an earlier version of Microsoft Developer
12803+ * Studio to define a function in a Win16 Cryptoki .dll, it
12804+ * might be defined by:
12805+ *
12806+ * #define CK_DEFINE_FUNCTION(returnType, name) \
12807+ *   returnType __export _far _pascal name
12808+ *
12809+ * In a UNIX environment, it might be defined by:
12810+ *
12811+ * #define CK_DEFINE_FUNCTION(returnType, name) \
12812+ *   returnType name
12813+ *
12814+ *
12815+ * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
12816+ * an importable Cryptoki library function declaration out of a
12817+ * return type and a function name.  It should be used in the
12818+ * following fashion:
12819+ *
12820+ * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
12821+ *   CK_VOID_PTR pReserved
12822+ * );
12823+ *
12824+ * If you're using Microsoft Developer Studio 5.0 to declare a
12825+ * function in a Win32 Cryptoki .dll, it might be defined by:
12826+ *
12827+ * #define CK_DECLARE_FUNCTION(returnType, name) \
12828+ *   returnType __declspec(dllimport) name
12829+ *
12830+ * If you're using an earlier version of Microsoft Developer
12831+ * Studio to declare a function in a Win16 Cryptoki .dll, it
12832+ * might be defined by:
12833+ *
12834+ * #define CK_DECLARE_FUNCTION(returnType, name) \
12835+ *   returnType __export _far _pascal name
12836+ *
12837+ * In a UNIX environment, it might be defined by:
12838+ *
12839+ * #define CK_DECLARE_FUNCTION(returnType, name) \
12840+ *   returnType name
12841+ *
12842+ *
12843+ * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
12844+ * which makes a Cryptoki API function pointer declaration or
12845+ * function pointer type declaration out of a return type and a
12846+ * function name.  It should be used in the following fashion:
12847+ *
12848+ * // Define funcPtr to be a pointer to a Cryptoki API function
12849+ * // taking arguments args and returning CK_RV.
12850+ * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
12851+ *
12852+ * or
12853+ *
12854+ * // Define funcPtrType to be the type of a pointer to a
12855+ * // Cryptoki API function taking arguments args and returning
12856+ * // CK_RV, and then define funcPtr to be a variable of type
12857+ * // funcPtrType.
12858+ * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
12859+ * funcPtrType funcPtr;
12860+ *
12861+ * If you're using Microsoft Developer Studio 5.0 to access
12862+ * functions in a Win32 Cryptoki .dll, in might be defined by:
12863+ *
12864+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
12865+ *   returnType __declspec(dllimport) (* name)
12866+ *
12867+ * If you're using an earlier version of Microsoft Developer
12868+ * Studio to access functions in a Win16 Cryptoki .dll, it might
12869+ * be defined by:
12870+ *
12871+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
12872+ *   returnType __export _far _pascal (* name)
12873+ *
12874+ * In a UNIX environment, it might be defined by:
12875+ *
12876+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
12877+ *   returnType (* name)
12878+ *
12879+ *
12880+ * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
12881+ * a function pointer type for an application callback out of
12882+ * a return type for the callback and a name for the callback.
12883+ * It should be used in the following fashion:
12884+ *
12885+ * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
12886+ *
12887+ * to declare a function pointer, myCallback, to a callback
12888+ * which takes arguments args and returns a CK_RV.  It can also
12889+ * be used like this:
12890+ *
12891+ * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
12892+ * myCallbackType myCallback;
12893+ *
12894+ * If you're using Microsoft Developer Studio 5.0 to do Win32
12895+ * Cryptoki development, it might be defined by:
12896+ *
12897+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
12898+ *   returnType (* name)
12899+ *
12900+ * If you're using an earlier version of Microsoft Developer
12901+ * Studio to do Win16 development, it might be defined by:
12902+ *
12903+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
12904+ *   returnType _far _pascal (* name)
12905+ *
12906+ * In a UNIX environment, it might be defined by:
12907+ *
12908+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
12909+ *   returnType (* name)
12910+ *
12911+ *
12912+ * 6. NULL_PTR: This macro is the value of a NULL pointer.
12913+ *
12914+ * In any ANSI/ISO C environment (and in many others as well),
12915+ * this should best be defined by
12916+ *
12917+ * #ifndef NULL_PTR
12918+ * #define NULL_PTR 0
12919+ * #endif
12920+ */
12921+
12922+
12923+/* All the various Cryptoki types and #define'd values are in the
12924+ * file pkcs11t.h. */
12925+#include "pkcs11t.h"
12926+
12927+#define __PASTE(x,y)      x##y
12928+
12929+
12930+/* ==============================================================
12931+ * Define the "extern" form of all the entry points.
12932+ * ==============================================================
12933+ */
12934+
12935+#define CK_NEED_ARG_LIST  1
12936+#define CK_PKCS11_FUNCTION_INFO(name) \
12937+  extern CK_DECLARE_FUNCTION(CK_RV, name)
12938+
12939+/* pkcs11f.h has all the information about the Cryptoki
12940+ * function prototypes. */
12941+#include "pkcs11f.h"
12942+
12943+#undef CK_NEED_ARG_LIST
12944+#undef CK_PKCS11_FUNCTION_INFO
12945+
12946+
12947+/* ==============================================================
12948+ * Define the typedef form of all the entry points.  That is, for
12949+ * each Cryptoki function C_XXX, define a type CK_C_XXX which is
12950+ * a pointer to that kind of function.
12951+ * ==============================================================
12952+ */
12953+
12954+#define CK_NEED_ARG_LIST  1
12955+#define CK_PKCS11_FUNCTION_INFO(name) \
12956+  typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
12957+
12958+/* pkcs11f.h has all the information about the Cryptoki
12959+ * function prototypes. */
12960+#include "pkcs11f.h"
12961+
12962+#undef CK_NEED_ARG_LIST
12963+#undef CK_PKCS11_FUNCTION_INFO
12964+
12965+
12966+/* ==============================================================
12967+ * Define structed vector of entry points.  A CK_FUNCTION_LIST
12968+ * contains a CK_VERSION indicating a library's Cryptoki version
12969+ * and then a whole slew of function pointers to the routines in
12970+ * the library.  This type was declared, but not defined, in
12971+ * pkcs11t.h.
12972+ * ==============================================================
12973+ */
12974+
12975+#define CK_PKCS11_FUNCTION_INFO(name) \
12976+  __PASTE(CK_,name) name;
12977+
12978+struct CK_FUNCTION_LIST {
12979+
12980+  CK_VERSION    version;  /* Cryptoki version */
12981+
12982+/* Pile all the function pointers into the CK_FUNCTION_LIST. */
12983+/* pkcs11f.h has all the information about the Cryptoki
12984+ * function prototypes. */
12985+#include "pkcs11f.h"
12986+
12987+};
12988+
12989+#undef CK_PKCS11_FUNCTION_INFO
12990+
12991+
12992+#undef __PASTE
12993+
12994+#ifdef __cplusplus
12995+}
12996+#endif
12997+
12998+#endif
12999Index: openssl/crypto/engine/pkcs11f.h
13000diff -u /dev/null openssl/crypto/engine/pkcs11f.h:1.1.1.1
13001--- /dev/null	Fri Jan  2 13:56:41 2015
13002+++ openssl/crypto/engine/pkcs11f.h	Wed Oct 24 23:27:09 2007
13003@@ -0,0 +1,912 @@
13004+/* pkcs11f.h include file for PKCS #11. */
13005+/* Revision: 1.1.1.1  */
13006+
13007+/* License to copy and use this software is granted provided that it is
13008+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
13009+ * (Cryptoki)" in all material mentioning or referencing this software.
13010+
13011+ * License is also granted to make and use derivative works provided that
13012+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
13013+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
13014+ * referencing the derived work.
13015+
13016+ * RSA Security Inc. makes no representations concerning either the
13017+ * merchantability of this software or the suitability of this software for
13018+ * any particular purpose. It is provided "as is" without express or implied
13019+ * warranty of any kind.
13020+ */
13021+
13022+/* This header file contains pretty much everything about all the */
13023+/* Cryptoki function prototypes.  Because this information is */
13024+/* used for more than just declaring function prototypes, the */
13025+/* order of the functions appearing herein is important, and */
13026+/* should not be altered. */
13027+
13028+/* General-purpose */
13029+
13030+/* C_Initialize initializes the Cryptoki library. */
13031+CK_PKCS11_FUNCTION_INFO(C_Initialize)
13032+#ifdef CK_NEED_ARG_LIST
13033+(
13034+  CK_VOID_PTR   pInitArgs  /* if this is not NULL_PTR, it gets
13035+                            * cast to CK_C_INITIALIZE_ARGS_PTR
13036+                            * and dereferenced */
13037+);
13038+#endif
13039+
13040+
13041+/* C_Finalize indicates that an application is done with the
13042+ * Cryptoki library. */
13043+CK_PKCS11_FUNCTION_INFO(C_Finalize)
13044+#ifdef CK_NEED_ARG_LIST
13045+(
13046+  CK_VOID_PTR   pReserved  /* reserved.  Should be NULL_PTR */
13047+);
13048+#endif
13049+
13050+
13051+/* C_GetInfo returns general information about Cryptoki. */
13052+CK_PKCS11_FUNCTION_INFO(C_GetInfo)
13053+#ifdef CK_NEED_ARG_LIST
13054+(
13055+  CK_INFO_PTR   pInfo  /* location that receives information */
13056+);
13057+#endif
13058+
13059+
13060+/* C_GetFunctionList returns the function list. */
13061+CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
13062+#ifdef CK_NEED_ARG_LIST
13063+(
13064+  CK_FUNCTION_LIST_PTR_PTR ppFunctionList  /* receives pointer to
13065+                                            * function list */
13066+);
13067+#endif
13068+
13069+
13070+
13071+/* Slot and token management */
13072+
13073+/* C_GetSlotList obtains a list of slots in the system. */
13074+CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
13075+#ifdef CK_NEED_ARG_LIST
13076+(
13077+  CK_BBOOL       tokenPresent,  /* only slots with tokens? */
13078+  CK_SLOT_ID_PTR pSlotList,     /* receives array of slot IDs */
13079+  CK_ULONG_PTR   pulCount       /* receives number of slots */
13080+);
13081+#endif
13082+
13083+
13084+/* C_GetSlotInfo obtains information about a particular slot in
13085+ * the system. */
13086+CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
13087+#ifdef CK_NEED_ARG_LIST
13088+(
13089+  CK_SLOT_ID       slotID,  /* the ID of the slot */
13090+  CK_SLOT_INFO_PTR pInfo    /* receives the slot information */
13091+);
13092+#endif
13093+
13094+
13095+/* C_GetTokenInfo obtains information about a particular token
13096+ * in the system. */
13097+CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
13098+#ifdef CK_NEED_ARG_LIST
13099+(
13100+  CK_SLOT_ID        slotID,  /* ID of the token's slot */
13101+  CK_TOKEN_INFO_PTR pInfo    /* receives the token information */
13102+);
13103+#endif
13104+
13105+
13106+/* C_GetMechanismList obtains a list of mechanism types
13107+ * supported by a token. */
13108+CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
13109+#ifdef CK_NEED_ARG_LIST
13110+(
13111+  CK_SLOT_ID            slotID,          /* ID of token's slot */
13112+  CK_MECHANISM_TYPE_PTR pMechanismList,  /* gets mech. array */
13113+  CK_ULONG_PTR          pulCount         /* gets # of mechs. */
13114+);
13115+#endif
13116+
13117+
13118+/* C_GetMechanismInfo obtains information about a particular
13119+ * mechanism possibly supported by a token. */
13120+CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
13121+#ifdef CK_NEED_ARG_LIST
13122+(
13123+  CK_SLOT_ID            slotID,  /* ID of the token's slot */
13124+  CK_MECHANISM_TYPE     type,    /* type of mechanism */
13125+  CK_MECHANISM_INFO_PTR pInfo    /* receives mechanism info */
13126+);
13127+#endif
13128+
13129+
13130+/* C_InitToken initializes a token. */
13131+CK_PKCS11_FUNCTION_INFO(C_InitToken)
13132+#ifdef CK_NEED_ARG_LIST
13133+/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
13134+(
13135+  CK_SLOT_ID      slotID,    /* ID of the token's slot */
13136+  CK_UTF8CHAR_PTR pPin,      /* the SO's initial PIN */
13137+  CK_ULONG        ulPinLen,  /* length in bytes of the PIN */
13138+  CK_UTF8CHAR_PTR pLabel     /* 32-byte token label (blank padded) */
13139+);
13140+#endif
13141+
13142+
13143+/* C_InitPIN initializes the normal user's PIN. */
13144+CK_PKCS11_FUNCTION_INFO(C_InitPIN)
13145+#ifdef CK_NEED_ARG_LIST
13146+(
13147+  CK_SESSION_HANDLE hSession,  /* the session's handle */
13148+  CK_UTF8CHAR_PTR   pPin,      /* the normal user's PIN */
13149+  CK_ULONG          ulPinLen   /* length in bytes of the PIN */
13150+);
13151+#endif
13152+
13153+
13154+/* C_SetPIN modifies the PIN of the user who is logged in. */
13155+CK_PKCS11_FUNCTION_INFO(C_SetPIN)
13156+#ifdef CK_NEED_ARG_LIST
13157+(
13158+  CK_SESSION_HANDLE hSession,  /* the session's handle */
13159+  CK_UTF8CHAR_PTR   pOldPin,   /* the old PIN */
13160+  CK_ULONG          ulOldLen,  /* length of the old PIN */
13161+  CK_UTF8CHAR_PTR   pNewPin,   /* the new PIN */
13162+  CK_ULONG          ulNewLen   /* length of the new PIN */
13163+);
13164+#endif
13165+
13166+
13167+
13168+/* Session management */
13169+
13170+/* C_OpenSession opens a session between an application and a
13171+ * token. */
13172+CK_PKCS11_FUNCTION_INFO(C_OpenSession)
13173+#ifdef CK_NEED_ARG_LIST
13174+(
13175+  CK_SLOT_ID            slotID,        /* the slot's ID */
13176+  CK_FLAGS              flags,         /* from CK_SESSION_INFO */
13177+  CK_VOID_PTR           pApplication,  /* passed to callback */
13178+  CK_NOTIFY             Notify,        /* callback function */
13179+  CK_SESSION_HANDLE_PTR phSession      /* gets session handle */
13180+);
13181+#endif
13182+
13183+
13184+/* C_CloseSession closes a session between an application and a
13185+ * token. */
13186+CK_PKCS11_FUNCTION_INFO(C_CloseSession)
13187+#ifdef CK_NEED_ARG_LIST
13188+(
13189+  CK_SESSION_HANDLE hSession  /* the session's handle */
13190+);
13191+#endif
13192+
13193+
13194+/* C_CloseAllSessions closes all sessions with a token. */
13195+CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
13196+#ifdef CK_NEED_ARG_LIST
13197+(
13198+  CK_SLOT_ID     slotID  /* the token's slot */
13199+);
13200+#endif
13201+
13202+
13203+/* C_GetSessionInfo obtains information about the session. */
13204+CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
13205+#ifdef CK_NEED_ARG_LIST
13206+(
13207+  CK_SESSION_HANDLE   hSession,  /* the session's handle */
13208+  CK_SESSION_INFO_PTR pInfo      /* receives session info */
13209+);
13210+#endif
13211+
13212+
13213+/* C_GetOperationState obtains the state of the cryptographic operation
13214+ * in a session. */
13215+CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
13216+#ifdef CK_NEED_ARG_LIST
13217+(
13218+  CK_SESSION_HANDLE hSession,             /* session's handle */
13219+  CK_BYTE_PTR       pOperationState,      /* gets state */
13220+  CK_ULONG_PTR      pulOperationStateLen  /* gets state length */
13221+);
13222+#endif
13223+
13224+
13225+/* C_SetOperationState restores the state of the cryptographic
13226+ * operation in a session. */
13227+CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
13228+#ifdef CK_NEED_ARG_LIST
13229+(
13230+  CK_SESSION_HANDLE hSession,            /* session's handle */
13231+  CK_BYTE_PTR      pOperationState,      /* holds state */
13232+  CK_ULONG         ulOperationStateLen,  /* holds state length */
13233+  CK_OBJECT_HANDLE hEncryptionKey,       /* en/decryption key */
13234+  CK_OBJECT_HANDLE hAuthenticationKey    /* sign/verify key */
13235+);
13236+#endif
13237+
13238+
13239+/* C_Login logs a user into a token. */
13240+CK_PKCS11_FUNCTION_INFO(C_Login)
13241+#ifdef CK_NEED_ARG_LIST
13242+(
13243+  CK_SESSION_HANDLE hSession,  /* the session's handle */
13244+  CK_USER_TYPE      userType,  /* the user type */
13245+  CK_UTF8CHAR_PTR   pPin,      /* the user's PIN */
13246+  CK_ULONG          ulPinLen   /* the length of the PIN */
13247+);
13248+#endif
13249+
13250+
13251+/* C_Logout logs a user out from a token. */
13252+CK_PKCS11_FUNCTION_INFO(C_Logout)
13253+#ifdef CK_NEED_ARG_LIST
13254+(
13255+  CK_SESSION_HANDLE hSession  /* the session's handle */
13256+);
13257+#endif
13258+
13259+
13260+
13261+/* Object management */
13262+
13263+/* C_CreateObject creates a new object. */
13264+CK_PKCS11_FUNCTION_INFO(C_CreateObject)
13265+#ifdef CK_NEED_ARG_LIST
13266+(
13267+  CK_SESSION_HANDLE hSession,    /* the session's handle */
13268+  CK_ATTRIBUTE_PTR  pTemplate,   /* the object's template */
13269+  CK_ULONG          ulCount,     /* attributes in template */
13270+  CK_OBJECT_HANDLE_PTR phObject  /* gets new object's handle. */
13271+);
13272+#endif
13273+
13274+
13275+/* C_CopyObject copies an object, creating a new object for the
13276+ * copy. */
13277+CK_PKCS11_FUNCTION_INFO(C_CopyObject)
13278+#ifdef CK_NEED_ARG_LIST
13279+(
13280+  CK_SESSION_HANDLE    hSession,    /* the session's handle */
13281+  CK_OBJECT_HANDLE     hObject,     /* the object's handle */
13282+  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new object */
13283+  CK_ULONG             ulCount,     /* attributes in template */
13284+  CK_OBJECT_HANDLE_PTR phNewObject  /* receives handle of copy */
13285+);
13286+#endif
13287+
13288+
13289+/* C_DestroyObject destroys an object. */
13290+CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
13291+#ifdef CK_NEED_ARG_LIST
13292+(
13293+  CK_SESSION_HANDLE hSession,  /* the session's handle */
13294+  CK_OBJECT_HANDLE  hObject    /* the object's handle */
13295+);
13296+#endif
13297+
13298+
13299+/* C_GetObjectSize gets the size of an object in bytes. */
13300+CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
13301+#ifdef CK_NEED_ARG_LIST
13302+(
13303+  CK_SESSION_HANDLE hSession,  /* the session's handle */
13304+  CK_OBJECT_HANDLE  hObject,   /* the object's handle */
13305+  CK_ULONG_PTR      pulSize    /* receives size of object */
13306+);
13307+#endif
13308+
13309+
13310+/* C_GetAttributeValue obtains the value of one or more object
13311+ * attributes. */
13312+CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
13313+#ifdef CK_NEED_ARG_LIST
13314+(
13315+  CK_SESSION_HANDLE hSession,   /* the session's handle */
13316+  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
13317+  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs; gets vals */
13318+  CK_ULONG          ulCount     /* attributes in template */
13319+);
13320+#endif
13321+
13322+
13323+/* C_SetAttributeValue modifies the value of one or more object
13324+ * attributes */
13325+CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
13326+#ifdef CK_NEED_ARG_LIST
13327+(
13328+  CK_SESSION_HANDLE hSession,   /* the session's handle */
13329+  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
13330+  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs and values */
13331+  CK_ULONG          ulCount     /* attributes in template */
13332+);
13333+#endif
13334+
13335+
13336+/* C_FindObjectsInit initializes a search for token and session
13337+ * objects that match a template. */
13338+CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
13339+#ifdef CK_NEED_ARG_LIST
13340+(
13341+  CK_SESSION_HANDLE hSession,   /* the session's handle */
13342+  CK_ATTRIBUTE_PTR  pTemplate,  /* attribute values to match */
13343+  CK_ULONG          ulCount     /* attrs in search template */
13344+);
13345+#endif
13346+
13347+
13348+/* C_FindObjects continues a search for token and session
13349+ * objects that match a template, obtaining additional object
13350+ * handles. */
13351+CK_PKCS11_FUNCTION_INFO(C_FindObjects)
13352+#ifdef CK_NEED_ARG_LIST
13353+(
13354+ CK_SESSION_HANDLE    hSession,          /* session's handle */
13355+ CK_OBJECT_HANDLE_PTR phObject,          /* gets obj. handles */
13356+ CK_ULONG             ulMaxObjectCount,  /* max handles to get */
13357+ CK_ULONG_PTR         pulObjectCount     /* actual # returned */
13358+);
13359+#endif
13360+
13361+
13362+/* C_FindObjectsFinal finishes a search for token and session
13363+ * objects. */
13364+CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
13365+#ifdef CK_NEED_ARG_LIST
13366+(
13367+  CK_SESSION_HANDLE hSession  /* the session's handle */
13368+);
13369+#endif
13370+
13371+
13372+
13373+/* Encryption and decryption */
13374+
13375+/* C_EncryptInit initializes an encryption operation. */
13376+CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
13377+#ifdef CK_NEED_ARG_LIST
13378+(
13379+  CK_SESSION_HANDLE hSession,    /* the session's handle */
13380+  CK_MECHANISM_PTR  pMechanism,  /* the encryption mechanism */
13381+  CK_OBJECT_HANDLE  hKey         /* handle of encryption key */
13382+);
13383+#endif
13384+
13385+
13386+/* C_Encrypt encrypts single-part data. */
13387+CK_PKCS11_FUNCTION_INFO(C_Encrypt)
13388+#ifdef CK_NEED_ARG_LIST
13389+(
13390+  CK_SESSION_HANDLE hSession,            /* session's handle */
13391+  CK_BYTE_PTR       pData,               /* the plaintext data */
13392+  CK_ULONG          ulDataLen,           /* bytes of plaintext */
13393+  CK_BYTE_PTR       pEncryptedData,      /* gets ciphertext */
13394+  CK_ULONG_PTR      pulEncryptedDataLen  /* gets c-text size */
13395+);
13396+#endif
13397+
13398+
13399+/* C_EncryptUpdate continues a multiple-part encryption
13400+ * operation. */
13401+CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
13402+#ifdef CK_NEED_ARG_LIST
13403+(
13404+  CK_SESSION_HANDLE hSession,           /* session's handle */
13405+  CK_BYTE_PTR       pPart,              /* the plaintext data */
13406+  CK_ULONG          ulPartLen,          /* plaintext data len */
13407+  CK_BYTE_PTR       pEncryptedPart,     /* gets ciphertext */
13408+  CK_ULONG_PTR      pulEncryptedPartLen /* gets c-text size */
13409+);
13410+#endif
13411+
13412+
13413+/* C_EncryptFinal finishes a multiple-part encryption
13414+ * operation. */
13415+CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
13416+#ifdef CK_NEED_ARG_LIST
13417+(
13418+  CK_SESSION_HANDLE hSession,                /* session handle */
13419+  CK_BYTE_PTR       pLastEncryptedPart,      /* last c-text */
13420+  CK_ULONG_PTR      pulLastEncryptedPartLen  /* gets last size */
13421+);
13422+#endif
13423+
13424+
13425+/* C_DecryptInit initializes a decryption operation. */
13426+CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
13427+#ifdef CK_NEED_ARG_LIST
13428+(
13429+  CK_SESSION_HANDLE hSession,    /* the session's handle */
13430+  CK_MECHANISM_PTR  pMechanism,  /* the decryption mechanism */
13431+  CK_OBJECT_HANDLE  hKey         /* handle of decryption key */
13432+);
13433+#endif
13434+
13435+
13436+/* C_Decrypt decrypts encrypted data in a single part. */
13437+CK_PKCS11_FUNCTION_INFO(C_Decrypt)
13438+#ifdef CK_NEED_ARG_LIST
13439+(
13440+  CK_SESSION_HANDLE hSession,           /* session's handle */
13441+  CK_BYTE_PTR       pEncryptedData,     /* ciphertext */
13442+  CK_ULONG          ulEncryptedDataLen, /* ciphertext length */
13443+  CK_BYTE_PTR       pData,              /* gets plaintext */
13444+  CK_ULONG_PTR      pulDataLen          /* gets p-text size */
13445+);
13446+#endif
13447+
13448+
13449+/* C_DecryptUpdate continues a multiple-part decryption
13450+ * operation. */
13451+CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
13452+#ifdef CK_NEED_ARG_LIST
13453+(
13454+  CK_SESSION_HANDLE hSession,            /* session's handle */
13455+  CK_BYTE_PTR       pEncryptedPart,      /* encrypted data */
13456+  CK_ULONG          ulEncryptedPartLen,  /* input length */
13457+  CK_BYTE_PTR       pPart,               /* gets plaintext */
13458+  CK_ULONG_PTR      pulPartLen           /* p-text size */
13459+);
13460+#endif
13461+
13462+
13463+/* C_DecryptFinal finishes a multiple-part decryption
13464+ * operation. */
13465+CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
13466+#ifdef CK_NEED_ARG_LIST
13467+(
13468+  CK_SESSION_HANDLE hSession,       /* the session's handle */
13469+  CK_BYTE_PTR       pLastPart,      /* gets plaintext */
13470+  CK_ULONG_PTR      pulLastPartLen  /* p-text size */
13471+);
13472+#endif
13473+
13474+
13475+
13476+/* Message digesting */
13477+
13478+/* C_DigestInit initializes a message-digesting operation. */
13479+CK_PKCS11_FUNCTION_INFO(C_DigestInit)
13480+#ifdef CK_NEED_ARG_LIST
13481+(
13482+  CK_SESSION_HANDLE hSession,   /* the session's handle */
13483+  CK_MECHANISM_PTR  pMechanism  /* the digesting mechanism */
13484+);
13485+#endif
13486+
13487+
13488+/* C_Digest digests data in a single part. */
13489+CK_PKCS11_FUNCTION_INFO(C_Digest)
13490+#ifdef CK_NEED_ARG_LIST
13491+(
13492+  CK_SESSION_HANDLE hSession,     /* the session's handle */
13493+  CK_BYTE_PTR       pData,        /* data to be digested */
13494+  CK_ULONG          ulDataLen,    /* bytes of data to digest */
13495+  CK_BYTE_PTR       pDigest,      /* gets the message digest */
13496+  CK_ULONG_PTR      pulDigestLen  /* gets digest length */
13497+);
13498+#endif
13499+
13500+
13501+/* C_DigestUpdate continues a multiple-part message-digesting
13502+ * operation. */
13503+CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
13504+#ifdef CK_NEED_ARG_LIST
13505+(
13506+  CK_SESSION_HANDLE hSession,  /* the session's handle */
13507+  CK_BYTE_PTR       pPart,     /* data to be digested */
13508+  CK_ULONG          ulPartLen  /* bytes of data to be digested */
13509+);
13510+#endif
13511+
13512+
13513+/* C_DigestKey continues a multi-part message-digesting
13514+ * operation, by digesting the value of a secret key as part of
13515+ * the data already digested. */
13516+CK_PKCS11_FUNCTION_INFO(C_DigestKey)
13517+#ifdef CK_NEED_ARG_LIST
13518+(
13519+  CK_SESSION_HANDLE hSession,  /* the session's handle */
13520+  CK_OBJECT_HANDLE  hKey       /* secret key to digest */
13521+);
13522+#endif
13523+
13524+
13525+/* C_DigestFinal finishes a multiple-part message-digesting
13526+ * operation. */
13527+CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
13528+#ifdef CK_NEED_ARG_LIST
13529+(
13530+  CK_SESSION_HANDLE hSession,     /* the session's handle */
13531+  CK_BYTE_PTR       pDigest,      /* gets the message digest */
13532+  CK_ULONG_PTR      pulDigestLen  /* gets byte count of digest */
13533+);
13534+#endif
13535+
13536+
13537+
13538+/* Signing and MACing */
13539+
13540+/* C_SignInit initializes a signature (private key encryption)
13541+ * operation, where the signature is (will be) an appendix to
13542+ * the data, and plaintext cannot be recovered from the
13543+ *signature. */
13544+CK_PKCS11_FUNCTION_INFO(C_SignInit)
13545+#ifdef CK_NEED_ARG_LIST
13546+(
13547+  CK_SESSION_HANDLE hSession,    /* the session's handle */
13548+  CK_MECHANISM_PTR  pMechanism,  /* the signature mechanism */
13549+  CK_OBJECT_HANDLE  hKey         /* handle of signature key */
13550+);
13551+#endif
13552+
13553+
13554+/* C_Sign signs (encrypts with private key) data in a single
13555+ * part, where the signature is (will be) an appendix to the
13556+ * data, and plaintext cannot be recovered from the signature. */
13557+CK_PKCS11_FUNCTION_INFO(C_Sign)
13558+#ifdef CK_NEED_ARG_LIST
13559+(
13560+  CK_SESSION_HANDLE hSession,        /* the session's handle */
13561+  CK_BYTE_PTR       pData,           /* the data to sign */
13562+  CK_ULONG          ulDataLen,       /* count of bytes to sign */
13563+  CK_BYTE_PTR       pSignature,      /* gets the signature */
13564+  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
13565+);
13566+#endif
13567+
13568+
13569+/* C_SignUpdate continues a multiple-part signature operation,
13570+ * where the signature is (will be) an appendix to the data,
13571+ * and plaintext cannot be recovered from the signature. */
13572+CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
13573+#ifdef CK_NEED_ARG_LIST
13574+(
13575+  CK_SESSION_HANDLE hSession,  /* the session's handle */
13576+  CK_BYTE_PTR       pPart,     /* the data to sign */
13577+  CK_ULONG          ulPartLen  /* count of bytes to sign */
13578+);
13579+#endif
13580+
13581+
13582+/* C_SignFinal finishes a multiple-part signature operation,
13583+ * returning the signature. */
13584+CK_PKCS11_FUNCTION_INFO(C_SignFinal)
13585+#ifdef CK_NEED_ARG_LIST
13586+(
13587+  CK_SESSION_HANDLE hSession,        /* the session's handle */
13588+  CK_BYTE_PTR       pSignature,      /* gets the signature */
13589+  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
13590+);
13591+#endif
13592+
13593+
13594+/* C_SignRecoverInit initializes a signature operation, where
13595+ * the data can be recovered from the signature. */
13596+CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
13597+#ifdef CK_NEED_ARG_LIST
13598+(
13599+  CK_SESSION_HANDLE hSession,   /* the session's handle */
13600+  CK_MECHANISM_PTR  pMechanism, /* the signature mechanism */
13601+  CK_OBJECT_HANDLE  hKey        /* handle of the signature key */
13602+);
13603+#endif
13604+
13605+
13606+/* C_SignRecover signs data in a single operation, where the
13607+ * data can be recovered from the signature. */
13608+CK_PKCS11_FUNCTION_INFO(C_SignRecover)
13609+#ifdef CK_NEED_ARG_LIST
13610+(
13611+  CK_SESSION_HANDLE hSession,        /* the session's handle */
13612+  CK_BYTE_PTR       pData,           /* the data to sign */
13613+  CK_ULONG          ulDataLen,       /* count of bytes to sign */
13614+  CK_BYTE_PTR       pSignature,      /* gets the signature */
13615+  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
13616+);
13617+#endif
13618+
13619+
13620+
13621+/* Verifying signatures and MACs */
13622+
13623+/* C_VerifyInit initializes a verification operation, where the
13624+ * signature is an appendix to the data, and plaintext cannot
13625+ *  cannot be recovered from the signature (e.g. DSA). */
13626+CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
13627+#ifdef CK_NEED_ARG_LIST
13628+(
13629+  CK_SESSION_HANDLE hSession,    /* the session's handle */
13630+  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
13631+  CK_OBJECT_HANDLE  hKey         /* verification key */
13632+);
13633+#endif
13634+
13635+
13636+/* C_Verify verifies a signature in a single-part operation,
13637+ * where the signature is an appendix to the data, and plaintext
13638+ * cannot be recovered from the signature. */
13639+CK_PKCS11_FUNCTION_INFO(C_Verify)
13640+#ifdef CK_NEED_ARG_LIST
13641+(
13642+  CK_SESSION_HANDLE hSession,       /* the session's handle */
13643+  CK_BYTE_PTR       pData,          /* signed data */
13644+  CK_ULONG          ulDataLen,      /* length of signed data */
13645+  CK_BYTE_PTR       pSignature,     /* signature */
13646+  CK_ULONG          ulSignatureLen  /* signature length*/
13647+);
13648+#endif
13649+
13650+
13651+/* C_VerifyUpdate continues a multiple-part verification
13652+ * operation, where the signature is an appendix to the data,
13653+ * and plaintext cannot be recovered from the signature. */
13654+CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
13655+#ifdef CK_NEED_ARG_LIST
13656+(
13657+  CK_SESSION_HANDLE hSession,  /* the session's handle */
13658+  CK_BYTE_PTR       pPart,     /* signed data */
13659+  CK_ULONG          ulPartLen  /* length of signed data */
13660+);
13661+#endif
13662+
13663+
13664+/* C_VerifyFinal finishes a multiple-part verification
13665+ * operation, checking the signature. */
13666+CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
13667+#ifdef CK_NEED_ARG_LIST
13668+(
13669+  CK_SESSION_HANDLE hSession,       /* the session's handle */
13670+  CK_BYTE_PTR       pSignature,     /* signature to verify */
13671+  CK_ULONG          ulSignatureLen  /* signature length */
13672+);
13673+#endif
13674+
13675+
13676+/* C_VerifyRecoverInit initializes a signature verification
13677+ * operation, where the data is recovered from the signature. */
13678+CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
13679+#ifdef CK_NEED_ARG_LIST
13680+(
13681+  CK_SESSION_HANDLE hSession,    /* the session's handle */
13682+  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
13683+  CK_OBJECT_HANDLE  hKey         /* verification key */
13684+);
13685+#endif
13686+
13687+
13688+/* C_VerifyRecover verifies a signature in a single-part
13689+ * operation, where the data is recovered from the signature. */
13690+CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
13691+#ifdef CK_NEED_ARG_LIST
13692+(
13693+  CK_SESSION_HANDLE hSession,        /* the session's handle */
13694+  CK_BYTE_PTR       pSignature,      /* signature to verify */
13695+  CK_ULONG          ulSignatureLen,  /* signature length */
13696+  CK_BYTE_PTR       pData,           /* gets signed data */
13697+  CK_ULONG_PTR      pulDataLen       /* gets signed data len */
13698+);
13699+#endif
13700+
13701+
13702+
13703+/* Dual-function cryptographic operations */
13704+
13705+/* C_DigestEncryptUpdate continues a multiple-part digesting
13706+ * and encryption operation. */
13707+CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
13708+#ifdef CK_NEED_ARG_LIST
13709+(
13710+  CK_SESSION_HANDLE hSession,            /* session's handle */
13711+  CK_BYTE_PTR       pPart,               /* the plaintext data */
13712+  CK_ULONG          ulPartLen,           /* plaintext length */
13713+  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
13714+  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
13715+);
13716+#endif
13717+
13718+
13719+/* C_DecryptDigestUpdate continues a multiple-part decryption and
13720+ * digesting operation. */
13721+CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
13722+#ifdef CK_NEED_ARG_LIST
13723+(
13724+  CK_SESSION_HANDLE hSession,            /* session's handle */
13725+  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
13726+  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
13727+  CK_BYTE_PTR       pPart,               /* gets plaintext */
13728+  CK_ULONG_PTR      pulPartLen           /* gets plaintext len */
13729+);
13730+#endif
13731+
13732+
13733+/* C_SignEncryptUpdate continues a multiple-part signing and
13734+ * encryption operation. */
13735+CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
13736+#ifdef CK_NEED_ARG_LIST
13737+(
13738+  CK_SESSION_HANDLE hSession,            /* session's handle */
13739+  CK_BYTE_PTR       pPart,               /* the plaintext data */
13740+  CK_ULONG          ulPartLen,           /* plaintext length */
13741+  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
13742+  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
13743+);
13744+#endif
13745+
13746+
13747+/* C_DecryptVerifyUpdate continues a multiple-part decryption and
13748+ * verify operation. */
13749+CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
13750+#ifdef CK_NEED_ARG_LIST
13751+(
13752+  CK_SESSION_HANDLE hSession,            /* session's handle */
13753+  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
13754+  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
13755+  CK_BYTE_PTR       pPart,               /* gets plaintext */
13756+  CK_ULONG_PTR      pulPartLen           /* gets p-text length */
13757+);
13758+#endif
13759+
13760+
13761+
13762+/* Key management */
13763+
13764+/* C_GenerateKey generates a secret key, creating a new key
13765+ * object. */
13766+CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
13767+#ifdef CK_NEED_ARG_LIST
13768+(
13769+  CK_SESSION_HANDLE    hSession,    /* the session's handle */
13770+  CK_MECHANISM_PTR     pMechanism,  /* key generation mech. */
13771+  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new key */
13772+  CK_ULONG             ulCount,     /* # of attrs in template */
13773+  CK_OBJECT_HANDLE_PTR phKey        /* gets handle of new key */
13774+);
13775+#endif
13776+
13777+
13778+/* C_GenerateKeyPair generates a public-key/private-key pair,
13779+ * creating new key objects. */
13780+CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
13781+#ifdef CK_NEED_ARG_LIST
13782+(
13783+  CK_SESSION_HANDLE    hSession,                    /* session
13784+                                                     * handle */
13785+  CK_MECHANISM_PTR     pMechanism,                  /* key-gen
13786+                                                     * mech. */
13787+  CK_ATTRIBUTE_PTR     pPublicKeyTemplate,          /* template
13788+                                                     * for pub.
13789+                                                     * key */
13790+  CK_ULONG             ulPublicKeyAttributeCount,   /* # pub.
13791+                                                     * attrs. */
13792+  CK_ATTRIBUTE_PTR     pPrivateKeyTemplate,         /* template
13793+                                                     * for priv.
13794+                                                     * key */
13795+  CK_ULONG             ulPrivateKeyAttributeCount,  /* # priv.
13796+                                                     * attrs. */
13797+  CK_OBJECT_HANDLE_PTR phPublicKey,                 /* gets pub.
13798+                                                     * key
13799+                                                     * handle */
13800+  CK_OBJECT_HANDLE_PTR phPrivateKey                 /* gets
13801+                                                     * priv. key
13802+                                                     * handle */
13803+);
13804+#endif
13805+
13806+
13807+/* C_WrapKey wraps (i.e., encrypts) a key. */
13808+CK_PKCS11_FUNCTION_INFO(C_WrapKey)
13809+#ifdef CK_NEED_ARG_LIST
13810+(
13811+  CK_SESSION_HANDLE hSession,        /* the session's handle */
13812+  CK_MECHANISM_PTR  pMechanism,      /* the wrapping mechanism */
13813+  CK_OBJECT_HANDLE  hWrappingKey,    /* wrapping key */
13814+  CK_OBJECT_HANDLE  hKey,            /* key to be wrapped */
13815+  CK_BYTE_PTR       pWrappedKey,     /* gets wrapped key */
13816+  CK_ULONG_PTR      pulWrappedKeyLen /* gets wrapped key size */
13817+);
13818+#endif
13819+
13820+
13821+/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
13822+ * key object. */
13823+CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
13824+#ifdef CK_NEED_ARG_LIST
13825+(
13826+  CK_SESSION_HANDLE    hSession,          /* session's handle */
13827+  CK_MECHANISM_PTR     pMechanism,        /* unwrapping mech. */
13828+  CK_OBJECT_HANDLE     hUnwrappingKey,    /* unwrapping key */
13829+  CK_BYTE_PTR          pWrappedKey,       /* the wrapped key */
13830+  CK_ULONG             ulWrappedKeyLen,   /* wrapped key len */
13831+  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
13832+  CK_ULONG             ulAttributeCount,  /* template length */
13833+  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
13834+);
13835+#endif
13836+
13837+
13838+/* C_DeriveKey derives a key from a base key, creating a new key
13839+ * object. */
13840+CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
13841+#ifdef CK_NEED_ARG_LIST
13842+(
13843+  CK_SESSION_HANDLE    hSession,          /* session's handle */
13844+  CK_MECHANISM_PTR     pMechanism,        /* key deriv. mech. */
13845+  CK_OBJECT_HANDLE     hBaseKey,          /* base key */
13846+  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
13847+  CK_ULONG             ulAttributeCount,  /* template length */
13848+  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
13849+);
13850+#endif
13851+
13852+
13853+
13854+/* Random number generation */
13855+
13856+/* C_SeedRandom mixes additional seed material into the token's
13857+ * random number generator. */
13858+CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
13859+#ifdef CK_NEED_ARG_LIST
13860+(
13861+  CK_SESSION_HANDLE hSession,  /* the session's handle */
13862+  CK_BYTE_PTR       pSeed,     /* the seed material */
13863+  CK_ULONG          ulSeedLen  /* length of seed material */
13864+);
13865+#endif
13866+
13867+
13868+/* C_GenerateRandom generates random data. */
13869+CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
13870+#ifdef CK_NEED_ARG_LIST
13871+(
13872+  CK_SESSION_HANDLE hSession,    /* the session's handle */
13873+  CK_BYTE_PTR       RandomData,  /* receives the random data */
13874+  CK_ULONG          ulRandomLen  /* # of bytes to generate */
13875+);
13876+#endif
13877+
13878+
13879+
13880+/* Parallel function management */
13881+
13882+/* C_GetFunctionStatus is a legacy function; it obtains an
13883+ * updated status of a function running in parallel with an
13884+ * application. */
13885+CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
13886+#ifdef CK_NEED_ARG_LIST
13887+(
13888+  CK_SESSION_HANDLE hSession  /* the session's handle */
13889+);
13890+#endif
13891+
13892+
13893+/* C_CancelFunction is a legacy function; it cancels a function
13894+ * running in parallel. */
13895+CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
13896+#ifdef CK_NEED_ARG_LIST
13897+(
13898+  CK_SESSION_HANDLE hSession  /* the session's handle */
13899+);
13900+#endif
13901+
13902+
13903+
13904+/* Functions added in for Cryptoki Version 2.01 or later */
13905+
13906+/* C_WaitForSlotEvent waits for a slot event (token insertion,
13907+ * removal, etc.) to occur. */
13908+CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
13909+#ifdef CK_NEED_ARG_LIST
13910+(
13911+  CK_FLAGS flags,        /* blocking/nonblocking flag */
13912+  CK_SLOT_ID_PTR pSlot,  /* location that receives the slot ID */
13913+  CK_VOID_PTR pRserved   /* reserved.  Should be NULL_PTR */
13914+);
13915+#endif
13916Index: openssl/crypto/engine/pkcs11t.h
13917diff -u /dev/null openssl/crypto/engine/pkcs11t.h:1.2
13918--- /dev/null	Fri Jan  2 13:56:41 2015
13919+++ openssl/crypto/engine/pkcs11t.h	Sat Aug 30 11:58:07 2008
13920@@ -0,0 +1,1885 @@
13921+/* pkcs11t.h include file for PKCS #11. */
13922+/* Revision: 1.2  */
13923+
13924+/* License to copy and use this software is granted provided that it is
13925+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
13926+ * (Cryptoki)" in all material mentioning or referencing this software.
13927+
13928+ * License is also granted to make and use derivative works provided that
13929+ * such works are identified as "derived from the RSA Security Inc. PKCS #11
13930+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
13931+ * referencing the derived work.
13932+
13933+ * RSA Security Inc. makes no representations concerning either the
13934+ * merchantability of this software or the suitability of this software for
13935+ * any particular purpose. It is provided "as is" without express or implied
13936+ * warranty of any kind.
13937+ */
13938+
13939+/* See top of pkcs11.h for information about the macros that
13940+ * must be defined and the structure-packing conventions that
13941+ * must be set before including this file. */
13942+
13943+#ifndef _PKCS11T_H_
13944+#define _PKCS11T_H_ 1
13945+
13946+#define CRYPTOKI_VERSION_MAJOR 2
13947+#define CRYPTOKI_VERSION_MINOR 20
13948+#define CRYPTOKI_VERSION_AMENDMENT 3
13949+
13950+#define CK_TRUE 1
13951+#define CK_FALSE 0
13952+
13953+#ifndef CK_DISABLE_TRUE_FALSE
13954+#ifndef FALSE
13955+#define FALSE CK_FALSE
13956+#endif
13957+
13958+#ifndef TRUE
13959+#define TRUE CK_TRUE
13960+#endif
13961+#endif
13962+
13963+/* an unsigned 8-bit value */
13964+typedef unsigned char     CK_BYTE;
13965+
13966+/* an unsigned 8-bit character */
13967+typedef CK_BYTE           CK_CHAR;
13968+
13969+/* an 8-bit UTF-8 character */
13970+typedef CK_BYTE           CK_UTF8CHAR;
13971+
13972+/* a BYTE-sized Boolean flag */
13973+typedef CK_BYTE           CK_BBOOL;
13974+
13975+/* an unsigned value, at least 32 bits long */
13976+typedef unsigned long int CK_ULONG;
13977+
13978+/* a signed value, the same size as a CK_ULONG */
13979+/* CK_LONG is new for v2.0 */
13980+typedef long int          CK_LONG;
13981+
13982+/* at least 32 bits; each bit is a Boolean flag */
13983+typedef CK_ULONG          CK_FLAGS;
13984+
13985+
13986+/* some special values for certain CK_ULONG variables */
13987+#define CK_UNAVAILABLE_INFORMATION (~0UL)
13988+#define CK_EFFECTIVELY_INFINITE    0
13989+
13990+
13991+typedef CK_BYTE     CK_PTR   CK_BYTE_PTR;
13992+typedef CK_CHAR     CK_PTR   CK_CHAR_PTR;
13993+typedef CK_UTF8CHAR CK_PTR   CK_UTF8CHAR_PTR;
13994+typedef CK_ULONG    CK_PTR   CK_ULONG_PTR;
13995+typedef void        CK_PTR   CK_VOID_PTR;
13996+
13997+/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
13998+typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
13999+
14000+
14001+/* The following value is always invalid if used as a session */
14002+/* handle or object handle */
14003+#define CK_INVALID_HANDLE 0
14004+
14005+
14006+typedef struct CK_VERSION {
14007+  CK_BYTE       major;  /* integer portion of version number */
14008+  CK_BYTE       minor;  /* 1/100ths portion of version number */
14009+} CK_VERSION;
14010+
14011+typedef CK_VERSION CK_PTR CK_VERSION_PTR;
14012+
14013+
14014+typedef struct CK_INFO {
14015+  /* manufacturerID and libraryDecription have been changed from
14016+   * CK_CHAR to CK_UTF8CHAR for v2.10 */
14017+  CK_VERSION    cryptokiVersion;     /* Cryptoki interface ver */
14018+  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
14019+  CK_FLAGS      flags;               /* must be zero */
14020+
14021+  /* libraryDescription and libraryVersion are new for v2.0 */
14022+  CK_UTF8CHAR   libraryDescription[32];  /* blank padded */
14023+  CK_VERSION    libraryVersion;          /* version of library */
14024+} CK_INFO;
14025+
14026+typedef CK_INFO CK_PTR    CK_INFO_PTR;
14027+
14028+
14029+/* CK_NOTIFICATION enumerates the types of notifications that
14030+ * Cryptoki provides to an application */
14031+/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
14032+ * for v2.0 */
14033+typedef CK_ULONG CK_NOTIFICATION;
14034+#define CKN_SURRENDER       0
14035+
14036+/* The following notification is new for PKCS #11 v2.20 amendment 3 */
14037+#define CKN_OTP_CHANGED     1
14038+
14039+
14040+typedef CK_ULONG          CK_SLOT_ID;
14041+
14042+typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
14043+
14044+
14045+/* CK_SLOT_INFO provides information about a slot */
14046+typedef struct CK_SLOT_INFO {
14047+  /* slotDescription and manufacturerID have been changed from
14048+   * CK_CHAR to CK_UTF8CHAR for v2.10 */
14049+  CK_UTF8CHAR   slotDescription[64];  /* blank padded */
14050+  CK_UTF8CHAR   manufacturerID[32];   /* blank padded */
14051+  CK_FLAGS      flags;
14052+
14053+  /* hardwareVersion and firmwareVersion are new for v2.0 */
14054+  CK_VERSION    hardwareVersion;  /* version of hardware */
14055+  CK_VERSION    firmwareVersion;  /* version of firmware */
14056+} CK_SLOT_INFO;
14057+
14058+/* flags: bit flags that provide capabilities of the slot
14059+ *      Bit Flag              Mask        Meaning
14060+ */
14061+#define CKF_TOKEN_PRESENT     0x00000001  /* a token is there */
14062+#define CKF_REMOVABLE_DEVICE  0x00000002  /* removable devices*/
14063+#define CKF_HW_SLOT           0x00000004  /* hardware slot */
14064+
14065+typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
14066+
14067+
14068+/* CK_TOKEN_INFO provides information about a token */
14069+typedef struct CK_TOKEN_INFO {
14070+  /* label, manufacturerID, and model have been changed from
14071+   * CK_CHAR to CK_UTF8CHAR for v2.10 */
14072+  CK_UTF8CHAR   label[32];           /* blank padded */
14073+  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
14074+  CK_UTF8CHAR   model[16];           /* blank padded */
14075+  CK_CHAR       serialNumber[16];    /* blank padded */
14076+  CK_FLAGS      flags;               /* see below */
14077+
14078+  /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
14079+   * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
14080+   * changed from CK_USHORT to CK_ULONG for v2.0 */
14081+  CK_ULONG      ulMaxSessionCount;     /* max open sessions */
14082+  CK_ULONG      ulSessionCount;        /* sess. now open */
14083+  CK_ULONG      ulMaxRwSessionCount;   /* max R/W sessions */
14084+  CK_ULONG      ulRwSessionCount;      /* R/W sess. now open */
14085+  CK_ULONG      ulMaxPinLen;           /* in bytes */
14086+  CK_ULONG      ulMinPinLen;           /* in bytes */
14087+  CK_ULONG      ulTotalPublicMemory;   /* in bytes */
14088+  CK_ULONG      ulFreePublicMemory;    /* in bytes */
14089+  CK_ULONG      ulTotalPrivateMemory;  /* in bytes */
14090+  CK_ULONG      ulFreePrivateMemory;   /* in bytes */
14091+
14092+  /* hardwareVersion, firmwareVersion, and time are new for
14093+   * v2.0 */
14094+  CK_VERSION    hardwareVersion;       /* version of hardware */
14095+  CK_VERSION    firmwareVersion;       /* version of firmware */
14096+  CK_CHAR       utcTime[16];           /* time */
14097+} CK_TOKEN_INFO;
14098+
14099+/* The flags parameter is defined as follows:
14100+ *      Bit Flag                    Mask        Meaning
14101+ */
14102+#define CKF_RNG                     0x00000001  /* has random #
14103+                                                 * generator */
14104+#define CKF_WRITE_PROTECTED         0x00000002  /* token is
14105+                                                 * write-
14106+                                                 * protected */
14107+#define CKF_LOGIN_REQUIRED          0x00000004  /* user must
14108+                                                 * login */
14109+#define CKF_USER_PIN_INITIALIZED    0x00000008  /* normal user's
14110+                                                 * PIN is set */
14111+
14112+/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0.  If it is set,
14113+ * that means that *every* time the state of cryptographic
14114+ * operations of a session is successfully saved, all keys
14115+ * needed to continue those operations are stored in the state */
14116+#define CKF_RESTORE_KEY_NOT_NEEDED  0x00000020
14117+
14118+/* CKF_CLOCK_ON_TOKEN is new for v2.0.  If it is set, that means
14119+ * that the token has some sort of clock.  The time on that
14120+ * clock is returned in the token info structure */
14121+#define CKF_CLOCK_ON_TOKEN          0x00000040
14122+
14123+/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0.  If it is
14124+ * set, that means that there is some way for the user to login
14125+ * without sending a PIN through the Cryptoki library itself */
14126+#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
14127+
14128+/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0.  If it is true,
14129+ * that means that a single session with the token can perform
14130+ * dual simultaneous cryptographic operations (digest and
14131+ * encrypt; decrypt and digest; sign and encrypt; and decrypt
14132+ * and sign) */
14133+#define CKF_DUAL_CRYPTO_OPERATIONS  0x00000200
14134+
14135+/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
14136+ * token has been initialized using C_InitializeToken or an
14137+ * equivalent mechanism outside the scope of PKCS #11.
14138+ * Calling C_InitializeToken when this flag is set will cause
14139+ * the token to be reinitialized. */
14140+#define CKF_TOKEN_INITIALIZED       0x00000400
14141+
14142+/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
14143+ * true, the token supports secondary authentication for
14144+ * private key objects. This flag is deprecated in v2.11 and
14145+   onwards. */
14146+#define CKF_SECONDARY_AUTHENTICATION  0x00000800
14147+
14148+/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
14149+ * incorrect user login PIN has been entered at least once
14150+ * since the last successful authentication. */
14151+#define CKF_USER_PIN_COUNT_LOW       0x00010000
14152+
14153+/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
14154+ * supplying an incorrect user PIN will it to become locked. */
14155+#define CKF_USER_PIN_FINAL_TRY       0x00020000
14156+
14157+/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
14158+ * user PIN has been locked. User login to the token is not
14159+ * possible. */
14160+#define CKF_USER_PIN_LOCKED          0x00040000
14161+
14162+/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
14163+ * the user PIN value is the default value set by token
14164+ * initialization or manufacturing, or the PIN has been
14165+ * expired by the card. */
14166+#define CKF_USER_PIN_TO_BE_CHANGED   0x00080000
14167+
14168+/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
14169+ * incorrect SO login PIN has been entered at least once since
14170+ * the last successful authentication. */
14171+#define CKF_SO_PIN_COUNT_LOW         0x00100000
14172+
14173+/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
14174+ * supplying an incorrect SO PIN will it to become locked. */
14175+#define CKF_SO_PIN_FINAL_TRY         0x00200000
14176+
14177+/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
14178+ * PIN has been locked. SO login to the token is not possible.
14179+ */
14180+#define CKF_SO_PIN_LOCKED            0x00400000
14181+
14182+/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
14183+ * the SO PIN value is the default value set by token
14184+ * initialization or manufacturing, or the PIN has been
14185+ * expired by the card. */
14186+#define CKF_SO_PIN_TO_BE_CHANGED     0x00800000
14187+
14188+typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
14189+
14190+
14191+/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
14192+ * identifies a session */
14193+typedef CK_ULONG          CK_SESSION_HANDLE;
14194+
14195+typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
14196+
14197+
14198+/* CK_USER_TYPE enumerates the types of Cryptoki users */
14199+/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
14200+ * v2.0 */
14201+typedef CK_ULONG          CK_USER_TYPE;
14202+/* Security Officer */
14203+#define CKU_SO    0
14204+/* Normal user */
14205+#define CKU_USER  1
14206+/* Context specific (added in v2.20) */
14207+#define CKU_CONTEXT_SPECIFIC   2
14208+
14209+/* CK_STATE enumerates the session states */
14210+/* CK_STATE has been changed from an enum to a CK_ULONG for
14211+ * v2.0 */
14212+typedef CK_ULONG          CK_STATE;
14213+#define CKS_RO_PUBLIC_SESSION  0
14214+#define CKS_RO_USER_FUNCTIONS  1
14215+#define CKS_RW_PUBLIC_SESSION  2
14216+#define CKS_RW_USER_FUNCTIONS  3
14217+#define CKS_RW_SO_FUNCTIONS    4
14218+
14219+
14220+/* CK_SESSION_INFO provides information about a session */
14221+typedef struct CK_SESSION_INFO {
14222+  CK_SLOT_ID    slotID;
14223+  CK_STATE      state;
14224+  CK_FLAGS      flags;          /* see below */
14225+
14226+  /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
14227+   * v2.0 */
14228+  CK_ULONG      ulDeviceError;  /* device-dependent error code */
14229+} CK_SESSION_INFO;
14230+
14231+/* The flags are defined in the following table:
14232+ *      Bit Flag                Mask        Meaning
14233+ */
14234+#define CKF_RW_SESSION          0x00000002  /* session is r/w */
14235+#define CKF_SERIAL_SESSION      0x00000004  /* no parallel */
14236+
14237+typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
14238+
14239+
14240+/* CK_OBJECT_HANDLE is a token-specific identifier for an
14241+ * object  */
14242+typedef CK_ULONG          CK_OBJECT_HANDLE;
14243+
14244+typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
14245+
14246+
14247+/* CK_OBJECT_CLASS is a value that identifies the classes (or
14248+ * types) of objects that Cryptoki recognizes.  It is defined
14249+ * as follows: */
14250+/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
14251+ * v2.0 */
14252+typedef CK_ULONG          CK_OBJECT_CLASS;
14253+
14254+/* The following classes of objects are defined: */
14255+/* CKO_HW_FEATURE is new for v2.10 */
14256+/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
14257+/* CKO_MECHANISM is new for v2.20 */
14258+#define CKO_DATA              0x00000000
14259+#define CKO_CERTIFICATE       0x00000001
14260+#define CKO_PUBLIC_KEY        0x00000002
14261+#define CKO_PRIVATE_KEY       0x00000003
14262+#define CKO_SECRET_KEY        0x00000004
14263+#define CKO_HW_FEATURE        0x00000005
14264+#define CKO_DOMAIN_PARAMETERS 0x00000006
14265+#define CKO_MECHANISM         0x00000007
14266+
14267+/* CKO_OTP_KEY is new for PKCS #11 v2.20 amendment 1 */
14268+#define CKO_OTP_KEY           0x00000008
14269+
14270+#define CKO_VENDOR_DEFINED    0x80000000
14271+
14272+typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
14273+
14274+/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
14275+ * value that identifies the hardware feature type of an object
14276+ * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
14277+typedef CK_ULONG          CK_HW_FEATURE_TYPE;
14278+
14279+/* The following hardware feature types are defined */
14280+/* CKH_USER_INTERFACE is new for v2.20 */
14281+#define CKH_MONOTONIC_COUNTER  0x00000001
14282+#define CKH_CLOCK           0x00000002
14283+#define CKH_USER_INTERFACE  0x00000003
14284+#define CKH_VENDOR_DEFINED  0x80000000
14285+
14286+/* CK_KEY_TYPE is a value that identifies a key type */
14287+/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
14288+typedef CK_ULONG          CK_KEY_TYPE;
14289+
14290+/* the following key types are defined: */
14291+#define CKK_RSA             0x00000000
14292+#define CKK_DSA             0x00000001
14293+#define CKK_DH              0x00000002
14294+
14295+/* CKK_ECDSA and CKK_KEA are new for v2.0 */
14296+/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
14297+#define CKK_ECDSA           0x00000003
14298+#define CKK_EC              0x00000003
14299+#define CKK_X9_42_DH        0x00000004
14300+#define CKK_KEA             0x00000005
14301+
14302+#define CKK_GENERIC_SECRET  0x00000010
14303+#define CKK_RC2             0x00000011
14304+#define CKK_RC4             0x00000012
14305+#define CKK_DES             0x00000013
14306+#define CKK_DES2            0x00000014
14307+#define CKK_DES3            0x00000015
14308+
14309+/* all these key types are new for v2.0 */
14310+#define CKK_CAST            0x00000016
14311+#define CKK_CAST3           0x00000017
14312+/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
14313+#define CKK_CAST5           0x00000018
14314+#define CKK_CAST128         0x00000018
14315+#define CKK_RC5             0x00000019
14316+#define CKK_IDEA            0x0000001A
14317+#define CKK_SKIPJACK        0x0000001B
14318+#define CKK_BATON           0x0000001C
14319+#define CKK_JUNIPER         0x0000001D
14320+#define CKK_CDMF            0x0000001E
14321+#define CKK_AES             0x0000001F
14322+
14323+/* BlowFish and TwoFish are new for v2.20 */
14324+#define CKK_BLOWFISH        0x00000020
14325+#define CKK_TWOFISH         0x00000021
14326+
14327+/* SecurID, HOTP, and ACTI are new for PKCS #11 v2.20 amendment 1 */
14328+#define CKK_SECURID         0x00000022
14329+#define CKK_HOTP            0x00000023
14330+#define CKK_ACTI            0x00000024
14331+
14332+/* Camellia is new for PKCS #11 v2.20 amendment 3 */
14333+#define CKK_CAMELLIA                   0x00000025
14334+/* ARIA is new for PKCS #11 v2.20 amendment 3 */
14335+#define CKK_ARIA                       0x00000026
14336+
14337+
14338+#define CKK_VENDOR_DEFINED  0x80000000
14339+
14340+
14341+/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
14342+ * type */
14343+/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
14344+ * for v2.0 */
14345+typedef CK_ULONG          CK_CERTIFICATE_TYPE;
14346+
14347+/* The following certificate types are defined: */
14348+/* CKC_X_509_ATTR_CERT is new for v2.10 */
14349+/* CKC_WTLS is new for v2.20 */
14350+#define CKC_X_509           0x00000000
14351+#define CKC_X_509_ATTR_CERT 0x00000001
14352+#define CKC_WTLS            0x00000002
14353+#define CKC_VENDOR_DEFINED  0x80000000
14354+
14355+
14356+/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
14357+ * type */
14358+/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
14359+ * v2.0 */
14360+typedef CK_ULONG          CK_ATTRIBUTE_TYPE;
14361+
14362+/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
14363+   consists of an array of values. */
14364+#define CKF_ARRAY_ATTRIBUTE    0x40000000
14365+
14366+/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1
14367+   and relates to the CKA_OTP_FORMAT attribute */
14368+#define CK_OTP_FORMAT_DECIMAL      0
14369+#define CK_OTP_FORMAT_HEXADECIMAL  1
14370+#define CK_OTP_FORMAT_ALPHANUMERIC 2
14371+#define CK_OTP_FORMAT_BINARY       3
14372+
14373+/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1
14374+   and relates to the CKA_OTP_..._REQUIREMENT attributes */
14375+#define CK_OTP_PARAM_IGNORED       0
14376+#define CK_OTP_PARAM_OPTIONAL      1
14377+#define CK_OTP_PARAM_MANDATORY     2
14378+
14379+/* The following attribute types are defined: */
14380+#define CKA_CLASS              0x00000000
14381+#define CKA_TOKEN              0x00000001
14382+#define CKA_PRIVATE            0x00000002
14383+#define CKA_LABEL              0x00000003
14384+#define CKA_APPLICATION        0x00000010
14385+#define CKA_VALUE              0x00000011
14386+
14387+/* CKA_OBJECT_ID is new for v2.10 */
14388+#define CKA_OBJECT_ID          0x00000012
14389+
14390+#define CKA_CERTIFICATE_TYPE   0x00000080
14391+#define CKA_ISSUER             0x00000081
14392+#define CKA_SERIAL_NUMBER      0x00000082
14393+
14394+/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
14395+ * for v2.10 */
14396+#define CKA_AC_ISSUER          0x00000083
14397+#define CKA_OWNER              0x00000084
14398+#define CKA_ATTR_TYPES         0x00000085
14399+
14400+/* CKA_TRUSTED is new for v2.11 */
14401+#define CKA_TRUSTED            0x00000086
14402+
14403+/* CKA_CERTIFICATE_CATEGORY ...
14404+ * CKA_CHECK_VALUE are new for v2.20 */
14405+#define CKA_CERTIFICATE_CATEGORY        0x00000087
14406+#define CKA_JAVA_MIDP_SECURITY_DOMAIN   0x00000088
14407+#define CKA_URL                         0x00000089
14408+#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY  0x0000008A
14409+#define CKA_HASH_OF_ISSUER_PUBLIC_KEY   0x0000008B
14410+#define CKA_CHECK_VALUE                 0x00000090
14411+
14412+#define CKA_KEY_TYPE           0x00000100
14413+#define CKA_SUBJECT            0x00000101
14414+#define CKA_ID                 0x00000102
14415+#define CKA_SENSITIVE          0x00000103
14416+#define CKA_ENCRYPT            0x00000104
14417+#define CKA_DECRYPT            0x00000105
14418+#define CKA_WRAP               0x00000106
14419+#define CKA_UNWRAP             0x00000107
14420+#define CKA_SIGN               0x00000108
14421+#define CKA_SIGN_RECOVER       0x00000109
14422+#define CKA_VERIFY             0x0000010A
14423+#define CKA_VERIFY_RECOVER     0x0000010B
14424+#define CKA_DERIVE             0x0000010C
14425+#define CKA_START_DATE         0x00000110
14426+#define CKA_END_DATE           0x00000111
14427+#define CKA_MODULUS            0x00000120
14428+#define CKA_MODULUS_BITS       0x00000121
14429+#define CKA_PUBLIC_EXPONENT    0x00000122
14430+#define CKA_PRIVATE_EXPONENT   0x00000123
14431+#define CKA_PRIME_1            0x00000124
14432+#define CKA_PRIME_2            0x00000125
14433+#define CKA_EXPONENT_1         0x00000126
14434+#define CKA_EXPONENT_2         0x00000127
14435+#define CKA_COEFFICIENT        0x00000128
14436+#define CKA_PRIME              0x00000130
14437+#define CKA_SUBPRIME           0x00000131
14438+#define CKA_BASE               0x00000132
14439+
14440+/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
14441+#define CKA_PRIME_BITS         0x00000133
14442+#define CKA_SUBPRIME_BITS      0x00000134
14443+#define CKA_SUB_PRIME_BITS     CKA_SUBPRIME_BITS
14444+/* (To retain backwards-compatibility) */
14445+
14446+#define CKA_VALUE_BITS         0x00000160
14447+#define CKA_VALUE_LEN          0x00000161
14448+
14449+/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
14450+ * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
14451+ * and CKA_EC_POINT are new for v2.0 */
14452+#define CKA_EXTRACTABLE        0x00000162
14453+#define CKA_LOCAL              0x00000163
14454+#define CKA_NEVER_EXTRACTABLE  0x00000164
14455+#define CKA_ALWAYS_SENSITIVE   0x00000165
14456+
14457+/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
14458+#define CKA_KEY_GEN_MECHANISM  0x00000166
14459+
14460+#define CKA_MODIFIABLE         0x00000170
14461+
14462+/* CKA_ECDSA_PARAMS is deprecated in v2.11,
14463+ * CKA_EC_PARAMS is preferred. */
14464+#define CKA_ECDSA_PARAMS       0x00000180
14465+#define CKA_EC_PARAMS          0x00000180
14466+
14467+#define CKA_EC_POINT           0x00000181
14468+
14469+/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
14470+ * are new for v2.10. Deprecated in v2.11 and onwards. */
14471+#define CKA_SECONDARY_AUTH     0x00000200
14472+#define CKA_AUTH_PIN_FLAGS     0x00000201
14473+
14474+/* CKA_ALWAYS_AUTHENTICATE ...
14475+ * CKA_UNWRAP_TEMPLATE are new for v2.20 */
14476+#define CKA_ALWAYS_AUTHENTICATE  0x00000202
14477+
14478+#define CKA_WRAP_WITH_TRUSTED    0x00000210
14479+#define CKA_WRAP_TEMPLATE        (CKF_ARRAY_ATTRIBUTE|0x00000211)
14480+#define CKA_UNWRAP_TEMPLATE      (CKF_ARRAY_ATTRIBUTE|0x00000212)
14481+
14482+/* CKA_OTP... atttributes are new for PKCS #11 v2.20 amendment 3. */
14483+#define CKA_OTP_FORMAT                0x00000220
14484+#define CKA_OTP_LENGTH                0x00000221
14485+#define CKA_OTP_TIME_INTERVAL         0x00000222
14486+#define CKA_OTP_USER_FRIENDLY_MODE    0x00000223
14487+#define CKA_OTP_CHALLENGE_REQUIREMENT 0x00000224
14488+#define CKA_OTP_TIME_REQUIREMENT      0x00000225
14489+#define CKA_OTP_COUNTER_REQUIREMENT   0x00000226
14490+#define CKA_OTP_PIN_REQUIREMENT       0x00000227
14491+#define CKA_OTP_COUNTER               0x0000022E
14492+#define CKA_OTP_TIME                  0x0000022F
14493+#define CKA_OTP_USER_IDENTIFIER       0x0000022A
14494+#define CKA_OTP_SERVICE_IDENTIFIER    0x0000022B
14495+#define CKA_OTP_SERVICE_LOGO          0x0000022C
14496+#define CKA_OTP_SERVICE_LOGO_TYPE     0x0000022D
14497+
14498+
14499+/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
14500+ * are new for v2.10 */
14501+#define CKA_HW_FEATURE_TYPE    0x00000300
14502+#define CKA_RESET_ON_INIT      0x00000301
14503+#define CKA_HAS_RESET          0x00000302
14504+
14505+/* The following attributes are new for v2.20 */
14506+#define CKA_PIXEL_X                     0x00000400
14507+#define CKA_PIXEL_Y                     0x00000401
14508+#define CKA_RESOLUTION                  0x00000402
14509+#define CKA_CHAR_ROWS                   0x00000403
14510+#define CKA_CHAR_COLUMNS                0x00000404
14511+#define CKA_COLOR                       0x00000405
14512+#define CKA_BITS_PER_PIXEL              0x00000406
14513+#define CKA_CHAR_SETS                   0x00000480
14514+#define CKA_ENCODING_METHODS            0x00000481
14515+#define CKA_MIME_TYPES                  0x00000482
14516+#define CKA_MECHANISM_TYPE              0x00000500
14517+#define CKA_REQUIRED_CMS_ATTRIBUTES     0x00000501
14518+#define CKA_DEFAULT_CMS_ATTRIBUTES      0x00000502
14519+#define CKA_SUPPORTED_CMS_ATTRIBUTES    0x00000503
14520+#define CKA_ALLOWED_MECHANISMS          (CKF_ARRAY_ATTRIBUTE|0x00000600)
14521+
14522+#define CKA_VENDOR_DEFINED     0x80000000
14523+
14524+/* CK_ATTRIBUTE is a structure that includes the type, length
14525+ * and value of an attribute */
14526+typedef struct CK_ATTRIBUTE {
14527+  CK_ATTRIBUTE_TYPE type;
14528+  CK_VOID_PTR       pValue;
14529+
14530+  /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
14531+  CK_ULONG          ulValueLen;  /* in bytes */
14532+} CK_ATTRIBUTE;
14533+
14534+typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
14535+
14536+
14537+/* CK_DATE is a structure that defines a date */
14538+typedef struct CK_DATE{
14539+  CK_CHAR       year[4];   /* the year ("1900" - "9999") */
14540+  CK_CHAR       month[2];  /* the month ("01" - "12") */
14541+  CK_CHAR       day[2];    /* the day   ("01" - "31") */
14542+} CK_DATE;
14543+
14544+
14545+/* CK_MECHANISM_TYPE is a value that identifies a mechanism
14546+ * type */
14547+/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
14548+ * v2.0 */
14549+typedef CK_ULONG          CK_MECHANISM_TYPE;
14550+
14551+/* the following mechanism types are defined: */
14552+#define CKM_RSA_PKCS_KEY_PAIR_GEN      0x00000000
14553+#define CKM_RSA_PKCS                   0x00000001
14554+#define CKM_RSA_9796                   0x00000002
14555+#define CKM_RSA_X_509                  0x00000003
14556+
14557+/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
14558+ * are new for v2.0.  They are mechanisms which hash and sign */
14559+#define CKM_MD2_RSA_PKCS               0x00000004
14560+#define CKM_MD5_RSA_PKCS               0x00000005
14561+#define CKM_SHA1_RSA_PKCS              0x00000006
14562+
14563+/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
14564+ * CKM_RSA_PKCS_OAEP are new for v2.10 */
14565+#define CKM_RIPEMD128_RSA_PKCS         0x00000007
14566+#define CKM_RIPEMD160_RSA_PKCS         0x00000008
14567+#define CKM_RSA_PKCS_OAEP              0x00000009
14568+
14569+/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
14570+ * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
14571+#define CKM_RSA_X9_31_KEY_PAIR_GEN     0x0000000A
14572+#define CKM_RSA_X9_31                  0x0000000B
14573+#define CKM_SHA1_RSA_X9_31             0x0000000C
14574+#define CKM_RSA_PKCS_PSS               0x0000000D
14575+#define CKM_SHA1_RSA_PKCS_PSS          0x0000000E
14576+
14577+#define CKM_DSA_KEY_PAIR_GEN           0x00000010
14578+#define CKM_DSA                        0x00000011
14579+#define CKM_DSA_SHA1                   0x00000012
14580+#define CKM_DH_PKCS_KEY_PAIR_GEN       0x00000020
14581+#define CKM_DH_PKCS_DERIVE             0x00000021
14582+
14583+/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
14584+ * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
14585+ * v2.11 */
14586+#define CKM_X9_42_DH_KEY_PAIR_GEN      0x00000030
14587+#define CKM_X9_42_DH_DERIVE            0x00000031
14588+#define CKM_X9_42_DH_HYBRID_DERIVE     0x00000032
14589+#define CKM_X9_42_MQV_DERIVE           0x00000033
14590+
14591+/* CKM_SHA256/384/512 are new for v2.20 */
14592+#define CKM_SHA256_RSA_PKCS            0x00000040
14593+#define CKM_SHA384_RSA_PKCS            0x00000041
14594+#define CKM_SHA512_RSA_PKCS            0x00000042
14595+#define CKM_SHA256_RSA_PKCS_PSS        0x00000043
14596+#define CKM_SHA384_RSA_PKCS_PSS        0x00000044
14597+#define CKM_SHA512_RSA_PKCS_PSS        0x00000045
14598+
14599+/* SHA-224 RSA mechanisms are new for PKCS #11 v2.20 amendment 3 */
14600+#define CKM_SHA224_RSA_PKCS            0x00000046
14601+#define CKM_SHA224_RSA_PKCS_PSS        0x00000047
14602+
14603+#define CKM_RC2_KEY_GEN                0x00000100
14604+#define CKM_RC2_ECB                    0x00000101
14605+#define CKM_RC2_CBC                    0x00000102
14606+#define CKM_RC2_MAC                    0x00000103
14607+
14608+/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
14609+#define CKM_RC2_MAC_GENERAL            0x00000104
14610+#define CKM_RC2_CBC_PAD                0x00000105
14611+
14612+#define CKM_RC4_KEY_GEN                0x00000110
14613+#define CKM_RC4                        0x00000111
14614+#define CKM_DES_KEY_GEN                0x00000120
14615+#define CKM_DES_ECB                    0x00000121
14616+#define CKM_DES_CBC                    0x00000122
14617+#define CKM_DES_MAC                    0x00000123
14618+
14619+/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
14620+#define CKM_DES_MAC_GENERAL            0x00000124
14621+#define CKM_DES_CBC_PAD                0x00000125
14622+
14623+#define CKM_DES2_KEY_GEN               0x00000130
14624+#define CKM_DES3_KEY_GEN               0x00000131
14625+#define CKM_DES3_ECB                   0x00000132
14626+#define CKM_DES3_CBC                   0x00000133
14627+#define CKM_DES3_MAC                   0x00000134
14628+
14629+/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
14630+ * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
14631+ * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
14632+#define CKM_DES3_MAC_GENERAL           0x00000135
14633+#define CKM_DES3_CBC_PAD               0x00000136
14634+#define CKM_CDMF_KEY_GEN               0x00000140
14635+#define CKM_CDMF_ECB                   0x00000141
14636+#define CKM_CDMF_CBC                   0x00000142
14637+#define CKM_CDMF_MAC                   0x00000143
14638+#define CKM_CDMF_MAC_GENERAL           0x00000144
14639+#define CKM_CDMF_CBC_PAD               0x00000145
14640+
14641+/* the following four DES mechanisms are new for v2.20 */
14642+#define CKM_DES_OFB64                  0x00000150
14643+#define CKM_DES_OFB8                   0x00000151
14644+#define CKM_DES_CFB64                  0x00000152
14645+#define CKM_DES_CFB8                   0x00000153
14646+
14647+#define CKM_MD2                        0x00000200
14648+
14649+/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
14650+#define CKM_MD2_HMAC                   0x00000201
14651+#define CKM_MD2_HMAC_GENERAL           0x00000202
14652+
14653+#define CKM_MD5                        0x00000210
14654+
14655+/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
14656+#define CKM_MD5_HMAC                   0x00000211
14657+#define CKM_MD5_HMAC_GENERAL           0x00000212
14658+
14659+#define CKM_SHA_1                      0x00000220
14660+
14661+/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
14662+#define CKM_SHA_1_HMAC                 0x00000221
14663+#define CKM_SHA_1_HMAC_GENERAL         0x00000222
14664+
14665+/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
14666+ * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
14667+ * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
14668+#define CKM_RIPEMD128                  0x00000230
14669+#define CKM_RIPEMD128_HMAC             0x00000231
14670+#define CKM_RIPEMD128_HMAC_GENERAL     0x00000232
14671+#define CKM_RIPEMD160                  0x00000240
14672+#define CKM_RIPEMD160_HMAC             0x00000241
14673+#define CKM_RIPEMD160_HMAC_GENERAL     0x00000242
14674+
14675+/* CKM_SHA256/384/512 are new for v2.20 */
14676+#define CKM_SHA256                     0x00000250
14677+#define CKM_SHA256_HMAC                0x00000251
14678+#define CKM_SHA256_HMAC_GENERAL        0x00000252
14679+
14680+/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
14681+#define CKM_SHA224                     0x00000255
14682+#define CKM_SHA224_HMAC                0x00000256
14683+#define CKM_SHA224_HMAC_GENERAL        0x00000257
14684+
14685+#define CKM_SHA384                     0x00000260
14686+#define CKM_SHA384_HMAC                0x00000261
14687+#define CKM_SHA384_HMAC_GENERAL        0x00000262
14688+#define CKM_SHA512                     0x00000270
14689+#define CKM_SHA512_HMAC                0x00000271
14690+#define CKM_SHA512_HMAC_GENERAL        0x00000272
14691+
14692+/* SecurID is new for PKCS #11 v2.20 amendment 1 */
14693+#define CKM_SECURID_KEY_GEN            0x00000280
14694+#define CKM_SECURID                    0x00000282
14695+
14696+/* HOTP is new for PKCS #11 v2.20 amendment 1 */
14697+#define CKM_HOTP_KEY_GEN    0x00000290
14698+#define CKM_HOTP            0x00000291
14699+
14700+/* ACTI is new for PKCS #11 v2.20 amendment 1 */
14701+#define CKM_ACTI            0x000002A0
14702+#define CKM_ACTI_KEY_GEN    0x000002A1
14703+
14704+/* All of the following mechanisms are new for v2.0 */
14705+/* Note that CAST128 and CAST5 are the same algorithm */
14706+#define CKM_CAST_KEY_GEN               0x00000300
14707+#define CKM_CAST_ECB                   0x00000301
14708+#define CKM_CAST_CBC                   0x00000302
14709+#define CKM_CAST_MAC                   0x00000303
14710+#define CKM_CAST_MAC_GENERAL           0x00000304
14711+#define CKM_CAST_CBC_PAD               0x00000305
14712+#define CKM_CAST3_KEY_GEN              0x00000310
14713+#define CKM_CAST3_ECB                  0x00000311
14714+#define CKM_CAST3_CBC                  0x00000312
14715+#define CKM_CAST3_MAC                  0x00000313
14716+#define CKM_CAST3_MAC_GENERAL          0x00000314
14717+#define CKM_CAST3_CBC_PAD              0x00000315
14718+#define CKM_CAST5_KEY_GEN              0x00000320
14719+#define CKM_CAST128_KEY_GEN            0x00000320
14720+#define CKM_CAST5_ECB                  0x00000321
14721+#define CKM_CAST128_ECB                0x00000321
14722+#define CKM_CAST5_CBC                  0x00000322
14723+#define CKM_CAST128_CBC                0x00000322
14724+#define CKM_CAST5_MAC                  0x00000323
14725+#define CKM_CAST128_MAC                0x00000323
14726+#define CKM_CAST5_MAC_GENERAL          0x00000324
14727+#define CKM_CAST128_MAC_GENERAL        0x00000324
14728+#define CKM_CAST5_CBC_PAD              0x00000325
14729+#define CKM_CAST128_CBC_PAD            0x00000325
14730+#define CKM_RC5_KEY_GEN                0x00000330
14731+#define CKM_RC5_ECB                    0x00000331
14732+#define CKM_RC5_CBC                    0x00000332
14733+#define CKM_RC5_MAC                    0x00000333
14734+#define CKM_RC5_MAC_GENERAL            0x00000334
14735+#define CKM_RC5_CBC_PAD                0x00000335
14736+#define CKM_IDEA_KEY_GEN               0x00000340
14737+#define CKM_IDEA_ECB                   0x00000341
14738+#define CKM_IDEA_CBC                   0x00000342
14739+#define CKM_IDEA_MAC                   0x00000343
14740+#define CKM_IDEA_MAC_GENERAL           0x00000344
14741+#define CKM_IDEA_CBC_PAD               0x00000345
14742+#define CKM_GENERIC_SECRET_KEY_GEN     0x00000350
14743+#define CKM_CONCATENATE_BASE_AND_KEY   0x00000360
14744+#define CKM_CONCATENATE_BASE_AND_DATA  0x00000362
14745+#define CKM_CONCATENATE_DATA_AND_BASE  0x00000363
14746+#define CKM_XOR_BASE_AND_DATA          0x00000364
14747+#define CKM_EXTRACT_KEY_FROM_KEY       0x00000365
14748+#define CKM_SSL3_PRE_MASTER_KEY_GEN    0x00000370
14749+#define CKM_SSL3_MASTER_KEY_DERIVE     0x00000371
14750+#define CKM_SSL3_KEY_AND_MAC_DERIVE    0x00000372
14751+
14752+/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
14753+ * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
14754+ * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
14755+#define CKM_SSL3_MASTER_KEY_DERIVE_DH  0x00000373
14756+#define CKM_TLS_PRE_MASTER_KEY_GEN     0x00000374
14757+#define CKM_TLS_MASTER_KEY_DERIVE      0x00000375
14758+#define CKM_TLS_KEY_AND_MAC_DERIVE     0x00000376
14759+#define CKM_TLS_MASTER_KEY_DERIVE_DH   0x00000377
14760+
14761+/* CKM_TLS_PRF is new for v2.20 */
14762+#define CKM_TLS_PRF                    0x00000378
14763+
14764+#define CKM_SSL3_MD5_MAC               0x00000380
14765+#define CKM_SSL3_SHA1_MAC              0x00000381
14766+#define CKM_MD5_KEY_DERIVATION         0x00000390
14767+#define CKM_MD2_KEY_DERIVATION         0x00000391
14768+#define CKM_SHA1_KEY_DERIVATION        0x00000392
14769+
14770+/* CKM_SHA256/384/512 are new for v2.20 */
14771+#define CKM_SHA256_KEY_DERIVATION      0x00000393
14772+#define CKM_SHA384_KEY_DERIVATION      0x00000394
14773+#define CKM_SHA512_KEY_DERIVATION      0x00000395
14774+
14775+/* SHA-224 key derivation is new for PKCS #11 v2.20 amendment 3 */
14776+#define CKM_SHA224_KEY_DERIVATION      0x00000396
14777+
14778+#define CKM_PBE_MD2_DES_CBC            0x000003A0
14779+#define CKM_PBE_MD5_DES_CBC            0x000003A1
14780+#define CKM_PBE_MD5_CAST_CBC           0x000003A2
14781+#define CKM_PBE_MD5_CAST3_CBC          0x000003A3
14782+#define CKM_PBE_MD5_CAST5_CBC          0x000003A4
14783+#define CKM_PBE_MD5_CAST128_CBC        0x000003A4
14784+#define CKM_PBE_SHA1_CAST5_CBC         0x000003A5
14785+#define CKM_PBE_SHA1_CAST128_CBC       0x000003A5
14786+#define CKM_PBE_SHA1_RC4_128           0x000003A6
14787+#define CKM_PBE_SHA1_RC4_40            0x000003A7
14788+#define CKM_PBE_SHA1_DES3_EDE_CBC      0x000003A8
14789+#define CKM_PBE_SHA1_DES2_EDE_CBC      0x000003A9
14790+#define CKM_PBE_SHA1_RC2_128_CBC       0x000003AA
14791+#define CKM_PBE_SHA1_RC2_40_CBC        0x000003AB
14792+
14793+/* CKM_PKCS5_PBKD2 is new for v2.10 */
14794+#define CKM_PKCS5_PBKD2                0x000003B0
14795+
14796+#define CKM_PBA_SHA1_WITH_SHA1_HMAC    0x000003C0
14797+
14798+/* WTLS mechanisms are new for v2.20 */
14799+#define CKM_WTLS_PRE_MASTER_KEY_GEN         0x000003D0
14800+#define CKM_WTLS_MASTER_KEY_DERIVE          0x000003D1
14801+#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC   0x000003D2
14802+#define CKM_WTLS_PRF                        0x000003D3
14803+#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE  0x000003D4
14804+#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE  0x000003D5
14805+
14806+#define CKM_KEY_WRAP_LYNKS             0x00000400
14807+#define CKM_KEY_WRAP_SET_OAEP          0x00000401
14808+
14809+/* CKM_CMS_SIG is new for v2.20 */
14810+#define CKM_CMS_SIG                    0x00000500
14811+
14812+/* CKM_KIP mechanisms are new for PKCS #11 v2.20 amendment 2 */
14813+#define CKM_KIP_DERIVE                 0x00000510
14814+#define CKM_KIP_WRAP                   0x00000511
14815+#define CKM_KIP_MAC                    0x00000512
14816+
14817+/* Camellia is new for PKCS #11 v2.20 amendment 3 */
14818+#define CKM_CAMELLIA_KEY_GEN           0x00000550
14819+#define CKM_CAMELLIA_ECB               0x00000551
14820+#define CKM_CAMELLIA_CBC               0x00000552
14821+#define CKM_CAMELLIA_MAC               0x00000553
14822+#define CKM_CAMELLIA_MAC_GENERAL       0x00000554
14823+#define CKM_CAMELLIA_CBC_PAD           0x00000555
14824+#define CKM_CAMELLIA_ECB_ENCRYPT_DATA  0x00000556
14825+#define CKM_CAMELLIA_CBC_ENCRYPT_DATA  0x00000557
14826+#define CKM_CAMELLIA_CTR               0x00000558
14827+
14828+/* ARIA is new for PKCS #11 v2.20 amendment 3 */
14829+#define CKM_ARIA_KEY_GEN               0x00000560
14830+#define CKM_ARIA_ECB                   0x00000561
14831+#define CKM_ARIA_CBC                   0x00000562
14832+#define CKM_ARIA_MAC                   0x00000563
14833+#define CKM_ARIA_MAC_GENERAL           0x00000564
14834+#define CKM_ARIA_CBC_PAD               0x00000565
14835+#define CKM_ARIA_ECB_ENCRYPT_DATA      0x00000566
14836+#define CKM_ARIA_CBC_ENCRYPT_DATA      0x00000567
14837+
14838+/* Fortezza mechanisms */
14839+#define CKM_SKIPJACK_KEY_GEN           0x00001000
14840+#define CKM_SKIPJACK_ECB64             0x00001001
14841+#define CKM_SKIPJACK_CBC64             0x00001002
14842+#define CKM_SKIPJACK_OFB64             0x00001003
14843+#define CKM_SKIPJACK_CFB64             0x00001004
14844+#define CKM_SKIPJACK_CFB32             0x00001005
14845+#define CKM_SKIPJACK_CFB16             0x00001006
14846+#define CKM_SKIPJACK_CFB8              0x00001007
14847+#define CKM_SKIPJACK_WRAP              0x00001008
14848+#define CKM_SKIPJACK_PRIVATE_WRAP      0x00001009
14849+#define CKM_SKIPJACK_RELAYX            0x0000100a
14850+#define CKM_KEA_KEY_PAIR_GEN           0x00001010
14851+#define CKM_KEA_KEY_DERIVE             0x00001011
14852+#define CKM_FORTEZZA_TIMESTAMP         0x00001020
14853+#define CKM_BATON_KEY_GEN              0x00001030
14854+#define CKM_BATON_ECB128               0x00001031
14855+#define CKM_BATON_ECB96                0x00001032
14856+#define CKM_BATON_CBC128               0x00001033
14857+#define CKM_BATON_COUNTER              0x00001034
14858+#define CKM_BATON_SHUFFLE              0x00001035
14859+#define CKM_BATON_WRAP                 0x00001036
14860+
14861+/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
14862+ * CKM_EC_KEY_PAIR_GEN is preferred */
14863+#define CKM_ECDSA_KEY_PAIR_GEN         0x00001040
14864+#define CKM_EC_KEY_PAIR_GEN            0x00001040
14865+
14866+#define CKM_ECDSA                      0x00001041
14867+#define CKM_ECDSA_SHA1                 0x00001042
14868+
14869+/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
14870+ * are new for v2.11 */
14871+#define CKM_ECDH1_DERIVE               0x00001050
14872+#define CKM_ECDH1_COFACTOR_DERIVE      0x00001051
14873+#define CKM_ECMQV_DERIVE               0x00001052
14874+
14875+#define CKM_JUNIPER_KEY_GEN            0x00001060
14876+#define CKM_JUNIPER_ECB128             0x00001061
14877+#define CKM_JUNIPER_CBC128             0x00001062
14878+#define CKM_JUNIPER_COUNTER            0x00001063
14879+#define CKM_JUNIPER_SHUFFLE            0x00001064
14880+#define CKM_JUNIPER_WRAP               0x00001065
14881+#define CKM_FASTHASH                   0x00001070
14882+
14883+/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
14884+ * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
14885+ * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
14886+ * new for v2.11 */
14887+#define CKM_AES_KEY_GEN                0x00001080
14888+#define CKM_AES_ECB                    0x00001081
14889+#define CKM_AES_CBC                    0x00001082
14890+#define CKM_AES_MAC                    0x00001083
14891+#define CKM_AES_MAC_GENERAL            0x00001084
14892+#define CKM_AES_CBC_PAD                0x00001085
14893+
14894+/* AES counter mode is new for PKCS #11 v2.20 amendment 3 */
14895+#define CKM_AES_CTR                    0x00001086
14896+
14897+/* BlowFish and TwoFish are new for v2.20 */
14898+#define CKM_BLOWFISH_KEY_GEN           0x00001090
14899+#define CKM_BLOWFISH_CBC               0x00001091
14900+#define CKM_TWOFISH_KEY_GEN            0x00001092
14901+#define CKM_TWOFISH_CBC                0x00001093
14902+
14903+
14904+/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */
14905+#define CKM_DES_ECB_ENCRYPT_DATA       0x00001100
14906+#define CKM_DES_CBC_ENCRYPT_DATA       0x00001101
14907+#define CKM_DES3_ECB_ENCRYPT_DATA      0x00001102
14908+#define CKM_DES3_CBC_ENCRYPT_DATA      0x00001103
14909+#define CKM_AES_ECB_ENCRYPT_DATA       0x00001104
14910+#define CKM_AES_CBC_ENCRYPT_DATA       0x00001105
14911+
14912+#define CKM_DSA_PARAMETER_GEN          0x00002000
14913+#define CKM_DH_PKCS_PARAMETER_GEN      0x00002001
14914+#define CKM_X9_42_DH_PARAMETER_GEN     0x00002002
14915+
14916+#define CKM_VENDOR_DEFINED             0x80000000
14917+
14918+typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
14919+
14920+
14921+/* CK_MECHANISM is a structure that specifies a particular
14922+ * mechanism  */
14923+typedef struct CK_MECHANISM {
14924+  CK_MECHANISM_TYPE mechanism;
14925+  CK_VOID_PTR       pParameter;
14926+
14927+  /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
14928+   * v2.0 */
14929+  CK_ULONG          ulParameterLen;  /* in bytes */
14930+} CK_MECHANISM;
14931+
14932+typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
14933+
14934+
14935+/* CK_MECHANISM_INFO provides information about a particular
14936+ * mechanism */
14937+typedef struct CK_MECHANISM_INFO {
14938+    CK_ULONG    ulMinKeySize;
14939+    CK_ULONG    ulMaxKeySize;
14940+    CK_FLAGS    flags;
14941+} CK_MECHANISM_INFO;
14942+
14943+/* The flags are defined as follows:
14944+ *      Bit Flag               Mask        Meaning */
14945+#define CKF_HW                 0x00000001  /* performed by HW */
14946+
14947+/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
14948+ * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
14949+ * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
14950+ * and CKF_DERIVE are new for v2.0.  They specify whether or not
14951+ * a mechanism can be used for a particular task */
14952+#define CKF_ENCRYPT            0x00000100
14953+#define CKF_DECRYPT            0x00000200
14954+#define CKF_DIGEST             0x00000400
14955+#define CKF_SIGN               0x00000800
14956+#define CKF_SIGN_RECOVER       0x00001000
14957+#define CKF_VERIFY             0x00002000
14958+#define CKF_VERIFY_RECOVER     0x00004000
14959+#define CKF_GENERATE           0x00008000
14960+#define CKF_GENERATE_KEY_PAIR  0x00010000
14961+#define CKF_WRAP               0x00020000
14962+#define CKF_UNWRAP             0x00040000
14963+#define CKF_DERIVE             0x00080000
14964+
14965+/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
14966+ * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
14967+ * describe a token's EC capabilities not available in mechanism
14968+ * information. */
14969+#define CKF_EC_F_P             0x00100000
14970+#define CKF_EC_F_2M            0x00200000
14971+#define CKF_EC_ECPARAMETERS    0x00400000
14972+#define CKF_EC_NAMEDCURVE      0x00800000
14973+#define CKF_EC_UNCOMPRESS      0x01000000
14974+#define CKF_EC_COMPRESS        0x02000000
14975+
14976+#define CKF_EXTENSION          0x80000000 /* FALSE for this version */
14977+
14978+typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
14979+
14980+
14981+/* CK_RV is a value that identifies the return value of a
14982+ * Cryptoki function */
14983+/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
14984+typedef CK_ULONG          CK_RV;
14985+
14986+#define CKR_OK                                0x00000000
14987+#define CKR_CANCEL                            0x00000001
14988+#define CKR_HOST_MEMORY                       0x00000002
14989+#define CKR_SLOT_ID_INVALID                   0x00000003
14990+
14991+/* CKR_FLAGS_INVALID was removed for v2.0 */
14992+
14993+/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
14994+#define CKR_GENERAL_ERROR                     0x00000005
14995+#define CKR_FUNCTION_FAILED                   0x00000006
14996+
14997+/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
14998+ * and CKR_CANT_LOCK are new for v2.01 */
14999+#define CKR_ARGUMENTS_BAD                     0x00000007
15000+#define CKR_NO_EVENT                          0x00000008
15001+#define CKR_NEED_TO_CREATE_THREADS            0x00000009
15002+#define CKR_CANT_LOCK                         0x0000000A
15003+
15004+#define CKR_ATTRIBUTE_READ_ONLY               0x00000010
15005+#define CKR_ATTRIBUTE_SENSITIVE               0x00000011
15006+#define CKR_ATTRIBUTE_TYPE_INVALID            0x00000012
15007+#define CKR_ATTRIBUTE_VALUE_INVALID           0x00000013
15008+#define CKR_DATA_INVALID                      0x00000020
15009+#define CKR_DATA_LEN_RANGE                    0x00000021
15010+#define CKR_DEVICE_ERROR                      0x00000030
15011+#define CKR_DEVICE_MEMORY                     0x00000031
15012+#define CKR_DEVICE_REMOVED                    0x00000032
15013+#define CKR_ENCRYPTED_DATA_INVALID            0x00000040
15014+#define CKR_ENCRYPTED_DATA_LEN_RANGE          0x00000041
15015+#define CKR_FUNCTION_CANCELED                 0x00000050
15016+#define CKR_FUNCTION_NOT_PARALLEL             0x00000051
15017+
15018+/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
15019+#define CKR_FUNCTION_NOT_SUPPORTED            0x00000054
15020+
15021+#define CKR_KEY_HANDLE_INVALID                0x00000060
15022+
15023+/* CKR_KEY_SENSITIVE was removed for v2.0 */
15024+
15025+#define CKR_KEY_SIZE_RANGE                    0x00000062
15026+#define CKR_KEY_TYPE_INCONSISTENT             0x00000063
15027+
15028+/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
15029+ * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
15030+ * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
15031+ * v2.0 */
15032+#define CKR_KEY_NOT_NEEDED                    0x00000064
15033+#define CKR_KEY_CHANGED                       0x00000065
15034+#define CKR_KEY_NEEDED                        0x00000066
15035+#define CKR_KEY_INDIGESTIBLE                  0x00000067
15036+#define CKR_KEY_FUNCTION_NOT_PERMITTED        0x00000068
15037+#define CKR_KEY_NOT_WRAPPABLE                 0x00000069
15038+#define CKR_KEY_UNEXTRACTABLE                 0x0000006A
15039+
15040+#define CKR_MECHANISM_INVALID                 0x00000070
15041+#define CKR_MECHANISM_PARAM_INVALID           0x00000071
15042+
15043+/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
15044+ * were removed for v2.0 */
15045+#define CKR_OBJECT_HANDLE_INVALID             0x00000082
15046+#define CKR_OPERATION_ACTIVE                  0x00000090
15047+#define CKR_OPERATION_NOT_INITIALIZED         0x00000091
15048+#define CKR_PIN_INCORRECT                     0x000000A0
15049+#define CKR_PIN_INVALID                       0x000000A1
15050+#define CKR_PIN_LEN_RANGE                     0x000000A2
15051+
15052+/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
15053+#define CKR_PIN_EXPIRED                       0x000000A3
15054+#define CKR_PIN_LOCKED                        0x000000A4
15055+
15056+#define CKR_SESSION_CLOSED                    0x000000B0
15057+#define CKR_SESSION_COUNT                     0x000000B1
15058+#define CKR_SESSION_HANDLE_INVALID            0x000000B3
15059+#define CKR_SESSION_PARALLEL_NOT_SUPPORTED    0x000000B4
15060+#define CKR_SESSION_READ_ONLY                 0x000000B5
15061+#define CKR_SESSION_EXISTS                    0x000000B6
15062+
15063+/* CKR_SESSION_READ_ONLY_EXISTS and
15064+ * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
15065+#define CKR_SESSION_READ_ONLY_EXISTS          0x000000B7
15066+#define CKR_SESSION_READ_WRITE_SO_EXISTS      0x000000B8
15067+
15068+#define CKR_SIGNATURE_INVALID                 0x000000C0
15069+#define CKR_SIGNATURE_LEN_RANGE               0x000000C1
15070+#define CKR_TEMPLATE_INCOMPLETE               0x000000D0
15071+#define CKR_TEMPLATE_INCONSISTENT             0x000000D1
15072+#define CKR_TOKEN_NOT_PRESENT                 0x000000E0
15073+#define CKR_TOKEN_NOT_RECOGNIZED              0x000000E1
15074+#define CKR_TOKEN_WRITE_PROTECTED             0x000000E2
15075+#define CKR_UNWRAPPING_KEY_HANDLE_INVALID     0x000000F0
15076+#define CKR_UNWRAPPING_KEY_SIZE_RANGE         0x000000F1
15077+#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT  0x000000F2
15078+#define CKR_USER_ALREADY_LOGGED_IN            0x00000100
15079+#define CKR_USER_NOT_LOGGED_IN                0x00000101
15080+#define CKR_USER_PIN_NOT_INITIALIZED          0x00000102
15081+#define CKR_USER_TYPE_INVALID                 0x00000103
15082+
15083+/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
15084+ * are new to v2.01 */
15085+#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN    0x00000104
15086+#define CKR_USER_TOO_MANY_TYPES               0x00000105
15087+
15088+#define CKR_WRAPPED_KEY_INVALID               0x00000110
15089+#define CKR_WRAPPED_KEY_LEN_RANGE             0x00000112
15090+#define CKR_WRAPPING_KEY_HANDLE_INVALID       0x00000113
15091+#define CKR_WRAPPING_KEY_SIZE_RANGE           0x00000114
15092+#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT    0x00000115
15093+#define CKR_RANDOM_SEED_NOT_SUPPORTED         0x00000120
15094+
15095+/* These are new to v2.0 */
15096+#define CKR_RANDOM_NO_RNG                     0x00000121
15097+
15098+/* These are new to v2.11 */
15099+#define CKR_DOMAIN_PARAMS_INVALID             0x00000130
15100+
15101+/* These are new to v2.0 */
15102+#define CKR_BUFFER_TOO_SMALL                  0x00000150
15103+#define CKR_SAVED_STATE_INVALID               0x00000160
15104+#define CKR_INFORMATION_SENSITIVE             0x00000170
15105+#define CKR_STATE_UNSAVEABLE                  0x00000180
15106+
15107+/* These are new to v2.01 */
15108+#define CKR_CRYPTOKI_NOT_INITIALIZED          0x00000190
15109+#define CKR_CRYPTOKI_ALREADY_INITIALIZED      0x00000191
15110+#define CKR_MUTEX_BAD                         0x000001A0
15111+#define CKR_MUTEX_NOT_LOCKED                  0x000001A1
15112+
15113+/* The following return values are new for PKCS #11 v2.20 amendment 3 */
15114+#define CKR_NEW_PIN_MODE                      0x000001B0
15115+#define CKR_NEXT_OTP                          0x000001B1
15116+
15117+/* This is new to v2.20 */
15118+#define CKR_FUNCTION_REJECTED                 0x00000200
15119+
15120+#define CKR_VENDOR_DEFINED                    0x80000000
15121+
15122+
15123+/* CK_NOTIFY is an application callback that processes events */
15124+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
15125+  CK_SESSION_HANDLE hSession,     /* the session's handle */
15126+  CK_NOTIFICATION   event,
15127+  CK_VOID_PTR       pApplication  /* passed to C_OpenSession */
15128+);
15129+
15130+
15131+/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
15132+ * version and pointers of appropriate types to all the
15133+ * Cryptoki functions */
15134+/* CK_FUNCTION_LIST is new for v2.0 */
15135+typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
15136+
15137+typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
15138+
15139+typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
15140+
15141+
15142+/* CK_CREATEMUTEX is an application callback for creating a
15143+ * mutex object */
15144+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
15145+  CK_VOID_PTR_PTR ppMutex  /* location to receive ptr to mutex */
15146+);
15147+
15148+
15149+/* CK_DESTROYMUTEX is an application callback for destroying a
15150+ * mutex object */
15151+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
15152+  CK_VOID_PTR pMutex  /* pointer to mutex */
15153+);
15154+
15155+
15156+/* CK_LOCKMUTEX is an application callback for locking a mutex */
15157+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
15158+  CK_VOID_PTR pMutex  /* pointer to mutex */
15159+);
15160+
15161+
15162+/* CK_UNLOCKMUTEX is an application callback for unlocking a
15163+ * mutex */
15164+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
15165+  CK_VOID_PTR pMutex  /* pointer to mutex */
15166+);
15167+
15168+
15169+/* CK_C_INITIALIZE_ARGS provides the optional arguments to
15170+ * C_Initialize */
15171+typedef struct CK_C_INITIALIZE_ARGS {
15172+  CK_CREATEMUTEX CreateMutex;
15173+  CK_DESTROYMUTEX DestroyMutex;
15174+  CK_LOCKMUTEX LockMutex;
15175+  CK_UNLOCKMUTEX UnlockMutex;
15176+  CK_FLAGS flags;
15177+  CK_VOID_PTR pReserved;
15178+} CK_C_INITIALIZE_ARGS;
15179+
15180+/* flags: bit flags that provide capabilities of the slot
15181+ *      Bit Flag                           Mask       Meaning
15182+ */
15183+#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
15184+#define CKF_OS_LOCKING_OK                  0x00000002
15185+
15186+typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
15187+
15188+
15189+/* additional flags for parameters to functions */
15190+
15191+/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
15192+#define CKF_DONT_BLOCK     1
15193+
15194+/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
15195+ * CK_RSA_PKCS_OAEP_MGF_TYPE  is used to indicate the Message
15196+ * Generation Function (MGF) applied to a message block when
15197+ * formatting a message block for the PKCS #1 OAEP encryption
15198+ * scheme. */
15199+typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
15200+
15201+typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
15202+
15203+/* The following MGFs are defined */
15204+/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512
15205+ * are new for v2.20 */
15206+#define CKG_MGF1_SHA1         0x00000001
15207+#define CKG_MGF1_SHA256       0x00000002
15208+#define CKG_MGF1_SHA384       0x00000003
15209+#define CKG_MGF1_SHA512       0x00000004
15210+/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
15211+#define CKG_MGF1_SHA224       0x00000005
15212+
15213+/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
15214+ * CK_RSA_PKCS_OAEP_SOURCE_TYPE  is used to indicate the source
15215+ * of the encoding parameter when formatting a message block
15216+ * for the PKCS #1 OAEP encryption scheme. */
15217+typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
15218+
15219+typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
15220+
15221+/* The following encoding parameter sources are defined */
15222+#define CKZ_DATA_SPECIFIED    0x00000001
15223+
15224+/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
15225+ * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
15226+ * CKM_RSA_PKCS_OAEP mechanism. */
15227+typedef struct CK_RSA_PKCS_OAEP_PARAMS {
15228+        CK_MECHANISM_TYPE hashAlg;
15229+        CK_RSA_PKCS_MGF_TYPE mgf;
15230+        CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
15231+        CK_VOID_PTR pSourceData;
15232+        CK_ULONG ulSourceDataLen;
15233+} CK_RSA_PKCS_OAEP_PARAMS;
15234+
15235+typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
15236+
15237+/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11.
15238+ * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
15239+ * CKM_RSA_PKCS_PSS mechanism(s). */
15240+typedef struct CK_RSA_PKCS_PSS_PARAMS {
15241+        CK_MECHANISM_TYPE    hashAlg;
15242+        CK_RSA_PKCS_MGF_TYPE mgf;
15243+        CK_ULONG             sLen;
15244+} CK_RSA_PKCS_PSS_PARAMS;
15245+
15246+typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
15247+
15248+/* CK_EC_KDF_TYPE is new for v2.11. */
15249+typedef CK_ULONG CK_EC_KDF_TYPE;
15250+
15251+/* The following EC Key Derivation Functions are defined */
15252+#define CKD_NULL                 0x00000001
15253+#define CKD_SHA1_KDF             0x00000002
15254+
15255+/* CK_ECDH1_DERIVE_PARAMS is new for v2.11.
15256+ * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
15257+ * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
15258+ * where each party contributes one key pair.
15259+ */
15260+typedef struct CK_ECDH1_DERIVE_PARAMS {
15261+  CK_EC_KDF_TYPE kdf;
15262+  CK_ULONG ulSharedDataLen;
15263+  CK_BYTE_PTR pSharedData;
15264+  CK_ULONG ulPublicDataLen;
15265+  CK_BYTE_PTR pPublicData;
15266+} CK_ECDH1_DERIVE_PARAMS;
15267+
15268+typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
15269+
15270+
15271+/* CK_ECDH2_DERIVE_PARAMS is new for v2.11.
15272+ * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
15273+ * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */
15274+typedef struct CK_ECDH2_DERIVE_PARAMS {
15275+  CK_EC_KDF_TYPE kdf;
15276+  CK_ULONG ulSharedDataLen;
15277+  CK_BYTE_PTR pSharedData;
15278+  CK_ULONG ulPublicDataLen;
15279+  CK_BYTE_PTR pPublicData;
15280+  CK_ULONG ulPrivateDataLen;
15281+  CK_OBJECT_HANDLE hPrivateData;
15282+  CK_ULONG ulPublicDataLen2;
15283+  CK_BYTE_PTR pPublicData2;
15284+} CK_ECDH2_DERIVE_PARAMS;
15285+
15286+typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
15287+
15288+typedef struct CK_ECMQV_DERIVE_PARAMS {
15289+  CK_EC_KDF_TYPE kdf;
15290+  CK_ULONG ulSharedDataLen;
15291+  CK_BYTE_PTR pSharedData;
15292+  CK_ULONG ulPublicDataLen;
15293+  CK_BYTE_PTR pPublicData;
15294+  CK_ULONG ulPrivateDataLen;
15295+  CK_OBJECT_HANDLE hPrivateData;
15296+  CK_ULONG ulPublicDataLen2;
15297+  CK_BYTE_PTR pPublicData2;
15298+  CK_OBJECT_HANDLE publicKey;
15299+} CK_ECMQV_DERIVE_PARAMS;
15300+
15301+typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
15302+
15303+/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
15304+ * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */
15305+typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
15306+typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
15307+
15308+/* The following X9.42 DH key derivation functions are defined
15309+   (besides CKD_NULL already defined : */
15310+#define CKD_SHA1_KDF_ASN1        0x00000003
15311+#define CKD_SHA1_KDF_CONCATENATE 0x00000004
15312+
15313+/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11.
15314+ * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
15315+ * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
15316+ * contributes one key pair */
15317+typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
15318+  CK_X9_42_DH_KDF_TYPE kdf;
15319+  CK_ULONG ulOtherInfoLen;
15320+  CK_BYTE_PTR pOtherInfo;
15321+  CK_ULONG ulPublicDataLen;
15322+  CK_BYTE_PTR pPublicData;
15323+} CK_X9_42_DH1_DERIVE_PARAMS;
15324+
15325+typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
15326+
15327+/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11.
15328+ * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
15329+ * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
15330+ * mechanisms, where each party contributes two key pairs */
15331+typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
15332+  CK_X9_42_DH_KDF_TYPE kdf;
15333+  CK_ULONG ulOtherInfoLen;
15334+  CK_BYTE_PTR pOtherInfo;
15335+  CK_ULONG ulPublicDataLen;
15336+  CK_BYTE_PTR pPublicData;
15337+  CK_ULONG ulPrivateDataLen;
15338+  CK_OBJECT_HANDLE hPrivateData;
15339+  CK_ULONG ulPublicDataLen2;
15340+  CK_BYTE_PTR pPublicData2;
15341+} CK_X9_42_DH2_DERIVE_PARAMS;
15342+
15343+typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
15344+
15345+typedef struct CK_X9_42_MQV_DERIVE_PARAMS {
15346+  CK_X9_42_DH_KDF_TYPE kdf;
15347+  CK_ULONG ulOtherInfoLen;
15348+  CK_BYTE_PTR pOtherInfo;
15349+  CK_ULONG ulPublicDataLen;
15350+  CK_BYTE_PTR pPublicData;
15351+  CK_ULONG ulPrivateDataLen;
15352+  CK_OBJECT_HANDLE hPrivateData;
15353+  CK_ULONG ulPublicDataLen2;
15354+  CK_BYTE_PTR pPublicData2;
15355+  CK_OBJECT_HANDLE publicKey;
15356+} CK_X9_42_MQV_DERIVE_PARAMS;
15357+
15358+typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
15359+
15360+/* CK_KEA_DERIVE_PARAMS provides the parameters to the
15361+ * CKM_KEA_DERIVE mechanism */
15362+/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
15363+typedef struct CK_KEA_DERIVE_PARAMS {
15364+  CK_BBOOL      isSender;
15365+  CK_ULONG      ulRandomLen;
15366+  CK_BYTE_PTR   pRandomA;
15367+  CK_BYTE_PTR   pRandomB;
15368+  CK_ULONG      ulPublicDataLen;
15369+  CK_BYTE_PTR   pPublicData;
15370+} CK_KEA_DERIVE_PARAMS;
15371+
15372+typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
15373+
15374+
15375+/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
15376+ * CKM_RC2_MAC mechanisms.  An instance of CK_RC2_PARAMS just
15377+ * holds the effective keysize */
15378+typedef CK_ULONG          CK_RC2_PARAMS;
15379+
15380+typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
15381+
15382+
15383+/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
15384+ * mechanism */
15385+typedef struct CK_RC2_CBC_PARAMS {
15386+  /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
15387+   * v2.0 */
15388+  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
15389+
15390+  CK_BYTE       iv[8];            /* IV for CBC mode */
15391+} CK_RC2_CBC_PARAMS;
15392+
15393+typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
15394+
15395+
15396+/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
15397+ * CKM_RC2_MAC_GENERAL mechanism */
15398+/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
15399+typedef struct CK_RC2_MAC_GENERAL_PARAMS {
15400+  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
15401+  CK_ULONG      ulMacLength;      /* Length of MAC in bytes */
15402+} CK_RC2_MAC_GENERAL_PARAMS;
15403+
15404+typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
15405+  CK_RC2_MAC_GENERAL_PARAMS_PTR;
15406+
15407+
15408+/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
15409+ * CKM_RC5_MAC mechanisms */
15410+/* CK_RC5_PARAMS is new for v2.0 */
15411+typedef struct CK_RC5_PARAMS {
15412+  CK_ULONG      ulWordsize;  /* wordsize in bits */
15413+  CK_ULONG      ulRounds;    /* number of rounds */
15414+} CK_RC5_PARAMS;
15415+
15416+typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
15417+
15418+
15419+/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
15420+ * mechanism */
15421+/* CK_RC5_CBC_PARAMS is new for v2.0 */
15422+typedef struct CK_RC5_CBC_PARAMS {
15423+  CK_ULONG      ulWordsize;  /* wordsize in bits */
15424+  CK_ULONG      ulRounds;    /* number of rounds */
15425+  CK_BYTE_PTR   pIv;         /* pointer to IV */
15426+  CK_ULONG      ulIvLen;     /* length of IV in bytes */
15427+} CK_RC5_CBC_PARAMS;
15428+
15429+typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
15430+
15431+
15432+/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
15433+ * CKM_RC5_MAC_GENERAL mechanism */
15434+/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
15435+typedef struct CK_RC5_MAC_GENERAL_PARAMS {
15436+  CK_ULONG      ulWordsize;   /* wordsize in bits */
15437+  CK_ULONG      ulRounds;     /* number of rounds */
15438+  CK_ULONG      ulMacLength;  /* Length of MAC in bytes */
15439+} CK_RC5_MAC_GENERAL_PARAMS;
15440+
15441+typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
15442+  CK_RC5_MAC_GENERAL_PARAMS_PTR;
15443+
15444+
15445+/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
15446+ * ciphers' MAC_GENERAL mechanisms.  Its value is the length of
15447+ * the MAC */
15448+/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
15449+typedef CK_ULONG          CK_MAC_GENERAL_PARAMS;
15450+
15451+typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
15452+
15453+/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
15454+typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
15455+  CK_BYTE      iv[8];
15456+  CK_BYTE_PTR  pData;
15457+  CK_ULONG     length;
15458+} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
15459+
15460+typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
15461+
15462+typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
15463+  CK_BYTE      iv[16];
15464+  CK_BYTE_PTR  pData;
15465+  CK_ULONG     length;
15466+} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
15467+
15468+typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
15469+
15470+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
15471+ * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
15472+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
15473+typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
15474+  CK_ULONG      ulPasswordLen;
15475+  CK_BYTE_PTR   pPassword;
15476+  CK_ULONG      ulPublicDataLen;
15477+  CK_BYTE_PTR   pPublicData;
15478+  CK_ULONG      ulPAndGLen;
15479+  CK_ULONG      ulQLen;
15480+  CK_ULONG      ulRandomLen;
15481+  CK_BYTE_PTR   pRandomA;
15482+  CK_BYTE_PTR   pPrimeP;
15483+  CK_BYTE_PTR   pBaseG;
15484+  CK_BYTE_PTR   pSubprimeQ;
15485+} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
15486+
15487+typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
15488+  CK_SKIPJACK_PRIVATE_WRAP_PTR;
15489+
15490+
15491+/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
15492+ * CKM_SKIPJACK_RELAYX mechanism */
15493+/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
15494+typedef struct CK_SKIPJACK_RELAYX_PARAMS {
15495+  CK_ULONG      ulOldWrappedXLen;
15496+  CK_BYTE_PTR   pOldWrappedX;
15497+  CK_ULONG      ulOldPasswordLen;
15498+  CK_BYTE_PTR   pOldPassword;
15499+  CK_ULONG      ulOldPublicDataLen;
15500+  CK_BYTE_PTR   pOldPublicData;
15501+  CK_ULONG      ulOldRandomLen;
15502+  CK_BYTE_PTR   pOldRandomA;
15503+  CK_ULONG      ulNewPasswordLen;
15504+  CK_BYTE_PTR   pNewPassword;
15505+  CK_ULONG      ulNewPublicDataLen;
15506+  CK_BYTE_PTR   pNewPublicData;
15507+  CK_ULONG      ulNewRandomLen;
15508+  CK_BYTE_PTR   pNewRandomA;
15509+} CK_SKIPJACK_RELAYX_PARAMS;
15510+
15511+typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
15512+  CK_SKIPJACK_RELAYX_PARAMS_PTR;
15513+
15514+
15515+typedef struct CK_PBE_PARAMS {
15516+  CK_BYTE_PTR      pInitVector;
15517+  CK_UTF8CHAR_PTR  pPassword;
15518+  CK_ULONG         ulPasswordLen;
15519+  CK_BYTE_PTR      pSalt;
15520+  CK_ULONG         ulSaltLen;
15521+  CK_ULONG         ulIteration;
15522+} CK_PBE_PARAMS;
15523+
15524+typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
15525+
15526+
15527+/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
15528+ * CKM_KEY_WRAP_SET_OAEP mechanism */
15529+/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
15530+typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
15531+  CK_BYTE       bBC;     /* block contents byte */
15532+  CK_BYTE_PTR   pX;      /* extra data */
15533+  CK_ULONG      ulXLen;  /* length of extra data in bytes */
15534+} CK_KEY_WRAP_SET_OAEP_PARAMS;
15535+
15536+typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
15537+  CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
15538+
15539+
15540+typedef struct CK_SSL3_RANDOM_DATA {
15541+  CK_BYTE_PTR  pClientRandom;
15542+  CK_ULONG     ulClientRandomLen;
15543+  CK_BYTE_PTR  pServerRandom;
15544+  CK_ULONG     ulServerRandomLen;
15545+} CK_SSL3_RANDOM_DATA;
15546+
15547+
15548+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
15549+  CK_SSL3_RANDOM_DATA RandomInfo;
15550+  CK_VERSION_PTR pVersion;
15551+} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
15552+
15553+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
15554+  CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
15555+
15556+
15557+typedef struct CK_SSL3_KEY_MAT_OUT {
15558+  CK_OBJECT_HANDLE hClientMacSecret;
15559+  CK_OBJECT_HANDLE hServerMacSecret;
15560+  CK_OBJECT_HANDLE hClientKey;
15561+  CK_OBJECT_HANDLE hServerKey;
15562+  CK_BYTE_PTR      pIVClient;
15563+  CK_BYTE_PTR      pIVServer;
15564+} CK_SSL3_KEY_MAT_OUT;
15565+
15566+typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
15567+
15568+
15569+typedef struct CK_SSL3_KEY_MAT_PARAMS {
15570+  CK_ULONG                ulMacSizeInBits;
15571+  CK_ULONG                ulKeySizeInBits;
15572+  CK_ULONG                ulIVSizeInBits;
15573+  CK_BBOOL                bIsExport;
15574+  CK_SSL3_RANDOM_DATA     RandomInfo;
15575+  CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
15576+} CK_SSL3_KEY_MAT_PARAMS;
15577+
15578+typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
15579+
15580+/* CK_TLS_PRF_PARAMS is new for version 2.20 */
15581+typedef struct CK_TLS_PRF_PARAMS {
15582+  CK_BYTE_PTR  pSeed;
15583+  CK_ULONG     ulSeedLen;
15584+  CK_BYTE_PTR  pLabel;
15585+  CK_ULONG     ulLabelLen;
15586+  CK_BYTE_PTR  pOutput;
15587+  CK_ULONG_PTR pulOutputLen;
15588+} CK_TLS_PRF_PARAMS;
15589+
15590+typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
15591+
15592+/* WTLS is new for version 2.20 */
15593+typedef struct CK_WTLS_RANDOM_DATA {
15594+  CK_BYTE_PTR pClientRandom;
15595+  CK_ULONG    ulClientRandomLen;
15596+  CK_BYTE_PTR pServerRandom;
15597+  CK_ULONG    ulServerRandomLen;
15598+} CK_WTLS_RANDOM_DATA;
15599+
15600+typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
15601+
15602+typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
15603+  CK_MECHANISM_TYPE   DigestMechanism;
15604+  CK_WTLS_RANDOM_DATA RandomInfo;
15605+  CK_BYTE_PTR         pVersion;
15606+} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
15607+
15608+typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
15609+  CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
15610+
15611+typedef struct CK_WTLS_PRF_PARAMS {
15612+  CK_MECHANISM_TYPE DigestMechanism;
15613+  CK_BYTE_PTR       pSeed;
15614+  CK_ULONG          ulSeedLen;
15615+  CK_BYTE_PTR       pLabel;
15616+  CK_ULONG          ulLabelLen;
15617+  CK_BYTE_PTR       pOutput;
15618+  CK_ULONG_PTR      pulOutputLen;
15619+} CK_WTLS_PRF_PARAMS;
15620+
15621+typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
15622+
15623+typedef struct CK_WTLS_KEY_MAT_OUT {
15624+  CK_OBJECT_HANDLE hMacSecret;
15625+  CK_OBJECT_HANDLE hKey;
15626+  CK_BYTE_PTR      pIV;
15627+} CK_WTLS_KEY_MAT_OUT;
15628+
15629+typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
15630+
15631+typedef struct CK_WTLS_KEY_MAT_PARAMS {
15632+  CK_MECHANISM_TYPE       DigestMechanism;
15633+  CK_ULONG                ulMacSizeInBits;
15634+  CK_ULONG                ulKeySizeInBits;
15635+  CK_ULONG                ulIVSizeInBits;
15636+  CK_ULONG                ulSequenceNumber;
15637+  CK_BBOOL                bIsExport;
15638+  CK_WTLS_RANDOM_DATA     RandomInfo;
15639+  CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
15640+} CK_WTLS_KEY_MAT_PARAMS;
15641+
15642+typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
15643+
15644+/* CMS is new for version 2.20 */
15645+typedef struct CK_CMS_SIG_PARAMS {
15646+  CK_OBJECT_HANDLE      certificateHandle;
15647+  CK_MECHANISM_PTR      pSigningMechanism;
15648+  CK_MECHANISM_PTR      pDigestMechanism;
15649+  CK_UTF8CHAR_PTR       pContentType;
15650+  CK_BYTE_PTR           pRequestedAttributes;
15651+  CK_ULONG              ulRequestedAttributesLen;
15652+  CK_BYTE_PTR           pRequiredAttributes;
15653+  CK_ULONG              ulRequiredAttributesLen;
15654+} CK_CMS_SIG_PARAMS;
15655+
15656+typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
15657+
15658+typedef struct CK_KEY_DERIVATION_STRING_DATA {
15659+  CK_BYTE_PTR pData;
15660+  CK_ULONG    ulLen;
15661+} CK_KEY_DERIVATION_STRING_DATA;
15662+
15663+typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
15664+  CK_KEY_DERIVATION_STRING_DATA_PTR;
15665+
15666+
15667+/* The CK_EXTRACT_PARAMS is used for the
15668+ * CKM_EXTRACT_KEY_FROM_KEY mechanism.  It specifies which bit
15669+ * of the base key should be used as the first bit of the
15670+ * derived key */
15671+/* CK_EXTRACT_PARAMS is new for v2.0 */
15672+typedef CK_ULONG CK_EXTRACT_PARAMS;
15673+
15674+typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
15675+
15676+/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
15677+ * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
15678+ * indicate the Pseudo-Random Function (PRF) used to generate
15679+ * key bits using PKCS #5 PBKDF2. */
15680+typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
15681+
15682+typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
15683+
15684+/* The following PRFs are defined in PKCS #5 v2.0. */
15685+#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
15686+
15687+
15688+/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
15689+ * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
15690+ * source of the salt value when deriving a key using PKCS #5
15691+ * PBKDF2. */
15692+typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
15693+
15694+typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
15695+
15696+/* The following salt value sources are defined in PKCS #5 v2.0. */
15697+#define CKZ_SALT_SPECIFIED        0x00000001
15698+
15699+/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
15700+ * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
15701+ * parameters to the CKM_PKCS5_PBKD2 mechanism. */
15702+typedef struct CK_PKCS5_PBKD2_PARAMS {
15703+        CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE           saltSource;
15704+        CK_VOID_PTR                                pSaltSourceData;
15705+        CK_ULONG                                   ulSaltSourceDataLen;
15706+        CK_ULONG                                   iterations;
15707+        CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
15708+        CK_VOID_PTR                                pPrfData;
15709+        CK_ULONG                                   ulPrfDataLen;
15710+        CK_UTF8CHAR_PTR                            pPassword;
15711+        CK_ULONG_PTR                               ulPasswordLen;
15712+} CK_PKCS5_PBKD2_PARAMS;
15713+
15714+typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
15715+
15716+/* All CK_OTP structs are new for PKCS #11 v2.20 amendment 3 */
15717+
15718+typedef CK_ULONG CK_OTP_PARAM_TYPE;
15719+typedef CK_OTP_PARAM_TYPE CK_PARAM_TYPE; /* B/w compatibility */
15720+
15721+typedef struct CK_OTP_PARAM {
15722+    CK_OTP_PARAM_TYPE type;
15723+    CK_VOID_PTR pValue;
15724+    CK_ULONG ulValueLen;
15725+} CK_OTP_PARAM;
15726+
15727+typedef CK_OTP_PARAM CK_PTR CK_OTP_PARAM_PTR;
15728+
15729+typedef struct CK_OTP_PARAMS {
15730+    CK_OTP_PARAM_PTR pParams;
15731+    CK_ULONG ulCount;
15732+} CK_OTP_PARAMS;
15733+
15734+typedef CK_OTP_PARAMS CK_PTR CK_OTP_PARAMS_PTR;
15735+
15736+typedef struct CK_OTP_SIGNATURE_INFO {
15737+    CK_OTP_PARAM_PTR pParams;
15738+    CK_ULONG ulCount;
15739+} CK_OTP_SIGNATURE_INFO;
15740+
15741+typedef CK_OTP_SIGNATURE_INFO CK_PTR CK_OTP_SIGNATURE_INFO_PTR;
15742+
15743+/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */
15744+#define CK_OTP_VALUE          0
15745+#define CK_OTP_PIN            1
15746+#define CK_OTP_CHALLENGE      2
15747+#define CK_OTP_TIME           3
15748+#define CK_OTP_COUNTER        4
15749+#define CK_OTP_FLAGS          5
15750+#define CK_OTP_OUTPUT_LENGTH  6
15751+#define CK_OTP_OUTPUT_FORMAT  7
15752+
15753+/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */
15754+#define CKF_NEXT_OTP          0x00000001
15755+#define CKF_EXCLUDE_TIME      0x00000002
15756+#define CKF_EXCLUDE_COUNTER   0x00000004
15757+#define CKF_EXCLUDE_CHALLENGE 0x00000008
15758+#define CKF_EXCLUDE_PIN       0x00000010
15759+#define CKF_USER_FRIENDLY_OTP 0x00000020
15760+
15761+/* CK_KIP_PARAMS is new for PKCS #11 v2.20 amendment 2 */
15762+typedef struct CK_KIP_PARAMS {
15763+    CK_MECHANISM_PTR  pMechanism;
15764+    CK_OBJECT_HANDLE  hKey;
15765+    CK_BYTE_PTR       pSeed;
15766+    CK_ULONG          ulSeedLen;
15767+} CK_KIP_PARAMS;
15768+
15769+typedef CK_KIP_PARAMS CK_PTR CK_KIP_PARAMS_PTR;
15770+
15771+/* CK_AES_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
15772+typedef struct CK_AES_CTR_PARAMS {
15773+    CK_ULONG ulCounterBits;
15774+    CK_BYTE cb[16];
15775+} CK_AES_CTR_PARAMS;
15776+
15777+typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR;
15778+
15779+/* CK_CAMELLIA_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
15780+typedef struct CK_CAMELLIA_CTR_PARAMS {
15781+    CK_ULONG ulCounterBits;
15782+    CK_BYTE cb[16];
15783+} CK_CAMELLIA_CTR_PARAMS;
15784+
15785+typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR;
15786+
15787+/* CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
15788+typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS {
15789+    CK_BYTE      iv[16];
15790+    CK_BYTE_PTR  pData;
15791+    CK_ULONG     length;
15792+} CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS;
15793+
15794+typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
15795+
15796+/* CK_ARIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
15797+typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS {
15798+    CK_BYTE      iv[16];
15799+    CK_BYTE_PTR  pData;
15800+    CK_ULONG     length;
15801+} CK_ARIA_CBC_ENCRYPT_DATA_PARAMS;
15802+
15803+typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
15804+
15805+#endif
15806Index: openssl/util/libeay.num
15807diff -u openssl/util/libeay.num:1.7.6.1.4.1.2.1 openssl/util/libeay.num:1.7.2.2
15808--- openssl/util/libeay.num:1.7.6.1.4.1.2.1	Thu Jul  3 12:12:37 2014
15809+++ openssl/util/libeay.num	Thu Jul  3 12:32:04 2014
15810@@ -3730,3 +3730,5 @@
15811 pqueue_size                             4114	EXIST::FUNCTION:
15812 OPENSSL_uni2asc                         4115	EXIST:NETWARE:FUNCTION:
15813 OPENSSL_asc2uni                         4116	EXIST:NETWARE:FUNCTION:
15814+ENGINE_load_pk11ca                      4117	EXIST::FUNCTION:HW_PKCS11CA,ENGINE
15815+ENGINE_load_pk11so                      4117	EXIST::FUNCTION:HW_PKCS11SO,ENGINE
15816Index: openssl/util/mk1mf.pl
15817diff -u openssl/util/mk1mf.pl:1.8.6.1 openssl/util/mk1mf.pl:1.8
15818--- openssl/util/mk1mf.pl:1.8.6.1	Sun Jan 15 15:45:40 2012
15819+++ openssl/util/mk1mf.pl	Mon Jun 13 14:25:25 2011
15820@@ -87,6 +87,8 @@
15821 	no-ecdh					- No ECDH
15822 	no-engine				- No engine
15823 	no-hw					- No hw
15824+	no-hw-pkcs11ca				- No hw PKCS#11 CA flavor
15825+	no-hw-pkcs11so				- No hw PKCS#11 SO flavor
15826 	nasm 					- Use NASM for x86 asm
15827 	nw-nasm					- Use NASM x86 asm for NetWare
15828 	nw-mwasm				- Use Metrowerks x86 asm for NetWare
15829@@ -242,6 +244,8 @@
15830 $cflags.=" -DOPENSSL_NO_ECDH" if $no_ecdh;
15831 $cflags.=" -DOPENSSL_NO_ENGINE"   if $no_engine;
15832 $cflags.=" -DOPENSSL_NO_HW"   if $no_hw;
15833+$cflags.=" -DOPENSSL_NO_HW_PKCS11CA"   if $no_hw_pkcs11ca;
15834+$cflags.=" -DOPENSSL_NO_HW_PKCS11SO"   if $no_hw_pkcs11so;
15835 $cflags.=" -DOPENSSL_FIPS"    if $fips;
15836 $cflags.= " -DZLIB" if $zlib_opt;
15837 $cflags.= " -DZLIB_SHARED" if $zlib_opt == 2;
15838@@ -316,6 +320,9 @@
15839 		$dir=$val;
15840 		}
15841
15842+	if ($key eq "PK11_LIB_LOCATION")
15843+		{ $cflags .= " -D$key=\\\"$val\\\"" if $val ne "";}
15844+
15845 	if ($key eq "KRB5_INCLUDES")
15846 		{ $cflags .= " $val";}
15847
15848@@ -1301,6 +1308,8 @@
15849 		"no-ecdh" => \$no_ecdh,
15850 		"no-engine" => \$no_engine,
15851 		"no-hw" => \$no_hw,
15852+		"no-hw-pkcs11ca" => \$no_hw_pkcs11ca,
15853+		"no-hw-pkcs11so" => \$no_hw_pkcs11so,
15854 		"just-ssl" =>
15855 			[\$no_rc2, \$no_idea, \$no_des, \$no_bf, \$no_cast,
15856 			  \$no_md2, \$no_sha, \$no_mdc2, \$no_dsa, \$no_dh,
15857Index: openssl/util/mkdef.pl
15858diff -u openssl/util/mkdef.pl:1.6.6.1 openssl/util/mkdef.pl:1.6
15859--- openssl/util/mkdef.pl:1.6.6.1	Sun Jan 15 15:45:40 2012
15860+++ openssl/util/mkdef.pl	Mon Jun 13 14:25:25 2011
15861@@ -93,7 +93,7 @@
15862 			 # External "algorithms"
15863 			 "FP_API", "STDIO", "SOCK", "KRB5", "DGRAM",
15864 			 # Engines
15865-			 "STATIC_ENGINE", "ENGINE", "HW", "GMP",
15866+			 "STATIC_ENGINE", "ENGINE", "HW", "GMP", "HW_PKCS11CA", "HW_PKCS11SO",
15867 			 # RFC3779 support
15868 			 "RFC3779",
15869 			 # TLS extension support
15870@@ -122,6 +122,7 @@
15871 my $no_md2; my $no_md4; my $no_md5; my $no_sha; my $no_ripemd; my $no_mdc2;
15872 my $no_rsa; my $no_dsa; my $no_dh; my $no_hmac=0; my $no_aes; my $no_krb5;
15873 my $no_ec; my $no_ecdsa; my $no_ecdh; my $no_engine; my $no_hw; my $no_camellia;
15874+my $no_pkcs11ca; my $no_pkcs11so;
15875 my $no_seed;
15876 my $no_fp_api; my $no_static_engine; my $no_gmp; my $no_deprecated;
15877 my $no_rfc3779; my $no_tlsext; my $no_cms; my $no_capieng; my $no_jpake;
15878@@ -214,6 +215,8 @@
15879 	elsif (/^no-cms$/)	{ $no_cms=1; }
15880 	elsif (/^no-capieng$/)	{ $no_capieng=1; }
15881 	elsif (/^no-jpake$/)	{ $no_jpake=1; }
15882+	elsif (/^no-hw-pkcs11ca$/) { $no_pkcs11ca=1; }
15883+	elsif (/^no-hw-pkcs11so$/) { $no_pkcs11so=1; }
15884 	}
15885
15886
15887@@ -1155,6 +1158,8 @@
15888 			if ($keyword eq "KRB5" && $no_krb5) { return 0; }
15889 			if ($keyword eq "ENGINE" && $no_engine) { return 0; }
15890 			if ($keyword eq "HW" && $no_hw) { return 0; }
15891+			if ($keyword eq "HW_PKCS11CA" && $no_pkcs11ca) { return 0; }
15892+			if ($keyword eq "HW_PKCS11SO" && $no_pkcs11so) { return 0; }
15893 			if ($keyword eq "FP_API" && $no_fp_api) { return 0; }
15894 			if ($keyword eq "STATIC_ENGINE" && $no_static_engine) { return 0; }
15895 			if ($keyword eq "GMP" && $no_gmp) { return 0; }
15896Index: openssl/util/pl/VC-32.pl
15897diff -u openssl/util/pl/VC-32.pl:1.6.6.1.2.1.4.1 openssl/util/pl/VC-32.pl:1.6.2.2
15898--- openssl/util/pl/VC-32.pl:1.6.6.1.2.1.4.1	Thu Jul  3 12:12:38 2014
15899+++ openssl/util/pl/VC-32.pl	Thu Jul  3 12:32:04 2014
15900@@ -52,7 +52,7 @@
15901     my $f = $shlib || $fips ?' /MD':' /MT';
15902     $lib_cflag='/Zl' if (!$shlib);	# remove /DEFAULTLIBs from static lib
15903     $opt_cflags=$f.' /Ox';
15904-    $dbg_cflags=$f.'d /Od -DDEBUG -D_DEBUG';
15905+    $dbg_cflags=$f.'d /Od /Zi -DDEBUG -D_DEBUG';
15906     $lflags="/nologo /subsystem:console /opt:ref";
15907     }
15908 elsif ($FLAVOR =~ /CE/)
15909