etc/services - sync with NetBSD-8
[minix.git] / external / bsd / bind / dist / bin / pkcs11 / openssl-1.0.0o-patch
blob8599af5e4ea4eeb749e3586aa7b6f4219ca718c8
1 Index: openssl/Configure
2 diff -u openssl/Configure:1.9.2.1.2.1.4.1.2.1 openssl/Configure:1.11.2.2
3 --- openssl/Configure:1.9.2.1.2.1.4.1.2.1       Tue Jan  7 09:25:41 2014
4 +++ openssl/Configure   Tue Jan  7 09:28:47 2014
5 @@ -10,7 +10,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] [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] [no-asm] [no-dso] [no-krb5] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
12  # Options:
13  #
14 @@ -23,6 +23,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)
21 +# --pk11-flavor either crypto-accelerator or sign-only
22 +#               (No default)
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 @@ -344,7 +350,7 @@
28  "linux-armv4", "gcc:-DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${armv4_asm}: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_asm}:a.out",
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 @@ -352,7 +358,7 @@
37  "linux-ia64",  "gcc:-DL_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_UNROLL DES_INT:${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 DES_INT:${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 DES_RISC1 DES_INT:${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}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
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}:elf:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
42  "linux-s390x", "gcc:-m64 -DB_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL:${s390x_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
43  #### SPARC Linux setups
44  # Ray Miller <ray.miller@computing-services.oxford.ac.uk> has patiently
45 @@ -623,6 +629,10 @@
46  my $idx_arflags = $idx++;
47  my $idx_multilib = $idx++;
49 +# PKCS#11 engine patch
50 +my $pk11_libname="";
51 +my $pk11_flavor="";
53  my $prefix="";
54  my $libdir="";
55  my $openssldir="";
56 @@ -825,6 +835,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 @@ -962,6 +980,22 @@
72         exit 0;
73  }
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 +        }
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 +       }
91  if ($target =~ m/^CygWin32(-.*)$/) {
92         $target = "Cygwin".$1;
93  }
94 @@ -1039,6 +1073,25 @@
95         $exp_cflags .= " -DOPENSSL_EXPERIMENTAL_$ALGO";
96         }
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";
117  my $IsMK1MF=scalar grep /^$target$/,@MK1MF_Builds;
119  $exe_ext=".exe" if ($target eq "Cygwin" || $target eq "DJGPP" || $target =~ /^mingw/);
120 @@ -1126,6 +1179,8 @@
121  if ($flags ne "")      { $cflags="$flags$cflags"; }
122  else                   { $no_user_cflags=1;       }
124 +$cflags="-DPK11_LIB_LOCATION=\"$pk11_libname\" $cflags";
126  # Kerberos settings.  The flavor must be provided from outside, either through
127  # the script "config" or manually.
128  if (!$no_krb5)
129 @@ -1495,6 +1550,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/;
137 Index: openssl/Makefile.org
138 diff -u openssl/Makefile.org:1.5.2.1.2.1 openssl/Makefile.org:1.6
139 --- openssl/Makefile.org:1.5.2.1.2.1    Tue Jun 19 14:46:04 2012
140 +++ openssl/Makefile.org        Tue Jun 19 14:49:21 2012
141 @@ -26,6 +26,9 @@
142  INSTALL_PREFIX=
143  INSTALLTOP=/usr/local/ssl
145 +# You must set this through --pk11-libname configure option.
146 +PK11_LIB_LOCATION=
148  # Do not edit this manually. Use Configure --openssldir=DIR do change this!
149  OPENSSLDIR=/usr/local/ssl
151 Index: openssl/README.pkcs11
152 diff -u /dev/null openssl/README.pkcs11:1.7.4.1
153 --- /dev/null   Fri Jan  2 14:26:16 2015
154 +++ openssl/README.pkcs11       Fri Oct  4 14:33:56 2013
155 @@ -0,0 +1,266 @@
156 +ISC modified
157 +============
159 +The previous key naming scheme was kept for backward compatibility.
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).
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.
172 +Note it is mandatory to set a pk11-flavor (and only one) in
173 +config/Configure.
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).
180 +PKCS#11 engine support for OpenSSL 0.9.8l
181 +=========================================
183 +[Nov 19, 2009]
185 +Contents:
187 +Overview
188 +Revisions of the patch for 0.9.8 branch
189 +FAQs
190 +Feedback
192 +Overview
193 +========
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.
201 +Patch can be applied like this:
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
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.
215 +According to the PKCS#11 providers installed on your machine, it can support
216 +following mechanisms:
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
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).
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:
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.
239 +Taking openCryptoki project on Linux AMD64 box as an example, you would run
240 +configure script like this:
242 +       ./config --pk11-libname=/usr/lib64/pkcs11/PKCS11_API.so
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.
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.
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.
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).
265 +Revisions of the patch for 0.9.8 branch
266 +=======================================
268 +2009-11-19
269 +- adjusted for OpenSSL version 0.9.8l
271 +- bugs and RFEs:
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
278 +2009-03-11
279 +- adjusted for OpenSSL version 0.9.8j 
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.
284 +- fixed bugs:
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
290 +2008-12-02
291 +- fixed bugs and RFEs (most of the work done by Vladimir Kotal)
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
305 +2008-08-01
306 +- fixed bug
308 +       6731839 OpenSSL PKCS#11 engine no longer uses n2cp for symmetric ciphers
309 +               and digests
311 +- Solaris specific code for slot selection made automatic
313 +2008-07-29
314 +- update the patch to OpenSSL 0.9.8h version
315 +- pkcs11t.h updated to the latest version:
317 +       6545665 make CKM_AES_CTR available to non-kernel users
319 +- fixed bugs in the engine code:
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()
354 +- new features and enhancements:
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
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"
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"
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
374 +2007-05-25
375 +- 6558630 race in OpenSSL pkcs11 engine when using symetric block ciphers
377 +2007-05-19
378 +- initial patch for 0.9.8e using latest OpenSolaris code
380 +FAQs
381 +====
383 +(1) my build failed on Linux distro with this error:
385 +../libcrypto.a(hw_pk11.o): In function `pk11_library_init':
386 +hw_pk11.c:(.text+0x20f5): undefined reference to `pthread_atfork'
388 +Answer:
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:
395 +Configured for linux-elf.
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:
403 +....-O3 -fomit-frame-pointer -Wall::-D_REENTRANT -pthread::-ldl:.....
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.
408 +Answer:
410 +       Sorry, pthread_atfork() is not implemented in the current pthread-win32
411 +       (as of Nov 2009). You can not use the patch there.
414 +Feedback
415 +========
417 +Please send feedback to security-discuss@opensolaris.org. The patch was
418 +created by Jan.Pechanec@Sun.COM from code available in OpenSolaris.
420 +Latest version should be always available on http://blogs.sun.com/janp.
422 Index: openssl/crypto/opensslconf.h
423 diff -u openssl/crypto/opensslconf.h:1.6.2.1 openssl/crypto/opensslconf.h:1.6
424 --- openssl/crypto/opensslconf.h:1.6.2.1        Sun Jan 15 16:09:43 2012
425 +++ openssl/crypto/opensslconf.h        Mon Jun 13 17:13:28 2011
426 @@ -29,6 +29,9 @@
428  #endif /* OPENSSL_DOING_MAKEDEPEND */
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 @@ -61,6 +64,8 @@
437  # endif
438  #endif
440 +#define OPENSSL_CPUID_OBJ
442  /* crypto/opensslconf.h.in */
444  /* Generate 80386 code? */
445 @@ -107,7 +112,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
454 @@ -115,7 +120,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
463 @@ -126,9 +131,9 @@
464  /* Should we define BN_DIV2W here? */
466  /* Only one for the following should be defined */
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  #endif
474  #if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
475 @@ -140,7 +145,7 @@
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 */
483  #if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
484 @@ -170,7 +175,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
492  /* These default values were supplied by
493 Index: openssl/crypto/bio/bss_file.c
494 diff -u openssl/crypto/bio/bss_file.c:1.6.2.1 openssl/crypto/bio/bss_file.c:1.6
495 --- openssl/crypto/bio/bss_file.c:1.6.2.1       Sun Jan 15 16:09:44 2012
496 +++ openssl/crypto/bio/bss_file.c       Mon Jun 13 17:13:31 2011
497 @@ -168,7 +168,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);
506 Index: openssl/crypto/engine/Makefile
507 diff -u openssl/crypto/engine/Makefile:1.8.2.1 openssl/crypto/engine/Makefile:1.8
508 --- openssl/crypto/engine/Makefile:1.8.2.1      Sun Jan 15 16:09:46 2012
509 +++ openssl/crypto/engine/Makefile      Tue Jun 14 21:51:32 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 tb_pkmeth.c tb_asnmth.c \
514 -       eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c
515 +       eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.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 tb_pkmeth.o tb_asnmth.o \
521 -       eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o
522 +       eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o \
523 +       hw_pk11.o hw_pk11_pub.o hw_pk11so.o hw_pk11so_pub.o
525  SRC= $(LIBSRC)
527 @@ -264,6 +266,83 @@
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: ../../e_os.h ../../include/openssl/aes.h
532 +hw_pk11.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
533 +hw_pk11.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
534 +hw_pk11.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
535 +hw_pk11.o: ../../include/openssl/dsa.h ../../include/openssl/dso.h
536 +hw_pk11.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
537 +hw_pk11.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
538 +hw_pk11.o: ../../include/openssl/engine.h ../../include/openssl/err.h
539 +hw_pk11.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
540 +hw_pk11.o: ../../include/openssl/md5.h ../../include/openssl/obj_mac.h
541 +hw_pk11.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
542 +hw_pk11.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
543 +hw_pk11.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
544 +hw_pk11.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
545 +hw_pk11.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
546 +hw_pk11.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
547 +hw_pk11.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
548 +hw_pk11.o: ../../include/openssl/x509_vfy.h ../cryptlib.h cryptoki.h hw_pk11.c
549 +hw_pk11.o: hw_pk11_err.c hw_pk11_err.h hw_pk11ca.h pkcs11.h pkcs11f.h pkcs11t.h
550 +hw_pk11_pub.o: ../../e_os.h ../../include/openssl/asn1.h
551 +hw_pk11_pub.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
552 +hw_pk11_pub.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
553 +hw_pk11_pub.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
554 +hw_pk11_pub.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
555 +hw_pk11_pub.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
556 +hw_pk11_pub.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
557 +hw_pk11_pub.o: ../../include/openssl/err.h ../../include/openssl/evp.h
558 +hw_pk11_pub.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
559 +hw_pk11_pub.o: ../../include/openssl/objects.h
560 +hw_pk11_pub.o: ../../include/openssl/opensslconf.h
561 +hw_pk11_pub.o: ../../include/openssl/opensslv.h
562 +hw_pk11_pub.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
563 +hw_pk11_pub.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
564 +hw_pk11_pub.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
565 +hw_pk11_pub.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
566 +hw_pk11_pub.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
567 +hw_pk11_pub.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
568 +hw_pk11_pub.o: ../cryptlib.h cryptoki.h hw_pk11_err.h hw_pk11_pub.c hw_pk11ca.h
569 +hw_pk11_pub.o: pkcs11.h pkcs11f.h pkcs11t.h
570 +hw_pk11so.o: ../../e_os.h ../../include/openssl/asn1.h
571 +hw_pk11so.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
572 +hw_pk11so.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
573 +hw_pk11so.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
574 +hw_pk11so.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
575 +hw_pk11so.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
576 +hw_pk11so.o: ../../include/openssl/err.h ../../include/openssl/evp.h
577 +hw_pk11so.o: ../../include/openssl/lhash.h ../../include/openssl/md5.h
578 +hw_pk11so.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
579 +hw_pk11so.o: ../../include/openssl/opensslconf.h
580 +hw_pk11so.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
581 +hw_pk11so.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
582 +hw_pk11so.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
583 +hw_pk11so.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
584 +hw_pk11so.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
585 +hw_pk11so.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
586 +hw_pk11so.o: ../../include/openssl/x509_vfy.h ../cryptlib.h cryptoki.h
587 +hw_pk11so.o: hw_pk11_err.c hw_pk11_err.h hw_pk11so.c hw_pk11so.h pkcs11.h
588 +hw_pk11so.o: pkcs11f.h pkcs11t.h
589 +hw_pk11so_pub.o: ../../e_os.h ../../include/openssl/asn1.h
590 +hw_pk11so_pub.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
591 +hw_pk11so_pub.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
592 +hw_pk11so_pub.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
593 +hw_pk11so_pub.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
594 +hw_pk11so_pub.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
595 +hw_pk11so_pub.o: ../../include/openssl/err.h ../../include/openssl/evp.h
596 +hw_pk11so_pub.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
597 +hw_pk11so_pub.o: ../../include/openssl/objects.h
598 +hw_pk11so_pub.o: ../../include/openssl/opensslconf.h
599 +hw_pk11so_pub.o: ../../include/openssl/opensslv.h
600 +hw_pk11so_pub.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
601 +hw_pk11so_pub.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
602 +hw_pk11so_pub.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
603 +hw_pk11so_pub.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
604 +hw_pk11so_pub.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
605 +hw_pk11so_pub.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
606 +hw_pk11so_pub.o: ../cryptlib.h cryptoki.h hw_pk11_err.h hw_pk11so.h
607 +hw_pk11so_pub.o: hw_pk11so_pub.c pkcs11.h pkcs11f.h pkcs11t.h
608  tb_asnmth.o: ../../e_os.h ../../include/openssl/asn1.h
609  tb_asnmth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
610  tb_asnmth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
611 Index: openssl/crypto/engine/cryptoki.h
612 diff -u /dev/null openssl/crypto/engine/cryptoki.h:1.4
613 --- /dev/null   Fri Jan  2 14:26:16 2015
614 +++ openssl/crypto/engine/cryptoki.h    Thu Dec 18 00:14:12 2008
615 @@ -0,0 +1,103 @@
617 + * CDDL HEADER START
618 + *
619 + * The contents of this file are subject to the terms of the
620 + * Common Development and Distribution License, Version 1.0 only
621 + * (the "License").  You may not use this file except in compliance
622 + * with the License.
623 + *
624 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
625 + * or http://www.opensolaris.org/os/licensing.
626 + * See the License for the specific language governing permissions
627 + * and limitations under the License.
628 + *
629 + * When distributing Covered Code, include this CDDL HEADER in each
630 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
631 + * If applicable, add the following below this CDDL HEADER, with the
632 + * fields enclosed by brackets "[]" replaced with your own identifying
633 + * information: Portions Copyright [yyyy] [name of copyright owner]
634 + *
635 + * CDDL HEADER END
636 + */
638 + * Copyright 2003 Sun Microsystems, Inc.   All rights reserved.
639 + * Use is subject to license terms.
640 + */
642 +#ifndef        _CRYPTOKI_H
643 +#define        _CRYPTOKI_H
645 +/* ident       "@(#)cryptoki.h 1.2     05/06/08 SMI" */
647 +#ifdef __cplusplus
648 +extern "C" {
649 +#endif
651 +#ifndef        CK_PTR
652 +#define        CK_PTR *
653 +#endif
655 +#ifndef CK_DEFINE_FUNCTION
656 +#define        CK_DEFINE_FUNCTION(returnType, name) returnType name
657 +#endif
659 +#ifndef CK_DECLARE_FUNCTION
660 +#define        CK_DECLARE_FUNCTION(returnType, name) returnType name
661 +#endif
663 +#ifndef CK_DECLARE_FUNCTION_POINTER
664 +#define        CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
665 +#endif
667 +#ifndef CK_CALLBACK_FUNCTION
668 +#define        CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
669 +#endif
671 +#ifndef NULL_PTR
672 +#include <unistd.h>    /* For NULL */
673 +#define        NULL_PTR NULL
674 +#endif
677 + * pkcs11t.h defines TRUE and FALSE in a way that upsets lint
678 + */
679 +#ifndef        CK_DISABLE_TRUE_FALSE
680 +#define        CK_DISABLE_TRUE_FALSE
681 +#ifndef        TRUE
682 +#define        TRUE    1
683 +#endif /* TRUE */
684 +#ifndef        FALSE
685 +#define        FALSE   0
686 +#endif /* FALSE */
687 +#endif /* CK_DISABLE_TRUE_FALSE */
689 +#undef CK_PKCS11_FUNCTION_INFO
691 +#include "pkcs11.h"
693 +/* Solaris specific functions */
695 +#include <stdlib.h>
698 + * SUNW_C_GetMechSession will initialize the framework and do all
699 + * the necessary PKCS#11 calls to create a session capable of
700 + * providing operations on the requested mechanism
701 + */
702 +CK_RV SUNW_C_GetMechSession(CK_MECHANISM_TYPE mech,
703 +    CK_SESSION_HANDLE_PTR hSession);
706 + * SUNW_C_KeyToObject will create a secret key object for the given
707 + * mechanism from the rawkey data.
708 + */
709 +CK_RV SUNW_C_KeyToObject(CK_SESSION_HANDLE hSession,
710 +    CK_MECHANISM_TYPE mech, const void *rawkey, size_t rawkey_len,
711 +    CK_OBJECT_HANDLE_PTR obj);
714 +#ifdef __cplusplus
716 +#endif
718 +#endif /* _CRYPTOKI_H */
719 Index: openssl/crypto/engine/eng_all.c
720 diff -u openssl/crypto/engine/eng_all.c:1.5.2.1 openssl/crypto/engine/eng_all.c:1.5
721 --- openssl/crypto/engine/eng_all.c:1.5.2.1     Sun Jan 15 16:09:46 2012
722 +++ openssl/crypto/engine/eng_all.c     Mon Jun 13 17:13:35 2011
723 @@ -111,6 +111,14 @@
724  #if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
725         ENGINE_load_capi();
726  #endif
727 +#ifndef OPENSSL_NO_HW_PKCS11
728 +#ifndef OPENSSL_NO_HW_PKCS11CA
729 +       ENGINE_load_pk11ca();
730 +#endif
731 +#ifndef OPENSSL_NO_HW_PKCS11SO
732 +       ENGINE_load_pk11so();
733 +#endif
734 +#endif
735  #endif
736         }
738 Index: openssl/crypto/engine/engine.h
739 diff -u openssl/crypto/engine/engine.h:1.5.2.1 openssl/crypto/engine/engine.h:1.5
740 --- openssl/crypto/engine/engine.h:1.5.2.1      Sun Jan 15 16:09:46 2012
741 +++ openssl/crypto/engine/engine.h      Mon Jun 13 17:13:36 2011
742 @@ -336,6 +336,12 @@
743  void ENGINE_load_ubsec(void);
744  void ENGINE_load_padlock(void);
745  void ENGINE_load_capi(void);
746 +#ifndef OPENSSL_NO_HW_PKCS11CA
747 +void ENGINE_load_pk11ca(void);
748 +#endif
749 +#ifndef OPENSSL_NO_HW_PKCS11SO
750 +void ENGINE_load_pk11so(void);
751 +#endif
752  #ifndef OPENSSL_NO_GMP
753  void ENGINE_load_gmp(void);
754  #endif
755 Index: openssl/crypto/engine/hw_pk11.c
756 diff -u /dev/null openssl/crypto/engine/hw_pk11.c:1.30.4.2
757 --- /dev/null   Fri Jan  2 14:26:16 2015
758 +++ openssl/crypto/engine/hw_pk11.c     Fri Oct  4 14:33:56 2013
759 @@ -0,0 +1,4116 @@
761 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
762 + * Use is subject to license terms.
763 + */
765 +/* crypto/engine/hw_pk11.c */
767 + * This product includes software developed by the OpenSSL Project for
768 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
769 + *
770 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
771 + * Afchine Madjlessi.
772 + */
774 + * ====================================================================
775 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
776 + *
777 + * Redistribution and use in source and binary forms, with or without
778 + * modification, are permitted provided that the following conditions
779 + * are met:
780 + *
781 + * 1. Redistributions of source code must retain the above copyright
782 + *    notice, this list of conditions and the following disclaimer.
783 + *
784 + * 2. Redistributions in binary form must reproduce the above copyright
785 + *    notice, this list of conditions and the following disclaimer in
786 + *    the documentation and/or other materials provided with the
787 + *    distribution.
788 + *
789 + * 3. All advertising materials mentioning features or use of this
790 + *    software must display the following acknowledgment:
791 + *    "This product includes software developed by the OpenSSL Project
792 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
793 + *
794 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
795 + *    endorse or promote products derived from this software without
796 + *    prior written permission. For written permission, please contact
797 + *    licensing@OpenSSL.org.
798 + *
799 + * 5. Products derived from this software may not be called "OpenSSL"
800 + *    nor may "OpenSSL" appear in their names without prior written
801 + *    permission of the OpenSSL Project.
802 + *
803 + * 6. Redistributions of any form whatsoever must retain the following
804 + *    acknowledgment:
805 + *    "This product includes software developed by the OpenSSL Project
806 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
807 + *
808 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
809 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
810 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
811 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
812 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
813 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
814 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
815 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
816 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
817 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
818 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
819 + * OF THE POSSIBILITY OF SUCH DAMAGE.
820 + * ====================================================================
821 + *
822 + * This product includes cryptographic software written by Eric Young
823 + * (eay@cryptsoft.com).  This product includes software written by Tim
824 + * Hudson (tjh@cryptsoft.com).
825 + *
826 + */
828 +#include <stdio.h>
829 +#include <stdlib.h>
830 +#include <string.h>
831 +#include <sys/types.h>
833 +#include <openssl/e_os2.h>
834 +#include <openssl/crypto.h>
835 +#include <cryptlib.h>
836 +#include <openssl/engine.h>
837 +#include <openssl/dso.h>
838 +#include <openssl/err.h>
839 +#include <openssl/bn.h>
840 +#include <openssl/md5.h>
841 +#include <openssl/pem.h>
842 +#ifndef OPENSSL_NO_RSA
843 +#include <openssl/rsa.h>
844 +#endif
845 +#ifndef OPENSSL_NO_DSA
846 +#include <openssl/dsa.h>
847 +#endif
848 +#ifndef OPENSSL_NO_DH
849 +#include <openssl/dh.h>
850 +#endif
851 +#include <openssl/rand.h>
852 +#include <openssl/objects.h>
853 +#include <openssl/x509.h>
854 +#include <openssl/aes.h>
855 +#include <openssl/des.h>
857 +#ifdef OPENSSL_SYS_WIN32
858 +typedef int pid_t;
859 +#define getpid() GetCurrentProcessId()
860 +#define NOPTHREADS
861 +#ifndef NULL_PTR
862 +#define NULL_PTR NULL
863 +#endif
864 +#define CK_DEFINE_FUNCTION(returnType, name) \
865 +       returnType __declspec(dllexport) name
866 +#define CK_DECLARE_FUNCTION(returnType, name) \
867 +       returnType __declspec(dllimport) name
868 +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
869 +       returnType __declspec(dllimport) (* name)
870 +#else
871 +#include <signal.h>
872 +#include <unistd.h>
873 +#include <dlfcn.h>
874 +#endif
876 +/* Debug mutexes */
877 +/*#undef DEBUG_MUTEX */
878 +#define DEBUG_MUTEX
880 +#ifndef NOPTHREADS
881 +/* for pthread error check on Linuxes */
882 +#ifdef DEBUG_MUTEX
883 +#define __USE_UNIX98
884 +#endif
885 +#include <pthread.h>
886 +#endif
888 +#ifndef OPENSSL_NO_HW
889 +#ifndef OPENSSL_NO_HW_PK11
890 +#ifndef OPENSSL_NO_HW_PK11CA
892 +/* label for debug messages printed on stderr */
893 +#define        PK11_DBG        "PKCS#11 ENGINE DEBUG"
894 +/* prints a lot of debug messages on stderr about slot selection process */
895 +/* #undef      DEBUG_SLOT_SELECTION */
897 + * Solaris specific code. See comment at check_hw_mechanisms() for more
898 + * information.
899 + */
900 +#if defined(__SVR4) && defined(__sun)
901 +#undef SOLARIS_HW_SLOT_SELECTION
902 +#endif
905 + * AES counter mode is not supported in the OpenSSL EVP API yet and neither
906 + * there are official OIDs for mechanisms based on this mode. With our changes,
907 + * an application can define its own EVP calls for AES counter mode and then
908 + * it can make use of hardware acceleration through this engine. However, it's
909 + * better if we keep AES CTR support code under ifdef's.
910 + */
911 +#define        SOLARIS_AES_CTR
913 +#ifdef OPENSSL_SYS_WIN32
914 +#pragma pack(push, cryptoki, 1)
915 +#include "cryptoki.h"
916 +#include "pkcs11.h"
917 +#pragma pack(pop, cryptoki)
918 +#else
919 +#include "cryptoki.h"
920 +#include "pkcs11.h"
921 +#endif
922 +#include "hw_pk11ca.h"
923 +#include "hw_pk11_err.c"
925 +#ifdef SOLARIS_AES_CTR
927 + * NIDs for AES counter mode that will be defined during the engine
928 + * initialization.
929 + */
930 +static int NID_aes_128_ctr = NID_undef;
931 +static int NID_aes_192_ctr = NID_undef;
932 +static int NID_aes_256_ctr = NID_undef;
933 +#endif /* SOLARIS_AES_CTR */
936 + * We use this lock to prevent multiple C_Login()s, guard getpassphrase(),
937 + * uri_struct manipulation, and static token info. All of that is used by the
938 + * RSA keys by reference feature.
939 + */
940 +#ifndef NOPTHREADS
941 +pthread_mutex_t *token_lock;
942 +#endif
944 +#ifdef SOLARIS_HW_SLOT_SELECTION
946 + * Tables for symmetric ciphers and digest mechs found in the pkcs11_kernel
947 + * library. See comment at check_hw_mechanisms() for more information.
948 + */
949 +static int *hw_cnids;
950 +static int *hw_dnids;
951 +#endif /* SOLARIS_HW_SLOT_SELECTION */
953 +/* PKCS#11 session caches and their locks for all operation types */
954 +static PK11_CACHE session_cache[OP_MAX];
957 + * We cache the flags so that we do not have to run C_GetTokenInfo() again when
958 + * logging into the token.
959 + */
960 +CK_FLAGS pubkey_token_flags;
963 + * As stated in v2.20, 11.7 Object Management Function, in section for
964 + * C_FindObjectsInit(), at most one search operation may be active at a given
965 + * time in a given session. Therefore, C_Find{,Init,Final}Objects() should be
966 + * grouped together to form one atomic search operation. This is already
967 + * ensured by the property of unique PKCS#11 session handle used for each
968 + * PK11_SESSION object.
969 + *
970 + * This is however not the biggest concern - maintaining consistency of the
971 + * underlying object store is more important. The same section of the spec also
972 + * says that one thread can be in the middle of a search operation while another
973 + * thread destroys the object matching the search template which would result in
974 + * invalid handle returned from the search operation.
975 + *
976 + * Hence, the following locks are used for both protection of the object stores.
977 + * They are also used for active list protection.
978 + */
979 +#ifndef NOPTHREADS
980 +pthread_mutex_t *find_lock[OP_MAX] = { NULL };
981 +#endif
984 + * lists of asymmetric key handles which are active (referenced by at least one
985 + * PK11_SESSION structure, either held by a thread or present in free_session
986 + * list) for given algorithm type
987 + */
988 +PK11_active *active_list[OP_MAX] = { NULL };
991 + * Create all secret key objects in a global session so that they are available
992 + * to use for other sessions. These other sessions may be opened or closed
993 + * without losing the secret key objects.
994 + */
995 +static CK_SESSION_HANDLE       global_session = CK_INVALID_HANDLE;
997 +/* ENGINE level stuff */
998 +static int pk11_init(ENGINE *e);
999 +static int pk11_library_init(ENGINE *e);
1000 +static int pk11_finish(ENGINE *e);
1001 +static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
1002 +static int pk11_destroy(ENGINE *e);
1004 +/* RAND stuff */
1005 +static void pk11_rand_seed(const void *buf, int num);
1006 +static void pk11_rand_add(const void *buf, int num, double add_entropy);
1007 +static void pk11_rand_cleanup(void);
1008 +static int pk11_rand_bytes(unsigned char *buf, int num);
1009 +static int pk11_rand_status(void);
1011 +/* These functions are also used in other files */
1012 +PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
1013 +void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
1015 +/* active list manipulation functions used in this file */
1016 +extern int pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type);
1017 +extern void pk11_free_active_list(PK11_OPTYPE type);
1019 +#ifndef OPENSSL_NO_RSA
1020 +int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
1021 +int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
1022 +int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
1023 +#endif
1024 +#ifndef OPENSSL_NO_DSA
1025 +int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
1026 +int pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
1027 +int pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
1028 +#endif
1029 +#ifndef OPENSSL_NO_DH
1030 +int pk11_destroy_dh_key_objects(PK11_SESSION *session);
1031 +int pk11_destroy_dh_object(PK11_SESSION *session, CK_BBOOL uselock);
1032 +#endif
1034 +/* Local helper functions */
1035 +static int pk11_free_all_sessions(void);
1036 +static int pk11_free_session_list(PK11_OPTYPE optype);
1037 +static int pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype);
1038 +static int pk11_destroy_cipher_key_objects(PK11_SESSION *session);
1039 +static int pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
1040 +       CK_BBOOL persistent);
1041 +static const char *get_PK11_LIBNAME(void);
1042 +static void free_PK11_LIBNAME(void);
1043 +static long set_PK11_LIBNAME(const char *name);
1045 +/* Symmetric cipher and digest support functions */
1046 +static int cipher_nid_to_pk11(int nid);
1047 +#ifdef SOLARIS_AES_CTR
1048 +static int pk11_add_NID(char *sn, char *ln);
1049 +static int pk11_add_aes_ctr_NIDs(void);
1050 +#endif /* SOLARIS_AES_CTR */
1051 +static int pk11_usable_ciphers(const int **nids);
1052 +static int pk11_usable_digests(const int **nids);
1053 +static int pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
1054 +       const unsigned char *iv, int enc);
1055 +static int pk11_cipher_final(PK11_SESSION *sp);
1056 +#if OPENSSL_VERSION_NUMBER < 0x10000000L
1057 +static int pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
1058 +       const unsigned char *in, unsigned int inl);
1059 +#else
1060 +static int pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
1061 +       const unsigned char *in, size_t inl);
1062 +#endif
1063 +static int pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx);
1064 +static int pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
1065 +       const int **nids, int nid);
1066 +static int pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
1067 +       const int **nids, int nid);
1068 +static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
1069 +       const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp);
1070 +static int check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key,
1071 +       int key_len);
1072 +static int md_nid_to_pk11(int nid);
1073 +static int pk11_digest_init(EVP_MD_CTX *ctx);
1074 +static int pk11_digest_update(EVP_MD_CTX *ctx, const void *data,
1075 +       size_t count);
1076 +static int pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md);
1077 +static int pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);
1078 +static int pk11_digest_cleanup(EVP_MD_CTX *ctx);
1080 +static int pk11_choose_slots(int *any_slot_found);
1081 +static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
1082 +    CK_SLOT_ID current_slot, int *current_slot_n_cipher,
1083 +    int *local_cipher_nids);
1084 +static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
1085 +    CK_SLOT_ID current_slot, int *current_slot_n_digest,
1086 +    int *local_digest_nids);
1087 +static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR, int slot_id,
1088 +    CK_MECHANISM_TYPE mech, int *current_slot_n_cipher, int *local_cipher_nids,
1089 +    int id);
1090 +static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
1091 +    CK_MECHANISM_TYPE mech, int *current_slot_n_digest, int *local_digest_nids,
1092 +    int id);
1094 +static int pk11_init_all_locks(void);
1095 +static void pk11_free_all_locks(void);
1097 +#ifdef SOLARIS_HW_SLOT_SELECTION
1098 +static int check_hw_mechanisms(void);
1099 +static int nid_in_table(int nid, int *nid_table);
1100 +#endif /* SOLARIS_HW_SLOT_SELECTION */
1102 +/* Index for the supported ciphers */
1103 +enum pk11_cipher_id {
1104 +       PK11_DES_CBC,
1105 +       PK11_DES3_CBC,
1106 +       PK11_DES_ECB,
1107 +       PK11_DES3_ECB,
1108 +       PK11_RC4,
1109 +       PK11_AES_128_CBC,
1110 +       PK11_AES_192_CBC,
1111 +       PK11_AES_256_CBC,
1112 +       PK11_AES_128_ECB,
1113 +       PK11_AES_192_ECB,
1114 +       PK11_AES_256_ECB,
1115 +       PK11_BLOWFISH_CBC,
1116 +#ifdef SOLARIS_AES_CTR
1117 +       PK11_AES_128_CTR,
1118 +       PK11_AES_192_CTR,
1119 +       PK11_AES_256_CTR,
1120 +#endif /* SOLARIS_AES_CTR */
1121 +       PK11_CIPHER_MAX
1124 +/* Index for the supported digests */
1125 +enum pk11_digest_id {
1126 +       PK11_MD5,
1127 +       PK11_SHA1,
1128 +       PK11_SHA224,
1129 +       PK11_SHA256,
1130 +       PK11_SHA384,
1131 +       PK11_SHA512,
1132 +       PK11_DIGEST_MAX
1135 +#define        TRY_OBJ_DESTROY(sp, obj_hdl, retval, uselock, alg_type, priv)   \
1136 +       {                                                               \
1137 +       if (uselock)                                                    \
1138 +               LOCK_OBJSTORE(alg_type);                                \
1139 +       if (pk11_active_delete(obj_hdl, alg_type) == 1)                 \
1140 +               {                                                       \
1141 +                 retval = pk11_destroy_object(sp->session, obj_hdl,    \
1142 +                 priv ? sp->priv_persistent : sp->pub_persistent);     \
1143 +               }                                                       \
1144 +       if (uselock)                                                    \
1145 +               UNLOCK_OBJSTORE(alg_type);                              \
1146 +       }
1148 +static int cipher_nids[PK11_CIPHER_MAX];
1149 +static int digest_nids[PK11_DIGEST_MAX];
1150 +static int cipher_count                = 0;
1151 +static int digest_count                = 0;
1152 +static CK_BBOOL pk11_have_rsa  = CK_FALSE;
1153 +static CK_BBOOL pk11_have_recover = CK_FALSE;
1154 +static CK_BBOOL pk11_have_dsa  = CK_FALSE;
1155 +static CK_BBOOL pk11_have_dh   = CK_FALSE;
1156 +static CK_BBOOL pk11_have_random = CK_FALSE;
1158 +typedef struct PK11_CIPHER_st
1159 +       {
1160 +       enum pk11_cipher_id     id;
1161 +       int                     nid;
1162 +       int                     iv_len;
1163 +       int                     min_key_len;
1164 +       int                     max_key_len;
1165 +       CK_KEY_TYPE             key_type;
1166 +       CK_MECHANISM_TYPE       mech_type;
1167 +       } PK11_CIPHER;
1169 +static PK11_CIPHER ciphers[] =
1170 +       {
1171 +       { PK11_DES_CBC,         NID_des_cbc,            8,       8,   8,
1172 +               CKK_DES,        CKM_DES_CBC, },
1173 +       { PK11_DES3_CBC,        NID_des_ede3_cbc,       8,      24,  24,
1174 +               CKK_DES3,       CKM_DES3_CBC, },
1175 +       { PK11_DES_ECB,         NID_des_ecb,            0,       8,   8,
1176 +               CKK_DES,        CKM_DES_ECB, },
1177 +       { PK11_DES3_ECB,        NID_des_ede3_ecb,       0,      24,  24,
1178 +               CKK_DES3,       CKM_DES3_ECB, },
1179 +       { PK11_RC4,             NID_rc4,                0,      16, 256,
1180 +               CKK_RC4,        CKM_RC4, },
1181 +       { PK11_AES_128_CBC,     NID_aes_128_cbc,        16,     16,  16,
1182 +               CKK_AES,        CKM_AES_CBC, },
1183 +       { PK11_AES_192_CBC,     NID_aes_192_cbc,        16,     24,  24,
1184 +               CKK_AES,        CKM_AES_CBC, },
1185 +       { PK11_AES_256_CBC,     NID_aes_256_cbc,        16,     32,  32,
1186 +               CKK_AES,        CKM_AES_CBC, },
1187 +       { PK11_AES_128_ECB,     NID_aes_128_ecb,        0,      16,  16,
1188 +               CKK_AES,        CKM_AES_ECB, },
1189 +       { PK11_AES_192_ECB,     NID_aes_192_ecb,        0,      24,  24,
1190 +               CKK_AES,        CKM_AES_ECB, },
1191 +       { PK11_AES_256_ECB,     NID_aes_256_ecb,        0,      32,  32,
1192 +               CKK_AES,        CKM_AES_ECB, },
1193 +       { PK11_BLOWFISH_CBC,    NID_bf_cbc,             8,      16,  16,
1194 +               CKK_BLOWFISH,   CKM_BLOWFISH_CBC, },
1195 +#ifdef SOLARIS_AES_CTR
1196 +       /* we don't know the correct NIDs until the engine is initialized */
1197 +       { PK11_AES_128_CTR,     NID_undef,              16,     16,  16,
1198 +               CKK_AES,        CKM_AES_CTR, },
1199 +       { PK11_AES_192_CTR,     NID_undef,              16,     24,  24,
1200 +               CKK_AES,        CKM_AES_CTR, },
1201 +       { PK11_AES_256_CTR,     NID_undef,              16,     32,  32,
1202 +               CKK_AES,        CKM_AES_CTR, },
1203 +#endif /* SOLARIS_AES_CTR */
1204 +       };
1206 +typedef struct PK11_DIGEST_st
1207 +       {
1208 +       enum pk11_digest_id     id;
1209 +       int                     nid;
1210 +       CK_MECHANISM_TYPE       mech_type;
1211 +       } PK11_DIGEST;
1213 +static PK11_DIGEST digests[] =
1214 +       {
1215 +       {PK11_MD5,      NID_md5,        CKM_MD5, },
1216 +       {PK11_SHA1,     NID_sha1,       CKM_SHA_1, },
1217 +       {PK11_SHA224,   NID_sha224,     CKM_SHA224, },
1218 +       {PK11_SHA256,   NID_sha256,     CKM_SHA256, },
1219 +       {PK11_SHA384,   NID_sha384,     CKM_SHA384, },
1220 +       {PK11_SHA512,   NID_sha512,     CKM_SHA512, },
1221 +       {0,             NID_undef,      0xFFFF, },
1222 +       };
1225 + * Structure to be used for the cipher_data/md_data in
1226 + * EVP_CIPHER_CTX/EVP_MD_CTX structures in order to use the same pk11
1227 + * session in multiple cipher_update calls
1228 + */
1229 +typedef struct PK11_CIPHER_STATE_st
1230 +       {
1231 +       PK11_SESSION    *sp;
1232 +       } PK11_CIPHER_STATE;
1236 + * libcrypto EVP stuff - this is how we get wired to EVP so the engine gets
1237 + * called when libcrypto requests a cipher NID.
1238 + *
1239 + * Note how the PK11_CIPHER_STATE is used here.
1240 + */
1242 +/* DES CBC EVP */
1243 +static const EVP_CIPHER pk11_des_cbc =
1244 +       {
1245 +       NID_des_cbc,
1246 +       8, 8, 8,
1247 +       EVP_CIPH_CBC_MODE,
1248 +       pk11_cipher_init,
1249 +       pk11_cipher_do_cipher,
1250 +       pk11_cipher_cleanup,
1251 +       sizeof (PK11_CIPHER_STATE),
1252 +       EVP_CIPHER_set_asn1_iv,
1253 +       EVP_CIPHER_get_asn1_iv,
1254 +       NULL
1255 +       };
1257 +/* 3DES CBC EVP */
1258 +static const EVP_CIPHER pk11_3des_cbc =
1259 +       {
1260 +       NID_des_ede3_cbc,
1261 +       8, 24, 8,
1262 +       EVP_CIPH_CBC_MODE,
1263 +       pk11_cipher_init,
1264 +       pk11_cipher_do_cipher,
1265 +       pk11_cipher_cleanup,
1266 +       sizeof (PK11_CIPHER_STATE),
1267 +       EVP_CIPHER_set_asn1_iv,
1268 +       EVP_CIPHER_get_asn1_iv,
1269 +       NULL
1270 +       };
1273 + * ECB modes don't use an Initial Vector so that's why set_asn1_parameters and
1274 + * get_asn1_parameters fields are set to NULL.
1275 + */
1276 +static const EVP_CIPHER pk11_des_ecb =
1277 +       {
1278 +       NID_des_ecb,
1279 +       8, 8, 8,
1280 +       EVP_CIPH_ECB_MODE,
1281 +       pk11_cipher_init,
1282 +       pk11_cipher_do_cipher,
1283 +       pk11_cipher_cleanup,
1284 +       sizeof (PK11_CIPHER_STATE),
1285 +       NULL,
1286 +       NULL,
1287 +       NULL
1288 +       };
1290 +static const EVP_CIPHER pk11_3des_ecb =
1291 +       {
1292 +       NID_des_ede3_ecb,
1293 +       8, 24, 8,
1294 +       EVP_CIPH_ECB_MODE,
1295 +       pk11_cipher_init,
1296 +       pk11_cipher_do_cipher,
1297 +       pk11_cipher_cleanup,
1298 +       sizeof (PK11_CIPHER_STATE),
1299 +       NULL,
1300 +       NULL,
1301 +       NULL
1302 +       };
1305 +static const EVP_CIPHER pk11_aes_128_cbc =
1306 +       {
1307 +       NID_aes_128_cbc,
1308 +       16, 16, 16,
1309 +       EVP_CIPH_CBC_MODE,
1310 +       pk11_cipher_init,
1311 +       pk11_cipher_do_cipher,
1312 +       pk11_cipher_cleanup,
1313 +       sizeof (PK11_CIPHER_STATE),
1314 +       EVP_CIPHER_set_asn1_iv,
1315 +       EVP_CIPHER_get_asn1_iv,
1316 +       NULL
1317 +       };
1319 +static const EVP_CIPHER pk11_aes_192_cbc =
1320 +       {
1321 +       NID_aes_192_cbc,
1322 +       16, 24, 16,
1323 +       EVP_CIPH_CBC_MODE,
1324 +       pk11_cipher_init,
1325 +       pk11_cipher_do_cipher,
1326 +       pk11_cipher_cleanup,
1327 +       sizeof (PK11_CIPHER_STATE),
1328 +       EVP_CIPHER_set_asn1_iv,
1329 +       EVP_CIPHER_get_asn1_iv,
1330 +       NULL
1331 +       };
1333 +static const EVP_CIPHER pk11_aes_256_cbc =
1334 +       {
1335 +       NID_aes_256_cbc,
1336 +       16, 32, 16,
1337 +       EVP_CIPH_CBC_MODE,
1338 +       pk11_cipher_init,
1339 +       pk11_cipher_do_cipher,
1340 +       pk11_cipher_cleanup,
1341 +       sizeof (PK11_CIPHER_STATE),
1342 +       EVP_CIPHER_set_asn1_iv,
1343 +       EVP_CIPHER_get_asn1_iv,
1344 +       NULL
1345 +       };
1348 + * ECB modes don't use IV so that's why set_asn1_parameters and
1349 + * get_asn1_parameters are set to NULL.
1350 + */
1351 +static const EVP_CIPHER pk11_aes_128_ecb =
1352 +       {
1353 +       NID_aes_128_ecb,
1354 +       16, 16, 0,
1355 +       EVP_CIPH_ECB_MODE,
1356 +       pk11_cipher_init,
1357 +       pk11_cipher_do_cipher,
1358 +       pk11_cipher_cleanup,
1359 +       sizeof (PK11_CIPHER_STATE),
1360 +       NULL,
1361 +       NULL,
1362 +       NULL
1363 +       };
1365 +static const EVP_CIPHER pk11_aes_192_ecb =
1366 +       {
1367 +       NID_aes_192_ecb,
1368 +       16, 24, 0,
1369 +       EVP_CIPH_ECB_MODE,
1370 +       pk11_cipher_init,
1371 +       pk11_cipher_do_cipher,
1372 +       pk11_cipher_cleanup,
1373 +       sizeof (PK11_CIPHER_STATE),
1374 +       NULL,
1375 +       NULL,
1376 +       NULL
1377 +       };
1379 +static const EVP_CIPHER pk11_aes_256_ecb =
1380 +       {
1381 +       NID_aes_256_ecb,
1382 +       16, 32, 0,
1383 +       EVP_CIPH_ECB_MODE,
1384 +       pk11_cipher_init,
1385 +       pk11_cipher_do_cipher,
1386 +       pk11_cipher_cleanup,
1387 +       sizeof (PK11_CIPHER_STATE),
1388 +       NULL,
1389 +       NULL,
1390 +       NULL
1391 +       };
1393 +#ifdef SOLARIS_AES_CTR
1395 + * NID_undef's will be changed to the AES counter mode NIDs as soon they are
1396 + * created in pk11_library_init(). Note that the need to change these structures
1397 + * is the reason why we don't define them with the const keyword.
1398 + */
1399 +static EVP_CIPHER pk11_aes_128_ctr =
1400 +       {
1401 +       NID_undef,
1402 +       16, 16, 16,
1403 +       EVP_CIPH_CBC_MODE,
1404 +       pk11_cipher_init,
1405 +       pk11_cipher_do_cipher,
1406 +       pk11_cipher_cleanup,
1407 +       sizeof (PK11_CIPHER_STATE),
1408 +       EVP_CIPHER_set_asn1_iv,
1409 +       EVP_CIPHER_get_asn1_iv,
1410 +       NULL
1411 +       };
1413 +static EVP_CIPHER pk11_aes_192_ctr =
1414 +       {
1415 +       NID_undef,
1416 +       16, 24, 16,
1417 +       EVP_CIPH_CBC_MODE,
1418 +       pk11_cipher_init,
1419 +       pk11_cipher_do_cipher,
1420 +       pk11_cipher_cleanup,
1421 +       sizeof (PK11_CIPHER_STATE),
1422 +       EVP_CIPHER_set_asn1_iv,
1423 +       EVP_CIPHER_get_asn1_iv,
1424 +       NULL
1425 +       };
1427 +static EVP_CIPHER pk11_aes_256_ctr =
1428 +       {
1429 +       NID_undef,
1430 +       16, 32, 16,
1431 +       EVP_CIPH_CBC_MODE,
1432 +       pk11_cipher_init,
1433 +       pk11_cipher_do_cipher,
1434 +       pk11_cipher_cleanup,
1435 +       sizeof (PK11_CIPHER_STATE),
1436 +       EVP_CIPHER_set_asn1_iv,
1437 +       EVP_CIPHER_get_asn1_iv,
1438 +       NULL
1439 +       };
1440 +#endif /* SOLARIS_AES_CTR */
1442 +static const EVP_CIPHER pk11_bf_cbc =
1443 +       {
1444 +       NID_bf_cbc,
1445 +       8, 16, 8,
1446 +       EVP_CIPH_VARIABLE_LENGTH,
1447 +       pk11_cipher_init,
1448 +       pk11_cipher_do_cipher,
1449 +       pk11_cipher_cleanup,
1450 +       sizeof (PK11_CIPHER_STATE),
1451 +       EVP_CIPHER_set_asn1_iv,
1452 +       EVP_CIPHER_get_asn1_iv,
1453 +       NULL
1454 +       };
1456 +static const EVP_CIPHER pk11_rc4 =
1457 +       {
1458 +       NID_rc4,
1459 +       1, 16, 0,
1460 +       EVP_CIPH_VARIABLE_LENGTH,
1461 +       pk11_cipher_init,
1462 +       pk11_cipher_do_cipher,
1463 +       pk11_cipher_cleanup,
1464 +       sizeof (PK11_CIPHER_STATE),
1465 +       NULL,
1466 +       NULL,
1467 +       NULL
1468 +       };
1470 +static const EVP_MD pk11_md5 =
1471 +       {
1472 +       NID_md5,
1473 +       NID_md5WithRSAEncryption,
1474 +       MD5_DIGEST_LENGTH,
1475 +       0,
1476 +       pk11_digest_init,
1477 +       pk11_digest_update,
1478 +       pk11_digest_final,
1479 +       pk11_digest_copy,
1480 +       pk11_digest_cleanup,
1481 +       EVP_PKEY_RSA_method,
1482 +       MD5_CBLOCK,
1483 +       sizeof (PK11_CIPHER_STATE),
1484 +       };
1486 +static const EVP_MD pk11_sha1 =
1487 +       {
1488 +       NID_sha1,
1489 +       NID_sha1WithRSAEncryption,
1490 +       SHA_DIGEST_LENGTH,
1491 +       EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
1492 +       pk11_digest_init,
1493 +       pk11_digest_update,
1494 +       pk11_digest_final,
1495 +       pk11_digest_copy,
1496 +       pk11_digest_cleanup,
1497 +       EVP_PKEY_RSA_method,
1498 +       SHA_CBLOCK,
1499 +       sizeof (PK11_CIPHER_STATE),
1500 +       };
1502 +static const EVP_MD pk11_sha224 =
1503 +       {
1504 +       NID_sha224,
1505 +       NID_sha224WithRSAEncryption,
1506 +       SHA224_DIGEST_LENGTH,
1507 +       EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
1508 +       pk11_digest_init,
1509 +       pk11_digest_update,
1510 +       pk11_digest_final,
1511 +       pk11_digest_copy,
1512 +       pk11_digest_cleanup,
1513 +       EVP_PKEY_RSA_method,
1514 +       /* SHA-224 uses the same cblock size as SHA-256 */
1515 +       SHA256_CBLOCK,
1516 +       sizeof (PK11_CIPHER_STATE),
1517 +       };
1519 +static const EVP_MD pk11_sha256 =
1520 +       {
1521 +       NID_sha256,
1522 +       NID_sha256WithRSAEncryption,
1523 +       SHA256_DIGEST_LENGTH,
1524 +       EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
1525 +       pk11_digest_init,
1526 +       pk11_digest_update,
1527 +       pk11_digest_final,
1528 +       pk11_digest_copy,
1529 +       pk11_digest_cleanup,
1530 +       EVP_PKEY_RSA_method,
1531 +       SHA256_CBLOCK,
1532 +       sizeof (PK11_CIPHER_STATE),
1533 +       };
1535 +static const EVP_MD pk11_sha384 =
1536 +       {
1537 +       NID_sha384,
1538 +       NID_sha384WithRSAEncryption,
1539 +       SHA384_DIGEST_LENGTH,
1540 +       EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
1541 +       pk11_digest_init,
1542 +       pk11_digest_update,
1543 +       pk11_digest_final,
1544 +       pk11_digest_copy,
1545 +       pk11_digest_cleanup,
1546 +       EVP_PKEY_RSA_method,
1547 +       /* SHA-384 uses the same cblock size as SHA-512 */
1548 +       SHA512_CBLOCK,
1549 +       sizeof (PK11_CIPHER_STATE),
1550 +       };
1552 +static const EVP_MD pk11_sha512 =
1553 +       {
1554 +       NID_sha512,
1555 +       NID_sha512WithRSAEncryption,
1556 +       SHA512_DIGEST_LENGTH,
1557 +       EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
1558 +       pk11_digest_init,
1559 +       pk11_digest_update,
1560 +       pk11_digest_final,
1561 +       pk11_digest_copy,
1562 +       pk11_digest_cleanup,
1563 +       EVP_PKEY_RSA_method,
1564 +       SHA512_CBLOCK,
1565 +       sizeof (PK11_CIPHER_STATE),
1566 +       };
1569 + * Initialization function. Sets up various PKCS#11 library components.
1570 + * The definitions for control commands specific to this engine
1571 + */
1572 +#define PK11_CMD_SO_PATH               ENGINE_CMD_BASE
1573 +#define PK11_CMD_PIN                   (ENGINE_CMD_BASE+1)
1574 +#define PK11_CMD_SLOT                  (ENGINE_CMD_BASE+2)
1575 +static const ENGINE_CMD_DEFN pk11_cmd_defns[] =
1576 +       {
1577 +               {
1578 +               PK11_CMD_SO_PATH,
1579 +               "SO_PATH",
1580 +               "Specifies the path to the 'pkcs#11' shared library",
1581 +               ENGINE_CMD_FLAG_STRING
1582 +               },
1583 +               {
1584 +               PK11_CMD_PIN,
1585 +               "PIN",
1586 +               "Specifies the pin code",
1587 +               ENGINE_CMD_FLAG_STRING
1588 +               },
1589 +               {
1590 +               PK11_CMD_SLOT,
1591 +               "SLOT",
1592 +               "Specifies the slot (default is auto select)",
1593 +               ENGINE_CMD_FLAG_NUMERIC,
1594 +               },
1595 +               {0, NULL, NULL, 0}
1596 +       };
1599 +static RAND_METHOD pk11_random =
1600 +       {
1601 +       pk11_rand_seed,
1602 +       pk11_rand_bytes,
1603 +       pk11_rand_cleanup,
1604 +       pk11_rand_add,
1605 +       pk11_rand_bytes,
1606 +       pk11_rand_status
1607 +       };
1610 +/* Constants used when creating the ENGINE */
1611 +#ifdef OPENSSL_NO_HW_PK11SO
1612 +#error "can't load both crypto-accelerator and sign-only PKCS#11 engines"
1613 +#endif
1614 +static const char *engine_pk11_id = "pkcs11";
1615 +static const char *engine_pk11_name =
1616 +       "PKCS #11 engine support (crypto accelerator)";
1618 +CK_FUNCTION_LIST_PTR pFuncList = NULL;
1619 +static const char PK11_GET_FUNCTION_LIST[] = "C_GetFunctionList";
1622 + * This is a static string constant for the DSO file name and the function
1623 + * symbol names to bind to. We set it in the Configure script based on whether
1624 + * this is 32 or 64 bit build.
1625 + */
1626 +static const char def_PK11_LIBNAME[] = PK11_LIB_LOCATION;
1628 +static CK_BBOOL mytrue = TRUE;
1629 +static CK_BBOOL myfalse = FALSE;
1630 +/* Needed in hw_pk11_pub.c as well so that's why it is not static. */
1631 +CK_SLOT_ID pubkey_SLOTID = 0;
1632 +static CK_SLOT_ID rand_SLOTID = 0;
1633 +static CK_SLOT_ID SLOTID = 0;
1634 +char *pk11_pin = NULL;
1635 +static CK_BBOOL pk11_library_initialized = FALSE;
1636 +static CK_BBOOL pk11_atfork_initialized = FALSE;
1637 +static int pk11_pid = 0;
1639 +static DSO *pk11_dso = NULL;
1641 +/* allocate and initialize all locks used by the engine itself */
1642 +static int pk11_init_all_locks(void)
1643 +       {
1644 +#ifndef NOPTHREADS
1645 +       int type;
1646 +       pthread_mutexattr_t attr;
1648 +       if (pthread_mutexattr_init(&attr) != 0)
1649 +       {
1650 +               PK11err(PK11_F_INIT_ALL_LOCKS, 100);
1651 +               return (0);
1652 +       }
1654 +#ifdef DEBUG_MUTEX
1655 +       if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0)
1656 +       {
1657 +               PK11err(PK11_F_INIT_ALL_LOCKS, 101);
1658 +               return (0);
1659 +       }
1660 +#endif
1662 +       if ((token_lock = OPENSSL_malloc(sizeof (pthread_mutex_t))) == NULL)
1663 +               goto malloc_err;
1664 +       (void) pthread_mutex_init(token_lock, &attr);
1666 +#ifndef OPENSSL_NO_RSA
1667 +       find_lock[OP_RSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
1668 +       if (find_lock[OP_RSA] == NULL)
1669 +               goto malloc_err;
1670 +       (void) pthread_mutex_init(find_lock[OP_RSA], &attr);
1671 +#endif /* OPENSSL_NO_RSA */
1673 +#ifndef OPENSSL_NO_DSA
1674 +       find_lock[OP_DSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
1675 +       if (find_lock[OP_DSA] == NULL)
1676 +               goto malloc_err;
1677 +       (void) pthread_mutex_init(find_lock[OP_DSA], &attr);
1678 +#endif /* OPENSSL_NO_DSA */
1680 +#ifndef OPENSSL_NO_DH
1681 +       find_lock[OP_DH] = OPENSSL_malloc(sizeof (pthread_mutex_t));
1682 +       if (find_lock[OP_DH] == NULL)
1683 +               goto malloc_err;
1684 +       (void) pthread_mutex_init(find_lock[OP_DH], &attr);
1685 +#endif /* OPENSSL_NO_DH */
1687 +       for (type = 0; type < OP_MAX; type++)
1688 +               {
1689 +               session_cache[type].lock =
1690 +                   OPENSSL_malloc(sizeof (pthread_mutex_t));
1691 +               if (session_cache[type].lock == NULL)
1692 +                       goto malloc_err;
1693 +               (void) pthread_mutex_init(session_cache[type].lock, &attr);
1694 +               }
1696 +       return (1);
1698 +malloc_err:
1699 +       pk11_free_all_locks();
1700 +       PK11err(PK11_F_INIT_ALL_LOCKS, PK11_R_MALLOC_FAILURE);
1701 +       return (0);
1702 +#else
1703 +       return (1);
1704 +#endif
1705 +       }
1707 +static void pk11_free_all_locks(void)
1708 +       {
1709 +#ifndef NOPTHREADS
1710 +       int type;
1712 +       if (token_lock != NULL)
1713 +               {
1714 +               (void) pthread_mutex_destroy(token_lock);
1715 +               OPENSSL_free(token_lock);
1716 +               token_lock = NULL;
1717 +               }
1719 +#ifndef OPENSSL_NO_RSA
1720 +       if (find_lock[OP_RSA] != NULL)
1721 +               {
1722 +               (void) pthread_mutex_destroy(find_lock[OP_RSA]);
1723 +               OPENSSL_free(find_lock[OP_RSA]);
1724 +               find_lock[OP_RSA] = NULL;
1725 +               }
1726 +#endif /* OPENSSL_NO_RSA */
1727 +#ifndef OPENSSL_NO_DSA
1728 +       if (find_lock[OP_DSA] != NULL)
1729 +               {
1730 +               (void) pthread_mutex_destroy(find_lock[OP_DSA]);
1731 +               OPENSSL_free(find_lock[OP_DSA]);
1732 +               find_lock[OP_DSA] = NULL;
1733 +               }
1734 +#endif /* OPENSSL_NO_DSA */
1735 +#ifndef OPENSSL_NO_DH
1736 +       if (find_lock[OP_DH] != NULL)
1737 +               {
1738 +               (void) pthread_mutex_destroy(find_lock[OP_DH]);
1739 +               OPENSSL_free(find_lock[OP_DH]);
1740 +               find_lock[OP_DH] = NULL;
1741 +               }
1742 +#endif /* OPENSSL_NO_DH */
1744 +       for (type = 0; type < OP_MAX; type++)
1745 +               {
1746 +               if (session_cache[type].lock != NULL)
1747 +                       {
1748 +                       (void) pthread_mutex_destroy(session_cache[type].lock);
1749 +                       OPENSSL_free(session_cache[type].lock);
1750 +                       session_cache[type].lock = NULL;
1751 +                       }
1752 +               }
1753 +#endif
1754 +       }
1757 + * This internal function is used by ENGINE_pk11() and "dynamic" ENGINE support.
1758 + */
1759 +static int bind_pk11(ENGINE *e)
1760 +       {
1761 +#ifndef OPENSSL_NO_RSA
1762 +       const RSA_METHOD *rsa = NULL;
1763 +       RSA_METHOD *pk11_rsa = PK11_RSA();
1764 +#endif /* OPENSSL_NO_RSA */
1765 +       if (!pk11_library_initialized)
1766 +               if (!pk11_library_init(e))
1767 +                       return (0);
1769 +       if (!ENGINE_set_id(e, engine_pk11_id) ||
1770 +           !ENGINE_set_name(e, engine_pk11_name) ||
1771 +           !ENGINE_set_ciphers(e, pk11_engine_ciphers) ||
1772 +           !ENGINE_set_digests(e, pk11_engine_digests))
1773 +               return (0);
1774 +#ifndef OPENSSL_NO_RSA
1775 +       if (pk11_have_rsa == CK_TRUE)
1776 +               {
1777 +               if (!ENGINE_set_RSA(e, PK11_RSA()) ||
1778 +                   !ENGINE_set_load_privkey_function(e, pk11_load_privkey) ||
1779 +                   !ENGINE_set_load_pubkey_function(e, pk11_load_pubkey))
1780 +                       return (0);
1781 +#ifdef DEBUG_SLOT_SELECTION
1782 +               fprintf(stderr, "%s: registered RSA\n", PK11_DBG);
1783 +#endif /* DEBUG_SLOT_SELECTION */
1784 +               }
1785 +#endif /* OPENSSL_NO_RSA */
1786 +#ifndef OPENSSL_NO_DSA
1787 +       if (pk11_have_dsa == CK_TRUE)
1788 +               {
1789 +               if (!ENGINE_set_DSA(e, PK11_DSA()))
1790 +                       return (0);
1791 +#ifdef DEBUG_SLOT_SELECTION
1792 +               fprintf(stderr, "%s: registered DSA\n", PK11_DBG);
1793 +#endif /* DEBUG_SLOT_SELECTION */
1794 +               }
1795 +#endif /* OPENSSL_NO_DSA */
1796 +#ifndef OPENSSL_NO_DH
1797 +       if (pk11_have_dh == CK_TRUE)
1798 +               {
1799 +               if (!ENGINE_set_DH(e, PK11_DH()))
1800 +                       return (0);
1801 +#ifdef DEBUG_SLOT_SELECTION
1802 +               fprintf(stderr, "%s: registered DH\n", PK11_DBG);
1803 +#endif /* DEBUG_SLOT_SELECTION */
1804 +               }
1805 +#endif /* OPENSSL_NO_DH */
1806 +       if (pk11_have_random)
1807 +               {
1808 +               if (!ENGINE_set_RAND(e, &pk11_random))
1809 +                       return (0);
1810 +#ifdef DEBUG_SLOT_SELECTION
1811 +               fprintf(stderr, "%s: registered random\n", PK11_DBG);
1812 +#endif /* DEBUG_SLOT_SELECTION */
1813 +               }
1814 +       if (!ENGINE_set_init_function(e, pk11_init) ||
1815 +           !ENGINE_set_destroy_function(e, pk11_destroy) ||
1816 +           !ENGINE_set_finish_function(e, pk11_finish) ||
1817 +           !ENGINE_set_ctrl_function(e, pk11_ctrl) ||
1818 +           !ENGINE_set_cmd_defns(e, pk11_cmd_defns))
1819 +               return (0);
1822 + * Apache calls OpenSSL function RSA_blinding_on() once during startup
1823 + * which in turn calls bn_mod_exp. Since we do not implement bn_mod_exp
1824 + * here, we wire it back to the OpenSSL software implementation.
1825 + * Since it is used only once, performance is not a concern.
1826 + */
1827 +#ifndef OPENSSL_NO_RSA
1828 +       rsa = RSA_PKCS1_SSLeay();
1829 +       pk11_rsa->rsa_mod_exp = rsa->rsa_mod_exp;
1830 +       pk11_rsa->bn_mod_exp = rsa->bn_mod_exp;
1831 +       if (pk11_have_recover != CK_TRUE)
1832 +               pk11_rsa->rsa_pub_dec = rsa->rsa_pub_dec;
1833 +#endif /* OPENSSL_NO_RSA */
1835 +       /* Ensure the pk11 error handling is set up */
1836 +       ERR_load_pk11_strings();
1838 +       return (1);
1839 +       }
1841 +/* Dynamic engine support is disabled at a higher level for Solaris */
1842 +#ifdef ENGINE_DYNAMIC_SUPPORT
1843 +#error  "dynamic engine not supported"
1844 +static int bind_helper(ENGINE *e, const char *id)
1845 +       {
1846 +       if (id && (strcmp(id, engine_pk11_id) != 0))
1847 +               return (0);
1849 +       if (!bind_pk11(e))
1850 +               return (0);
1852 +       return (1);
1853 +       }
1855 +IMPLEMENT_DYNAMIC_CHECK_FN()
1856 +IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
1858 +#else
1859 +static ENGINE *engine_pk11(void)
1860 +       {
1861 +       ENGINE *ret = ENGINE_new();
1863 +       if (!ret)
1864 +               return (NULL);
1866 +       if (!bind_pk11(ret))
1867 +               {
1868 +               ENGINE_free(ret);
1869 +               return (NULL);
1870 +               }
1872 +       return (ret);
1873 +       }
1875 +void
1876 +ENGINE_load_pk11(void)
1877 +       {
1878 +       ENGINE *e_pk11 = NULL;
1880 +       /*
1881 +        * Do not use dynamic PKCS#11 library on Solaris due to
1882 +        * security reasons. We will link it in statically.
1883 +        */
1884 +       /* Attempt to load PKCS#11 library */
1885 +       if (!pk11_dso)
1886 +               pk11_dso = DSO_load(NULL, get_PK11_LIBNAME(), NULL, 0);
1888 +       if (pk11_dso == NULL)
1889 +               {
1890 +               PK11err(PK11_F_LOAD, PK11_R_DSO_FAILURE);
1891 +               return;
1892 +               }
1894 +       e_pk11 = engine_pk11();
1895 +       if (!e_pk11)
1896 +               {
1897 +               DSO_free(pk11_dso);
1898 +               pk11_dso = NULL;
1899 +               return;
1900 +               }
1902 +       /*
1903 +        * At this point, the pk11 shared library is either dynamically
1904 +        * loaded or statically linked in. So, initialize the pk11
1905 +        * library before calling ENGINE_set_default since the latter
1906 +        * needs cipher and digest algorithm information
1907 +        */
1908 +       if (!pk11_library_init(e_pk11))
1909 +               {
1910 +               DSO_free(pk11_dso);
1911 +               pk11_dso = NULL;
1912 +               ENGINE_free(e_pk11);
1913 +               return;
1914 +               }
1916 +       ENGINE_add(e_pk11);
1918 +       ENGINE_free(e_pk11);
1919 +       ERR_clear_error();
1920 +       }
1921 +#endif /* ENGINE_DYNAMIC_SUPPORT */
1924 + * These are the static string constants for the DSO file name and
1925 + * the function symbol names to bind to.
1926 + */
1927 +static const char *PK11_LIBNAME = NULL;
1929 +static const char *get_PK11_LIBNAME(void)
1930 +       {
1931 +       if (PK11_LIBNAME)
1932 +               return (PK11_LIBNAME);
1934 +       return (def_PK11_LIBNAME);
1935 +       }
1937 +static void free_PK11_LIBNAME(void)
1938 +       {
1939 +       if (PK11_LIBNAME)
1940 +               OPENSSL_free((void*)PK11_LIBNAME);
1942 +       PK11_LIBNAME = NULL;
1943 +       }
1945 +static long set_PK11_LIBNAME(const char *name)
1946 +       {
1947 +       free_PK11_LIBNAME();
1949 +       return ((PK11_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
1950 +       }
1952 +/* acquire all engine specific mutexes before fork */
1953 +static void pk11_fork_prepare(void)
1954 +       {
1955 +#ifndef NOPTHREADS
1956 +       int i;
1958 +       if (!pk11_library_initialized)
1959 +               return;
1961 +       LOCK_OBJSTORE(OP_RSA);
1962 +       LOCK_OBJSTORE(OP_DSA);
1963 +       LOCK_OBJSTORE(OP_DH);
1964 +       OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
1965 +       for (i = 0; i < OP_MAX; i++)
1966 +               {
1967 +               OPENSSL_assert(pthread_mutex_lock(session_cache[i].lock) == 0);
1968 +               }
1969 +#endif
1970 +       }
1972 +/* release all engine specific mutexes */
1973 +static void pk11_fork_parent(void)
1974 +       {
1975 +#ifndef NOPTHREADS
1976 +       int i;
1978 +       if (!pk11_library_initialized)
1979 +               return;
1981 +       for (i = OP_MAX - 1; i >= 0; i--)
1982 +               {
1983 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[i].lock) == 0);
1984 +               }
1985 +       UNLOCK_OBJSTORE(OP_DH);
1986 +       UNLOCK_OBJSTORE(OP_DSA);
1987 +       UNLOCK_OBJSTORE(OP_RSA);
1988 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
1989 +#endif
1990 +       }
1993 + * same situation as in parent - we need to unlock all locks to make them
1994 + * accessible to all threads.
1995 + */
1996 +static void pk11_fork_child(void)
1997 +       {
1998 +#ifndef NOPTHREADS
1999 +       int i;
2001 +       if (!pk11_library_initialized)
2002 +               return;
2004 +       for (i = OP_MAX - 1; i >= 0; i--)
2005 +               {
2006 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[i].lock) == 0);
2007 +               }
2008 +       UNLOCK_OBJSTORE(OP_DH);
2009 +       UNLOCK_OBJSTORE(OP_DSA);
2010 +       UNLOCK_OBJSTORE(OP_RSA);
2011 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
2012 +#endif
2013 +       }
2015 +/* Initialization function for the pk11 engine */
2016 +static int pk11_init(ENGINE *e)
2018 +       return (pk11_library_init(e));
2021 +static CK_C_INITIALIZE_ARGS pk11_init_args =
2022 +       {
2023 +       NULL_PTR,               /* CreateMutex */
2024 +       NULL_PTR,               /* DestroyMutex */
2025 +       NULL_PTR,               /* LockMutex */
2026 +       NULL_PTR,               /* UnlockMutex */
2027 +       CKF_OS_LOCKING_OK,      /* flags */
2028 +       NULL_PTR,               /* pReserved */
2029 +       };
2032 + * Initialization function. Sets up various PKCS#11 library components.
2033 + * It selects a slot based on predefined critiera. In the process, it also
2034 + * count how many ciphers and digests to support. Since the cipher and
2035 + * digest information is needed when setting default engine, this function
2036 + * needs to be called before calling ENGINE_set_default.
2037 + */
2038 +/* ARGSUSED */
2039 +static int pk11_library_init(ENGINE *e)
2040 +       {
2041 +       CK_C_GetFunctionList p;
2042 +       CK_RV rv = CKR_OK;
2043 +       CK_INFO info;
2044 +       CK_ULONG ul_state_len;
2045 +       int any_slot_found;
2046 +       int i;
2047 +#ifndef OPENSSL_SYS_WIN32
2048 +       struct sigaction sigint_act, sigterm_act, sighup_act;
2049 +#endif
2051 +       /*
2052 +        * pk11_library_initialized is set to 0 in pk11_finish() which
2053 +        * is called from ENGINE_finish(). However, if there is still
2054 +        * at least one existing functional reference to the engine
2055 +        * (see engine(3) for more information), pk11_finish() is
2056 +        * skipped. For example, this can happen if an application
2057 +        * forgets to clear one cipher context. In case of a fork()
2058 +        * when the application is finishing the engine so that it can
2059 +        * be reinitialized in the child, forgotten functional
2060 +        * reference causes pk11_library_initialized to stay 1. In
2061 +        * that case we need the PID check so that we properly
2062 +        * initialize the engine again.
2063 +        */
2064 +       if (pk11_library_initialized)
2065 +               {
2066 +               if (pk11_pid == getpid())
2067 +                       {
2068 +                       return (1);
2069 +                       }
2070 +               else
2071 +                       {
2072 +                       global_session = CK_INVALID_HANDLE;
2073 +                       /*
2074 +                        * free the locks first to prevent memory leak in case
2075 +                        * the application calls fork() without finishing the
2076 +                        * engine first.
2077 +                        */
2078 +                       pk11_free_all_locks();
2079 +                       }
2080 +               }
2082 +       if (pk11_dso == NULL)
2083 +               {
2084 +               PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
2085 +               goto err;
2086 +               }
2088 +#ifdef SOLARIS_AES_CTR
2089 +       /*
2090 +        * We must do this before we start working with slots since we need all
2091 +        * NIDs there.
2092 +        */
2093 +       if (pk11_add_aes_ctr_NIDs() == 0)
2094 +               goto err;
2095 +#endif /* SOLARIS_AES_CTR */
2097 +#ifdef SOLARIS_HW_SLOT_SELECTION
2098 +       if (check_hw_mechanisms() == 0)
2099 +               goto err;
2100 +#endif /* SOLARIS_HW_SLOT_SELECTION */
2102 +       /* get the C_GetFunctionList function from the loaded library */
2103 +       p = (CK_C_GetFunctionList)DSO_bind_func(pk11_dso,
2104 +               PK11_GET_FUNCTION_LIST);
2105 +       if (!p)
2106 +               {
2107 +               PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
2108 +               goto err;
2109 +               }
2111 +       /* get the full function list from the loaded library */
2112 +       rv = p(&pFuncList);
2113 +       if (rv != CKR_OK)
2114 +               {
2115 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE, rv);
2116 +               goto err;
2117 +               }
2119 +#ifndef OPENSSL_SYS_WIN32
2120 +       /* Not all PKCS#11 library are signal safe! */
2122 +       (void) memset(&sigint_act, 0, sizeof(sigint_act));
2123 +       (void) memset(&sigterm_act, 0, sizeof(sigterm_act));
2124 +       (void) memset(&sighup_act, 0, sizeof(sighup_act));
2125 +       (void) sigaction(SIGINT, NULL, &sigint_act);
2126 +       (void) sigaction(SIGTERM, NULL, &sigterm_act);
2127 +       (void) sigaction(SIGHUP, NULL, &sighup_act);
2128 +#endif
2129 +       rv = pFuncList->C_Initialize((CK_VOID_PTR)&pk11_init_args);
2130 +#ifndef OPENSSL_SYS_WIN32
2131 +       (void) sigaction(SIGINT, &sigint_act, NULL);
2132 +       (void) sigaction(SIGTERM, &sigterm_act, NULL);
2133 +       (void) sigaction(SIGHUP, &sighup_act, NULL);
2134 +#endif
2135 +       if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
2136 +               {
2137 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_INITIALIZE, rv);
2138 +               goto err;
2139 +               }
2141 +       rv = pFuncList->C_GetInfo(&info);
2142 +       if (rv != CKR_OK)
2143 +               {
2144 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_GETINFO, rv);
2145 +               goto err;
2146 +               }
2148 +       if (pk11_choose_slots(&any_slot_found) == 0)
2149 +               goto err;
2151 +       /*
2152 +        * The library we use, set in def_PK11_LIBNAME, may not offer any
2153 +        * slot(s). In that case, we must not proceed but we must not return an
2154 +        * error. The reason is that applications that try to set up the PKCS#11
2155 +        * engine don't exit on error during the engine initialization just
2156 +        * because no slot was present.
2157 +        */
2158 +       if (any_slot_found == 0)
2159 +               return (1);
2161 +       if (global_session == CK_INVALID_HANDLE)
2162 +               {
2163 +               /* Open the global_session for the new process */
2164 +               rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
2165 +                       NULL_PTR, NULL_PTR, &global_session);
2166 +               if (rv != CKR_OK)
2167 +                       {
2168 +                       PK11err_add_data(PK11_F_LIBRARY_INIT,
2169 +                           PK11_R_OPENSESSION, rv);
2170 +                       goto err;
2171 +                       }
2172 +               }
2174 +       /*
2175 +        * Disable digest if C_GetOperationState is not supported since
2176 +        * this function is required by OpenSSL digest copy function
2177 +        */
2178 +       /* Keyper fails to return CKR_FUNCTION_NOT_SUPPORTED */
2179 +       if (pFuncList->C_GetOperationState(global_session, NULL, &ul_state_len)
2180 +                       != CKR_OK) {
2181 +#ifdef DEBUG_SLOT_SELECTION
2182 +               fprintf(stderr, "%s: C_GetOperationState() not supported, "
2183 +                   "setting digest_count to 0\n", PK11_DBG);
2184 +#endif /* DEBUG_SLOT_SELECTION */
2185 +               digest_count = 0;
2186 +       }
2188 +       pk11_library_initialized = TRUE;
2189 +       pk11_pid = getpid();
2190 +       /*
2191 +        * if initialization of the locks fails pk11_init_all_locks()
2192 +        * will do the cleanup.
2193 +        */
2194 +       if (!pk11_init_all_locks())
2195 +               goto err;
2196 +       for (i = 0; i < OP_MAX; i++)
2197 +               session_cache[i].head = NULL;
2198 +       /*
2199 +        * initialize active lists. We only use active lists
2200 +        * for asymmetric ciphers.
2201 +        */
2202 +       for (i = 0; i < OP_MAX; i++)
2203 +               active_list[i] = NULL;
2205 +#ifndef NOPTHREADS
2206 +       if (!pk11_atfork_initialized)
2207 +               {
2208 +               if (pthread_atfork(pk11_fork_prepare, pk11_fork_parent,
2209 +                   pk11_fork_child) != 0)
2210 +                       {
2211 +                       PK11err(PK11_F_LIBRARY_INIT, PK11_R_ATFORK_FAILED);
2212 +                       goto err;
2213 +                       }
2214 +               pk11_atfork_initialized = TRUE;
2215 +               }
2216 +#endif
2218 +       return (1);
2220 +err:
2221 +       return (0);
2222 +       }
2224 +/* Destructor (complements the "ENGINE_pk11()" constructor) */
2225 +/* ARGSUSED */
2226 +static int pk11_destroy(ENGINE *e)
2227 +       {
2228 +       free_PK11_LIBNAME();
2229 +       ERR_unload_pk11_strings();
2230 +       if (pk11_pin) {
2231 +               memset(pk11_pin, 0, strlen(pk11_pin));
2232 +               OPENSSL_free((void*)pk11_pin);
2233 +       }
2234 +       pk11_pin = NULL;
2235 +       return (1);
2236 +       }
2239 + * Termination function to clean up the session, the token, and the pk11
2240 + * library.
2241 + */
2242 +/* ARGSUSED */
2243 +static int pk11_finish(ENGINE *e)
2244 +       {
2245 +       int i;
2247 +       if (pk11_pin) {
2248 +               memset(pk11_pin, 0, strlen(pk11_pin));
2249 +               OPENSSL_free((void*)pk11_pin);
2250 +       }
2251 +       pk11_pin = NULL;
2253 +       if (pk11_dso == NULL)
2254 +               {
2255 +               PK11err(PK11_F_FINISH, PK11_R_NOT_LOADED);
2256 +               goto err;
2257 +               }
2259 +       OPENSSL_assert(pFuncList != NULL);
2261 +       if (pk11_free_all_sessions() == 0)
2262 +               goto err;
2264 +       /* free all active lists */
2265 +       for (i = 0; i < OP_MAX; i++)
2266 +               pk11_free_active_list(i);
2268 +       pFuncList->C_CloseSession(global_session);
2269 +       global_session = CK_INVALID_HANDLE;
2271 +       /*
2272 +        * Since we are part of a library (libcrypto.so), calling this function
2273 +        * may have side-effects.
2274 +        */
2275 +#if 0
2276 +       pFuncList->C_Finalize(NULL);
2277 +#endif
2279 +       if (!DSO_free(pk11_dso))
2280 +               {
2281 +               PK11err(PK11_F_FINISH, PK11_R_DSO_FAILURE);
2282 +               goto err;
2283 +               }
2284 +       pk11_dso = NULL;
2285 +       pFuncList = NULL;
2286 +       pk11_library_initialized = FALSE;
2287 +       pk11_pid = 0;
2288 +       /*
2289 +        * There is no way how to unregister atfork handlers (other than
2290 +        * unloading the library) so we just free the locks. For this reason
2291 +        * the atfork handlers check if the engine is initialized and bail out
2292 +        * immediately if not. This is necessary in case a process finishes
2293 +        * the engine before calling fork().
2294 +        */
2295 +       pk11_free_all_locks();
2297 +       return (1);
2299 +err:
2300 +       return (0);
2301 +       }
2303 +/* Standard engine interface function to set the dynamic library path */
2304 +/* ARGSUSED */
2305 +static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
2306 +       {
2307 +       int initialized = ((pk11_dso == NULL) ? 0 : 1);
2309 +       switch (cmd)
2310 +               {
2311 +       case PK11_CMD_SO_PATH:
2312 +               if (p == NULL)
2313 +                       {
2314 +                       PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
2315 +                       return (0);
2316 +                       }
2318 +               if (initialized)
2319 +                       {
2320 +                       PK11err(PK11_F_CTRL, PK11_R_ALREADY_LOADED);
2321 +                       return (0);
2322 +                       }
2324 +               return (set_PK11_LIBNAME((const char *)p));
2325 +       case PK11_CMD_PIN:
2326 +               if (pk11_pin) {
2327 +                       memset(pk11_pin, 0, strlen(pk11_pin));
2328 +                       OPENSSL_free((void*)pk11_pin);
2329 +               }
2330 +               pk11_pin = NULL;
2332 +               if (p == NULL)
2333 +                       {
2334 +                       PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
2335 +                       return (0);
2336 +                       }
2338 +               pk11_pin = BUF_strdup(p);
2339 +               if (pk11_pin == NULL)
2340 +                       {
2341 +                       PK11err(PK11_F_GET_SESSION, PK11_R_MALLOC_FAILURE);
2342 +                       return (0);
2343 +                       }
2344 +               return (1);
2345 +       case PK11_CMD_SLOT:
2346 +               SLOTID = (CK_SLOT_ID)i;
2347 +#ifdef DEBUG_SLOT_SELECTION
2348 +               fprintf(stderr, "%s: slot set\n", PK11_DBG);
2349 +#endif
2350 +               return (1);
2351 +       default:
2352 +               break;
2353 +               }
2355 +       PK11err(PK11_F_CTRL, PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED);
2357 +       return (0);
2358 +       }
2361 +/* Required function by the engine random interface. It does nothing here */
2362 +static void pk11_rand_cleanup(void)
2363 +       {
2364 +       return;
2365 +       }
2367 +/* ARGSUSED */
2368 +static void pk11_rand_add(const void *buf, int num, double add)
2369 +       {
2370 +       PK11_SESSION *sp;
2372 +       if ((sp = pk11_get_session(OP_RAND)) == NULL)
2373 +               return;
2375 +       /*
2376 +        * Ignore any errors (e.g. CKR_RANDOM_SEED_NOT_SUPPORTED) since
2377 +        * the calling functions do not care anyway
2378 +        */
2379 +       pFuncList->C_SeedRandom(sp->session, (unsigned char *) buf, num);
2380 +       pk11_return_session(sp, OP_RAND);
2382 +       return;
2383 +       }
2385 +static void pk11_rand_seed(const void *buf, int num)
2386 +       {
2387 +       pk11_rand_add(buf, num, 0);
2388 +       }
2390 +static int pk11_rand_bytes(unsigned char *buf, int num)
2391 +       {
2392 +       CK_RV rv;
2393 +       PK11_SESSION *sp;
2395 +       if ((sp = pk11_get_session(OP_RAND)) == NULL)
2396 +               return (0);
2398 +       rv = pFuncList->C_GenerateRandom(sp->session, buf, num);
2399 +       if (rv != CKR_OK)
2400 +               {
2401 +               PK11err_add_data(PK11_F_RAND_BYTES, PK11_R_GENERATERANDOM, rv);
2402 +               pk11_return_session(sp, OP_RAND);
2403 +               return (0);
2404 +               }
2406 +       pk11_return_session(sp, OP_RAND);
2407 +       return (1);
2408 +       }
2410 +/* Required function by the engine random interface. It does nothing here */
2411 +static int pk11_rand_status(void)
2412 +       {
2413 +       return (1);
2414 +       }
2416 +/* Free all BIGNUM structures from PK11_SESSION. */
2417 +static void pk11_free_nums(PK11_SESSION *sp, PK11_OPTYPE optype)
2418 +       {
2419 +       switch (optype)
2420 +               {
2421 +#ifndef        OPENSSL_NO_RSA
2422 +               case OP_RSA:
2423 +                       if (sp->opdata_rsa_n_num != NULL)
2424 +                               {
2425 +                               BN_free(sp->opdata_rsa_n_num);
2426 +                               sp->opdata_rsa_n_num = NULL;
2427 +                               }
2428 +                       if (sp->opdata_rsa_e_num != NULL)
2429 +                               {
2430 +                               BN_free(sp->opdata_rsa_e_num);
2431 +                               sp->opdata_rsa_e_num = NULL;
2432 +                               }
2433 +                       if (sp->opdata_rsa_pn_num != NULL)
2434 +                               {
2435 +                               BN_free(sp->opdata_rsa_pn_num);
2436 +                               sp->opdata_rsa_pn_num = NULL;
2437 +                               }
2438 +                       if (sp->opdata_rsa_pe_num != NULL)
2439 +                               {
2440 +                               BN_free(sp->opdata_rsa_pe_num);
2441 +                               sp->opdata_rsa_pe_num = NULL;
2442 +                               }
2443 +                       if (sp->opdata_rsa_d_num != NULL)
2444 +                               {
2445 +                               BN_free(sp->opdata_rsa_d_num);
2446 +                               sp->opdata_rsa_d_num = NULL;
2447 +                               }
2448 +                       break;
2449 +#endif
2450 +#ifndef        OPENSSL_NO_DSA
2451 +               case OP_DSA:
2452 +                       if (sp->opdata_dsa_pub_num != NULL)
2453 +                               {
2454 +                               BN_free(sp->opdata_dsa_pub_num);
2455 +                               sp->opdata_dsa_pub_num = NULL;
2456 +                               }
2457 +                       if (sp->opdata_dsa_priv_num != NULL)
2458 +                               {
2459 +                               BN_free(sp->opdata_dsa_priv_num);
2460 +                               sp->opdata_dsa_priv_num = NULL;
2461 +                               }
2462 +                       break;
2463 +#endif
2464 +#ifndef        OPENSSL_NO_DH
2465 +               case OP_DH:
2466 +                       if (sp->opdata_dh_priv_num != NULL)
2467 +                               {
2468 +                               BN_free(sp->opdata_dh_priv_num);
2469 +                               sp->opdata_dh_priv_num = NULL;
2470 +                               }
2471 +                       break;
2472 +#endif
2473 +               default:
2474 +                       break;
2475 +               }
2476 +       }
2479 + * Get new PK11_SESSION structure ready for use. Every process must have
2480 + * its own freelist of PK11_SESSION structures so handle fork() here
2481 + * by destroying the old and creating new freelist.
2482 + * The returned PK11_SESSION structure is disconnected from the freelist.
2483 + */
2484 +PK11_SESSION *
2485 +pk11_get_session(PK11_OPTYPE optype)
2486 +       {
2487 +       PK11_SESSION *sp = NULL, *sp1, *freelist;
2488 +#ifndef NOPTHREADS
2489 +       pthread_mutex_t *freelist_lock = NULL;
2490 +#endif
2491 +       static pid_t pid = 0;
2492 +       pid_t new_pid;
2493 +       CK_RV rv;
2495 +       switch (optype)
2496 +               {
2497 +               case OP_RSA:
2498 +               case OP_DSA:
2499 +               case OP_DH:
2500 +               case OP_RAND:
2501 +               case OP_DIGEST:
2502 +               case OP_CIPHER:
2503 +#ifndef NOPTHREADS
2504 +                       freelist_lock = session_cache[optype].lock;
2505 +#endif
2506 +                       break;
2507 +               default:
2508 +                       PK11err(PK11_F_GET_SESSION,
2509 +                               PK11_R_INVALID_OPERATION_TYPE);
2510 +                       return (NULL);
2511 +               }
2512 +#ifndef NOPTHREADS
2513 +       OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
2514 +#else
2515 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
2516 +#endif
2518 +       /*
2519 +        * Will use it to find out if we forked. We cannot use the PID field in
2520 +        * the session structure because we could get a newly allocated session
2521 +        * here, with no PID information.
2522 +        */
2523 +       if (pid == 0)
2524 +               pid = getpid();
2526 +       freelist = session_cache[optype].head;
2527 +       sp = freelist;
2529 +       /*
2530 +        * If the free list is empty, allocate new unitialized (filled
2531 +        * with zeroes) PK11_SESSION structure otherwise return first
2532 +        * structure from the freelist.
2533 +        */
2534 +       if (sp == NULL)
2535 +               {
2536 +               if ((sp = OPENSSL_malloc(sizeof (PK11_SESSION))) == NULL)
2537 +                       {
2538 +                       PK11err(PK11_F_GET_SESSION,
2539 +                               PK11_R_MALLOC_FAILURE);
2540 +                       goto err;
2541 +                       }
2542 +               (void) memset(sp, 0, sizeof (PK11_SESSION));
2544 +               /*
2545 +                * It is a new session so it will look like a cache miss to the
2546 +                * code below. So, we must not try to to destroy its members so
2547 +                * mark them as unused.
2548 +                */
2549 +               sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
2550 +               sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
2551 +               }
2552 +       else
2553 +               {
2554 +               freelist = sp->next;
2555 +               }
2557 +       /*
2558 +        * Check whether we have forked. In that case, we must get rid of all
2559 +        * inherited sessions and start allocating new ones.
2560 +        */
2561 +       if (pid != (new_pid = getpid()))
2562 +               {
2563 +               pid = new_pid;
2565 +               /*
2566 +                * We are a new process and thus need to free any inherited
2567 +                * PK11_SESSION objects aside from the first session (sp) which
2568 +                * is the only PK11_SESSION structure we will reuse (for the
2569 +                * head of the list).
2570 +                */
2571 +               while ((sp1 = freelist) != NULL)
2572 +                       {
2573 +                       freelist = sp1->next;
2574 +                       /*
2575 +                        * NOTE: we do not want to call pk11_free_all_sessions()
2576 +                        * here because it would close underlying PKCS#11
2577 +                        * sessions and destroy all objects.
2578 +                        */
2579 +                       pk11_free_nums(sp1, optype);
2580 +                       OPENSSL_free(sp1);
2581 +                       }
2583 +               /* we have to free the active list as well. */
2584 +               pk11_free_active_list(optype);
2586 +               /* Initialize the process */
2587 +               rv = pFuncList->C_Initialize((CK_VOID_PTR)&pk11_init_args);
2588 +               if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
2589 +                       {
2590 +                       PK11err_add_data(PK11_F_GET_SESSION, PK11_R_INITIALIZE,
2591 +                           rv);
2592 +                       OPENSSL_free(sp);
2593 +                       sp = NULL;
2594 +                       goto err;
2595 +                       }
2597 +               /*
2598 +                * Choose slot here since the slot table is different on this
2599 +                * process. If we are here then we must have found at least one
2600 +                * usable slot before so we don't need to check any_slot_found.
2601 +                * See pk11_library_init()'s usage of this function for more
2602 +                * information.
2603 +                */
2604 +#ifdef SOLARIS_HW_SLOT_SELECTION
2605 +               if (check_hw_mechanisms() == 0)
2606 +                       goto err;
2607 +#endif /* SOLARIS_HW_SLOT_SELECTION */
2608 +               if (pk11_choose_slots(NULL) == 0)
2609 +                       goto err;
2611 +               /* Open the global_session for the new process */
2612 +               rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
2613 +                       NULL_PTR, NULL_PTR, &global_session);
2614 +               if (rv != CKR_OK)
2615 +                       {
2616 +                       PK11err_add_data(PK11_F_GET_SESSION, PK11_R_OPENSESSION,
2617 +                           rv);
2618 +                       OPENSSL_free(sp);
2619 +                       sp = NULL;
2620 +                       goto err;
2621 +                       }
2623 +               /*
2624 +                * It is an inherited session from our parent so it needs
2625 +                * re-initialization.
2626 +                */
2627 +               if (pk11_setup_session(sp, optype) == 0)
2628 +                       {
2629 +                       OPENSSL_free(sp);
2630 +                       sp = NULL;
2631 +                       goto err;
2632 +                       }
2633 +               if (pk11_token_relogin(sp->session) == 0) 
2634 +                       {
2635 +                       /*
2636 +                        * We will keep the session in the cache list and let
2637 +                        * the caller cope with the situation.
2638 +                        */
2639 +                       freelist = sp;
2640 +                       sp = NULL;
2641 +                       goto err;
2642 +                       }
2643 +               }
2645 +       if (sp->pid == 0)
2646 +               {
2647 +               /* It is a new session and needs initialization. */
2648 +               if (pk11_setup_session(sp, optype) == 0)
2649 +                       {
2650 +                       OPENSSL_free(sp);
2651 +                       sp = NULL;
2652 +                       }
2653 +               }
2655 +       /* set new head for the list of PK11_SESSION objects */
2656 +       session_cache[optype].head = freelist;
2658 +err:
2659 +       if (sp != NULL)
2660 +               sp->next = NULL;
2662 +#ifndef NOPTHREADS
2663 +       OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
2664 +#else
2665 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
2666 +#endif
2668 +       return (sp);
2669 +       }
2672 +void
2673 +pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype)
2674 +       {
2675 +#ifndef NOPTHREADS
2676 +       pthread_mutex_t *freelist_lock;
2677 +#endif
2678 +       PK11_SESSION *freelist;
2680 +       /*
2681 +        * If this is a session from the parent it will be taken care of and
2682 +        * freed in pk11_get_session() as part of the post-fork clean up the
2683 +        * next time we will ask for a new session.
2684 +        */
2685 +       if (sp == NULL || sp->pid != getpid())
2686 +               return;
2688 +       switch (optype)
2689 +               {
2690 +               case OP_RSA:
2691 +               case OP_DSA:
2692 +               case OP_DH:
2693 +               case OP_RAND:
2694 +               case OP_DIGEST:
2695 +               case OP_CIPHER:
2696 +#ifndef NOPTHREADS
2697 +                       freelist_lock = session_cache[optype].lock;
2698 +#endif
2699 +                       break;
2700 +               default:
2701 +                       PK11err(PK11_F_RETURN_SESSION,
2702 +                               PK11_R_INVALID_OPERATION_TYPE);
2703 +                       return;
2704 +               }
2706 +#ifndef NOPTHREADS
2707 +       OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
2708 +#else
2709 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
2710 +#endif
2711 +       freelist = session_cache[optype].head;
2712 +       sp->next = freelist;
2713 +       session_cache[optype].head = sp;
2714 +#ifndef NOPTHREADS
2715 +       OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
2716 +#else
2717 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
2718 +#endif
2719 +       }
2722 +/* Destroy all objects. This function is called when the engine is finished */
2723 +static int pk11_free_all_sessions()
2724 +       {
2725 +       int ret = 1;
2726 +       int type;
2728 +#ifndef OPENSSL_NO_RSA
2729 +       (void) pk11_destroy_rsa_key_objects(NULL);
2730 +#endif /* OPENSSL_NO_RSA */
2731 +#ifndef OPENSSL_NO_DSA
2732 +       (void) pk11_destroy_dsa_key_objects(NULL);
2733 +#endif /* OPENSSL_NO_DSA */
2734 +#ifndef OPENSSL_NO_DH
2735 +       (void) pk11_destroy_dh_key_objects(NULL);
2736 +#endif /* OPENSSL_NO_DH */
2737 +       (void) pk11_destroy_cipher_key_objects(NULL);
2739 +       /*
2740 +        * We try to release as much as we can but any error means that we will
2741 +        * return 0 on exit.
2742 +        */
2743 +       for (type = 0; type < OP_MAX; type++)
2744 +               {
2745 +               if (pk11_free_session_list(type) == 0)
2746 +                       ret = 0;
2747 +               }
2749 +       return (ret);
2750 +       }
2753 + * Destroy session structures from the linked list specified. Free as many
2754 + * sessions as possible but any failure in C_CloseSession() means that we
2755 + * return an error on return.
2756 + */
2757 +static int pk11_free_session_list(PK11_OPTYPE optype)
2758 +       {
2759 +       CK_RV rv;
2760 +       PK11_SESSION *sp = NULL;
2761 +       PK11_SESSION *freelist = NULL;
2762 +       pid_t mypid = getpid();
2763 +#ifndef NOPTHREADS
2764 +       pthread_mutex_t *freelist_lock;
2765 +#endif
2766 +       int ret = 1;
2768 +       switch (optype)
2769 +               {
2770 +               case OP_RSA:
2771 +               case OP_DSA:
2772 +               case OP_DH:
2773 +               case OP_RAND:
2774 +               case OP_DIGEST:
2775 +               case OP_CIPHER:
2776 +#ifndef NOPTHREADS
2777 +                       freelist_lock = session_cache[optype].lock;
2778 +#endif
2779 +                       break;
2780 +               default:
2781 +                       PK11err(PK11_F_FREE_ALL_SESSIONS,
2782 +                               PK11_R_INVALID_OPERATION_TYPE);
2783 +                       return (0);
2784 +               }
2786 +#ifndef NOPTHREADS
2787 +       OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
2788 +#else
2789 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
2790 +#endif
2791 +       freelist = session_cache[optype].head;
2792 +       while ((sp = freelist) != NULL)
2793 +               {
2794 +               if (sp->session != CK_INVALID_HANDLE && sp->pid == mypid)
2795 +                       {
2796 +                       rv = pFuncList->C_CloseSession(sp->session);
2797 +                       if (rv != CKR_OK)
2798 +                               {
2799 +                               PK11err_add_data(PK11_F_FREE_ALL_SESSIONS,
2800 +                                       PK11_R_CLOSESESSION, rv);
2801 +                               ret = 0;
2802 +                               }
2803 +                       }
2804 +               freelist = sp->next;
2805 +               pk11_free_nums(sp, optype);
2806 +               OPENSSL_free(sp);
2807 +               }
2809 +#ifndef NOPTHREADS
2810 +       OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
2811 +#else
2812 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
2813 +#endif
2814 +       return (ret);
2815 +       }
2818 +static int
2819 +pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype)
2820 +       {
2821 +       CK_RV rv;
2822 +       CK_SLOT_ID myslot;
2824 +       switch (optype)
2825 +               {
2826 +               case OP_RSA:
2827 +               case OP_DSA:
2828 +               case OP_DH:
2829 +                       myslot = pubkey_SLOTID;
2830 +                       break;
2831 +               case OP_RAND:
2832 +                       myslot = rand_SLOTID;
2833 +                       break;
2834 +               case OP_DIGEST:
2835 +               case OP_CIPHER:
2836 +                       myslot = SLOTID;
2837 +                       break;
2838 +               default:
2839 +                       PK11err(PK11_F_SETUP_SESSION,
2840 +                           PK11_R_INVALID_OPERATION_TYPE);
2841 +                       return (0);
2842 +               }
2844 +       sp->session = CK_INVALID_HANDLE;
2845 +#ifdef DEBUG_SLOT_SELECTION
2846 +       fprintf(stderr, "%s: myslot=%d optype=%d\n", PK11_DBG, myslot, optype);
2847 +#endif /* DEBUG_SLOT_SELECTION */
2848 +       rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
2849 +               NULL_PTR, NULL_PTR, &sp->session);
2850 +       if (rv == CKR_CRYPTOKI_NOT_INITIALIZED)
2851 +               {
2852 +               /*
2853 +                * We are probably a child process so force the
2854 +                * reinitialize of the session
2855 +                */
2856 +               pk11_library_initialized = FALSE;
2857 +               if (!pk11_library_init(NULL))
2858 +                       return (0);
2859 +               rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
2860 +                       NULL_PTR, NULL_PTR, &sp->session);
2861 +               }
2862 +       if (rv != CKR_OK)
2863 +               {
2864 +               PK11err_add_data(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION, rv);
2865 +               return (0);
2866 +               }
2868 +       sp->pid = getpid();
2870 +       switch (optype)
2871 +               {
2872 +#ifndef OPENSSL_NO_RSA
2873 +               case OP_RSA:
2874 +                       sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
2875 +                       sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
2876 +                       sp->opdata_rsa_pub = NULL;
2877 +                       sp->opdata_rsa_n_num = NULL;
2878 +                       sp->opdata_rsa_e_num = NULL;
2879 +                       sp->opdata_rsa_priv = NULL;
2880 +                       sp->opdata_rsa_pn_num = NULL;
2881 +                       sp->opdata_rsa_pe_num = NULL;
2882 +                       sp->opdata_rsa_d_num = NULL;
2883 +                       break;
2884 +#endif /* OPENSSL_NO_RSA */
2885 +#ifndef OPENSSL_NO_DSA
2886 +               case OP_DSA:
2887 +                       sp->opdata_dsa_pub_key = CK_INVALID_HANDLE;
2888 +                       sp->opdata_dsa_priv_key = CK_INVALID_HANDLE;
2889 +                       sp->opdata_dsa_pub = NULL;
2890 +                       sp->opdata_dsa_pub_num = NULL;
2891 +                       sp->opdata_dsa_priv = NULL;
2892 +                       sp->opdata_dsa_priv_num = NULL;
2893 +                       break;
2894 +#endif /* OPENSSL_NO_DSA */
2895 +#ifndef OPENSSL_NO_DH
2896 +               case OP_DH:
2897 +                       sp->opdata_dh_key = CK_INVALID_HANDLE;
2898 +                       sp->opdata_dh = NULL;
2899 +                       sp->opdata_dh_priv_num = NULL;
2900 +                       break;
2901 +#endif /* OPENSSL_NO_DH */
2902 +               case OP_CIPHER:
2903 +                       sp->opdata_cipher_key = CK_INVALID_HANDLE;
2904 +                       sp->opdata_encrypt = -1;
2905 +                       break;
2906 +               default:
2907 +                       break;
2908 +               }
2910 +       /*
2911 +        * We always initialize the session as containing a non-persistent
2912 +        * object. The key load functions set it to persistent if that is so.
2913 +        */
2914 +       sp->pub_persistent = CK_FALSE;
2915 +       sp->priv_persistent = CK_FALSE;
2916 +       return (1);
2917 +       }
2919 +#ifndef OPENSSL_NO_RSA
2920 +/* Destroy RSA public key from single session. */
2921 +int
2922 +pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
2923 +       {
2924 +       int ret = 0;
2926 +       if (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE)
2927 +               {
2928 +               TRY_OBJ_DESTROY(sp, sp->opdata_rsa_pub_key,
2929 +                   ret, uselock, OP_RSA, CK_FALSE);
2930 +               sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
2931 +               sp->opdata_rsa_pub = NULL;
2932 +               if (sp->opdata_rsa_n_num != NULL)
2933 +                       {
2934 +                       BN_free(sp->opdata_rsa_n_num);
2935 +                       sp->opdata_rsa_n_num = NULL;
2936 +                       }
2937 +               if (sp->opdata_rsa_e_num != NULL)
2938 +                       {
2939 +                       BN_free(sp->opdata_rsa_e_num);
2940 +                       sp->opdata_rsa_e_num = NULL;
2941 +                       }
2942 +               }
2944 +       return (ret);
2945 +       }
2947 +/* Destroy RSA private key from single session. */
2948 +int
2949 +pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
2950 +       {
2951 +       int ret = 0;
2953 +       if (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE)
2954 +               {
2955 +               TRY_OBJ_DESTROY(sp, sp->opdata_rsa_priv_key,
2956 +                   ret, uselock, OP_RSA, CK_TRUE);
2957 +               sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
2958 +               sp->opdata_rsa_priv = NULL;
2959 +               if (sp->opdata_rsa_d_num != NULL)
2960 +                       {
2961 +                       BN_free(sp->opdata_rsa_d_num);
2962 +                       sp->opdata_rsa_d_num = NULL;
2963 +                       }
2965 +               /*
2966 +                * For the RSA key by reference code, public components 'n'/'e'
2967 +                * are the key components we use to check for the cache hit. We
2968 +                * must free those as well.
2969 +                */
2970 +               if (sp->opdata_rsa_pn_num != NULL)
2971 +                       {
2972 +                       BN_free(sp->opdata_rsa_pn_num);
2973 +                       sp->opdata_rsa_pn_num = NULL;
2974 +                       }
2975 +               if (sp->opdata_rsa_pe_num != NULL)
2976 +                       {
2977 +                       BN_free(sp->opdata_rsa_pe_num);
2978 +                       sp->opdata_rsa_pe_num = NULL;
2979 +                       }
2980 +               }
2982 +       return (ret);
2983 +       }
2986 + * Destroy RSA key object wrapper. If session is NULL, try to destroy all
2987 + * objects in the free list.
2988 + */
2989 +int
2990 +pk11_destroy_rsa_key_objects(PK11_SESSION *session)
2991 +       {
2992 +       int ret = 1;
2993 +       PK11_SESSION *sp = NULL;
2994 +       PK11_SESSION *local_free_session;
2995 +       CK_BBOOL uselock = TRUE;
2997 +       if (session != NULL)
2998 +               local_free_session = session;
2999 +       else
3000 +               {
3001 +#ifndef NOPTHREADS
3002 +               OPENSSL_assert(pthread_mutex_lock(session_cache[OP_RSA].lock) == 0);
3003 +#else
3004 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
3005 +#endif
3006 +               local_free_session = session_cache[OP_RSA].head;
3007 +               uselock = FALSE;
3008 +               }
3010 +       /*
3011 +        * go through the list of sessions and delete key objects
3012 +        */
3013 +       while ((sp = local_free_session) != NULL)
3014 +               {
3015 +               local_free_session = sp->next;
3017 +               /*
3018 +                * Do not terminate list traversal if one of the
3019 +                * destroy operations fails.
3020 +                */
3021 +               if (pk11_destroy_rsa_object_pub(sp, uselock) == 0)
3022 +                       {
3023 +                       ret = 0;
3024 +                       continue;
3025 +                       }
3026 +               if (pk11_destroy_rsa_object_priv(sp, uselock) == 0)
3027 +                       {
3028 +                       ret = 0;
3029 +                       continue;
3030 +                       }
3031 +               }
3033 +#ifndef NOPTHREADS
3034 +       if (session == NULL)
3035 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[OP_RSA].lock) == 0);
3036 +#else
3037 +       if (session == NULL)
3038 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
3039 +#endif
3041 +       return (ret);
3042 +       }
3043 +#endif /* OPENSSL_NO_RSA */
3045 +#ifndef OPENSSL_NO_DSA
3046 +/* Destroy DSA public key from single session. */
3047 +int
3048 +pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
3049 +       {
3050 +       int ret = 0;
3052 +       if (sp->opdata_dsa_pub_key != CK_INVALID_HANDLE)
3053 +               {
3054 +               TRY_OBJ_DESTROY(sp, sp->opdata_dsa_pub_key,
3055 +                   ret, uselock, OP_DSA, CK_FALSE);
3056 +               sp->opdata_dsa_pub_key = CK_INVALID_HANDLE;
3057 +               sp->opdata_dsa_pub = NULL;
3058 +               if (sp->opdata_dsa_pub_num != NULL)
3059 +                       {
3060 +                       BN_free(sp->opdata_dsa_pub_num);
3061 +                       sp->opdata_dsa_pub_num = NULL;
3062 +                       }
3063 +               }
3065 +       return (ret);
3066 +       }
3068 +/* Destroy DSA private key from single session. */
3069 +int
3070 +pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
3071 +       {
3072 +       int ret = 0;
3074 +       if (sp->opdata_dsa_priv_key != CK_INVALID_HANDLE)
3075 +               {
3076 +               TRY_OBJ_DESTROY(sp, sp->opdata_dsa_priv_key,
3077 +                   ret, uselock, OP_DSA, CK_TRUE);
3078 +               sp->opdata_dsa_priv_key = CK_INVALID_HANDLE;
3079 +               sp->opdata_dsa_priv = NULL;
3080 +               if (sp->opdata_dsa_priv_num != NULL)
3081 +                       {
3082 +                       BN_free(sp->opdata_dsa_priv_num);
3083 +                       sp->opdata_dsa_priv_num = NULL;
3084 +                       }
3085 +               }
3087 +       return (ret);
3088 +       }
3091 + * Destroy DSA key object wrapper. If session is NULL, try to destroy all
3092 + * objects in the free list.
3093 + */
3094 +int
3095 +pk11_destroy_dsa_key_objects(PK11_SESSION *session)
3096 +       {
3097 +       int ret = 1;
3098 +       PK11_SESSION *sp = NULL;
3099 +       PK11_SESSION *local_free_session;
3100 +       CK_BBOOL uselock = TRUE;
3102 +       if (session != NULL)
3103 +               local_free_session = session;
3104 +       else
3105 +               {
3106 +#ifndef NOPTHREADS
3107 +               OPENSSL_assert(pthread_mutex_lock(session_cache[OP_DSA].lock) == 0);
3108 +#else
3109 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
3110 +#endif
3111 +               local_free_session = session_cache[OP_DSA].head;
3112 +               uselock = FALSE;
3113 +               }
3115 +       /*
3116 +        * go through the list of sessions and delete key objects
3117 +        */
3118 +       while ((sp = local_free_session) != NULL)
3119 +               {
3120 +               local_free_session = sp->next;
3122 +               /*
3123 +                * Do not terminate list traversal if one of the
3124 +                * destroy operations fails.
3125 +                */
3126 +               if (pk11_destroy_dsa_object_pub(sp, uselock) == 0)
3127 +                       {
3128 +                       ret = 0;
3129 +                       continue;
3130 +                       }
3131 +               if (pk11_destroy_dsa_object_priv(sp, uselock) == 0)
3132 +                       {
3133 +                       ret = 0;
3134 +                       continue;
3135 +                       }
3136 +               }
3138 +#ifndef NOPTHREADS
3139 +       if (session == NULL)
3140 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[OP_DSA].lock) == 0);
3141 +#else
3142 +       if (session == NULL)
3143 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
3144 +#endif
3146 +       return (ret);
3147 +       }
3148 +#endif /* OPENSSL_NO_DSA */
3150 +#ifndef OPENSSL_NO_DH
3151 +/* Destroy DH key from single session. */
3152 +int
3153 +pk11_destroy_dh_object(PK11_SESSION *sp, CK_BBOOL uselock)
3154 +       {
3155 +       int ret = 0;
3157 +       if (sp->opdata_dh_key != CK_INVALID_HANDLE)
3158 +               {
3159 +               TRY_OBJ_DESTROY(sp, sp->opdata_dh_key,
3160 +                   ret, uselock, OP_DH, CK_TRUE);
3161 +               sp->opdata_dh_key = CK_INVALID_HANDLE;
3162 +               sp->opdata_dh = NULL;
3163 +               if (sp->opdata_dh_priv_num != NULL)
3164 +                       {
3165 +                       BN_free(sp->opdata_dh_priv_num);
3166 +                       sp->opdata_dh_priv_num = NULL;
3167 +                       }
3168 +               }
3170 +       return (ret);
3171 +       }
3174 + * Destroy DH key object wrapper.
3175 + *
3176 + * arg0: pointer to PKCS#11 engine session structure
3177 + *       if session is NULL, try to destroy all objects in the free list
3178 + */
3179 +int
3180 +pk11_destroy_dh_key_objects(PK11_SESSION *session)
3181 +       {
3182 +       int ret = 1;
3183 +       PK11_SESSION *sp = NULL;
3184 +       PK11_SESSION *local_free_session;
3185 +       CK_BBOOL uselock = TRUE;
3187 +       if (session != NULL)
3188 +               local_free_session = session;
3189 +       else
3190 +               {
3191 +#ifndef NOPTHREADS
3192 +               OPENSSL_assert(pthread_mutex_lock(session_cache[OP_DH].lock) == 0);
3193 +#else
3194 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
3195 +#endif
3196 +               local_free_session = session_cache[OP_DH].head;
3197 +               uselock = FALSE;
3198 +               }
3200 +       while ((sp = local_free_session) != NULL)
3201 +               {
3202 +               local_free_session = sp->next;
3204 +               /*
3205 +                * Do not terminate list traversal if one of the
3206 +                * destroy operations fails.
3207 +                */
3208 +               if (pk11_destroy_dh_object(sp, uselock) == 0)
3209 +                       {
3210 +                       ret = 0;
3211 +                       continue;
3212 +                       }
3213 +               }
3215 +#ifndef NOPTHREADS
3216 +       if (session == NULL)
3217 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[OP_DH].lock) == 0);
3218 +#else
3219 +       if (session == NULL)
3220 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
3221 +#endif
3223 +       return (ret);
3224 +       }
3225 +#endif /* OPENSSL_NO_DH */
3227 +static int
3228 +pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
3229 +       CK_BBOOL persistent)
3230 +       {
3231 +       CK_RV rv;
3233 +       /*
3234 +        * We never try to destroy persistent objects which are the objects
3235 +        * stored in the keystore. Also, we always use read-only sessions so
3236 +        * C_DestroyObject() would be returning CKR_SESSION_READ_ONLY here.
3237 +        */
3238 +       if (persistent == CK_TRUE)
3239 +               return (1);
3241 +       rv = pFuncList->C_DestroyObject(session, oh);
3242 +       if (rv != CKR_OK)
3243 +               {
3244 +               PK11err_add_data(PK11_F_DESTROY_OBJECT, PK11_R_DESTROYOBJECT,
3245 +                   rv);
3246 +               return (0);
3247 +               }
3249 +       return (1);
3250 +       }
3253 +/* Symmetric ciphers and digests support functions */
3255 +static int
3256 +cipher_nid_to_pk11(int nid)
3257 +       {
3258 +       int i;
3260 +       for (i = 0; i < PK11_CIPHER_MAX; i++)
3261 +               if (ciphers[i].nid == nid)
3262 +                       return (ciphers[i].id);
3263 +       return (-1);
3264 +       }
3266 +static int
3267 +pk11_usable_ciphers(const int **nids)
3268 +       {
3269 +       if (cipher_count > 0)
3270 +               *nids = cipher_nids;
3271 +       else
3272 +               *nids = NULL;
3273 +       return (cipher_count);
3274 +       }
3276 +static int
3277 +pk11_usable_digests(const int **nids)
3278 +       {
3279 +       if (digest_count > 0)
3280 +               *nids = digest_nids;
3281 +       else
3282 +               *nids = NULL;
3283 +       return (digest_count);
3284 +       }
3287 + * Init context for encryption or decryption using a symmetric key.
3288 + */
3289 +static int pk11_init_symmetric(EVP_CIPHER_CTX *ctx, PK11_CIPHER *pcipher,
3290 +       PK11_SESSION *sp, CK_MECHANISM_PTR pmech)
3291 +       {
3292 +       CK_RV rv;
3293 +#ifdef SOLARIS_AES_CTR
3294 +       CK_AES_CTR_PARAMS ctr_params;
3295 +#endif /* SOLARIS_AES_CTR */
3297 +       /*
3298 +        * We expect pmech->mechanism to be already set and
3299 +        * pParameter/ulParameterLen initialized to NULL/0 before
3300 +        * pk11_init_symetric() is called.
3301 +        */
3302 +       OPENSSL_assert(pmech->mechanism != 0);
3303 +       OPENSSL_assert(pmech->pParameter == NULL);
3304 +       OPENSSL_assert(pmech->ulParameterLen == 0);
3306 +#ifdef SOLARIS_AES_CTR
3307 +       if (ctx->cipher->nid == NID_aes_128_ctr ||
3308 +           ctx->cipher->nid == NID_aes_192_ctr ||
3309 +           ctx->cipher->nid == NID_aes_256_ctr)
3310 +               {
3311 +               pmech->pParameter = (void *)(&ctr_params);
3312 +               pmech->ulParameterLen = sizeof (ctr_params);
3313 +               /*
3314 +                * For now, we are limited to the fixed length of the counter,
3315 +                * it covers the whole counter block. That's what RFC 4344
3316 +                * needs. For more information on internal structure of the
3317 +                * counter block, see RFC 3686. If needed in the future, we can
3318 +                * add code so that the counter length can be set via
3319 +                * ENGINE_ctrl() function.
3320 +                */
3321 +               ctr_params.ulCounterBits = AES_BLOCK_SIZE * 8;
3322 +               OPENSSL_assert(pcipher->iv_len == AES_BLOCK_SIZE);
3323 +               (void) memcpy(ctr_params.cb, ctx->iv, AES_BLOCK_SIZE);
3324 +               }
3325 +       else
3326 +#endif /* SOLARIS_AES_CTR */
3327 +               {
3328 +               if (pcipher->iv_len > 0)
3329 +                       {
3330 +                       pmech->pParameter = (void *)ctx->iv;
3331 +                       pmech->ulParameterLen = pcipher->iv_len;
3332 +                       }
3333 +               }
3335 +       /* if we get here, the encryption needs to be reinitialized */
3336 +       if (ctx->encrypt)
3337 +               rv = pFuncList->C_EncryptInit(sp->session, pmech,
3338 +                       sp->opdata_cipher_key);
3339 +       else
3340 +               rv = pFuncList->C_DecryptInit(sp->session, pmech,
3341 +                       sp->opdata_cipher_key);
3343 +       if (rv != CKR_OK)
3344 +               {
3345 +               PK11err_add_data(PK11_F_CIPHER_INIT, ctx->encrypt ?
3346 +                   PK11_R_ENCRYPTINIT : PK11_R_DECRYPTINIT, rv);
3347 +               pk11_return_session(sp, OP_CIPHER);
3348 +               return (0);
3349 +               }
3351 +       return (1);
3352 +       }
3354 +/* ARGSUSED */
3355 +static int
3356 +pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
3357 +    const unsigned char *iv, int enc)
3358 +       {
3359 +       CK_MECHANISM mech;
3360 +       int index;
3361 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
3362 +       PK11_SESSION *sp;
3363 +       PK11_CIPHER *p_ciph_table_row;
3365 +       state->sp = NULL;
3367 +       index = cipher_nid_to_pk11(ctx->cipher->nid);
3368 +       if (index < 0 || index >= PK11_CIPHER_MAX)
3369 +               return (0);
3371 +       p_ciph_table_row = &ciphers[index];
3372 +       /*
3373 +        * iv_len in the ctx->cipher structure is the maximum IV length for the
3374 +        * current cipher and it must be less or equal to the IV length in our
3375 +        * ciphers table. The key length must be in the allowed interval. From
3376 +        * all cipher modes that the PKCS#11 engine supports only RC4 allows a
3377 +        * key length to be in some range, all other NIDs have a precise key
3378 +        * length. Every application can define its own EVP functions so this
3379 +        * code serves as a sanity check.
3380 +        *
3381 +        * Note that the reason why the IV length in ctx->cipher might be
3382 +        * greater than the actual length is that OpenSSL uses BLOCK_CIPHER_defs
3383 +        * macro to define functions that return EVP structures for all DES
3384 +        * modes. So, even ECB modes get 8 byte IV.
3385 +        */
3386 +       if (ctx->cipher->iv_len < p_ciph_table_row->iv_len ||
3387 +           ctx->key_len < p_ciph_table_row->min_key_len ||
3388 +           ctx->key_len > p_ciph_table_row->max_key_len) {
3389 +               PK11err(PK11_F_CIPHER_INIT, PK11_R_KEY_OR_IV_LEN_PROBLEM);
3390 +               return (0);
3391 +       }
3393 +       if ((sp = pk11_get_session(OP_CIPHER)) == NULL)
3394 +               return (0);
3396 +       /* if applicable, the mechanism parameter is used for IV */
3397 +       mech.mechanism = p_ciph_table_row->mech_type;
3398 +       mech.pParameter = NULL;
3399 +       mech.ulParameterLen = 0;
3401 +       /* The key object is destroyed here if it is not the current key. */
3402 +       (void) check_new_cipher_key(sp, key, ctx->key_len);
3404 +       /*
3405 +        * If the key is the same and the encryption is also the same, then
3406 +        * just reuse it. However, we must not forget to reinitialize the
3407 +        * context that was finalized in pk11_cipher_cleanup().
3408 +        */
3409 +       if (sp->opdata_cipher_key != CK_INVALID_HANDLE &&
3410 +           sp->opdata_encrypt == ctx->encrypt)
3411 +               {
3412 +               state->sp = sp;
3413 +               if (pk11_init_symmetric(ctx, p_ciph_table_row, sp, &mech) == 0)
3414 +                       return (0);
3416 +               return (1);
3417 +               }
3419 +       /*
3420 +        * Check if the key has been invalidated. If so, a new key object
3421 +        * needs to be created.
3422 +        */
3423 +       if (sp->opdata_cipher_key == CK_INVALID_HANDLE)
3424 +               {
3425 +               sp->opdata_cipher_key = pk11_get_cipher_key(
3426 +                       ctx, key, p_ciph_table_row->key_type, sp);
3427 +               }
3429 +       if (sp->opdata_encrypt != ctx->encrypt && sp->opdata_encrypt != -1)
3430 +               {
3431 +               /*
3432 +                * The previous encryption/decryption is different. Need to
3433 +                * terminate the previous * active encryption/decryption here.
3434 +                */
3435 +               if (!pk11_cipher_final(sp))
3436 +                       {
3437 +                       pk11_return_session(sp, OP_CIPHER);
3438 +                       return (0);
3439 +                       }
3440 +               }
3442 +       if (sp->opdata_cipher_key == CK_INVALID_HANDLE)
3443 +               {
3444 +               pk11_return_session(sp, OP_CIPHER);
3445 +               return (0);
3446 +               }
3448 +       /* now initialize the context with a new key */
3449 +       if (pk11_init_symmetric(ctx, p_ciph_table_row, sp, &mech) == 0)
3450 +               return (0);
3452 +       sp->opdata_encrypt = ctx->encrypt;
3453 +       state->sp = sp;
3455 +       return (1);
3456 +       }
3459 + * When reusing the same key in an encryption/decryption session for a
3460 + * decryption/encryption session, we need to close the active session
3461 + * and recreate a new one. Note that the key is in the global session so
3462 + * that it needs not be recreated.
3463 + *
3464 + * It is more appropriate to use C_En/DecryptFinish here. At the time of this
3465 + * development, these two functions in the PKCS#11 libraries used return
3466 + * unexpected errors when passing in 0 length output. It may be a good
3467 + * idea to try them again if performance is a problem here and fix
3468 + * C_En/DecryptFinial if there are bugs there causing the problem.
3469 + */
3470 +static int
3471 +pk11_cipher_final(PK11_SESSION *sp)
3472 +       {
3473 +       CK_RV rv;
3475 +       rv = pFuncList->C_CloseSession(sp->session);
3476 +       if (rv != CKR_OK)
3477 +               {
3478 +               PK11err_add_data(PK11_F_CIPHER_FINAL, PK11_R_CLOSESESSION, rv);
3479 +               return (0);
3480 +               }
3482 +       rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
3483 +               NULL_PTR, NULL_PTR, &sp->session);
3484 +       if (rv != CKR_OK)
3485 +               {
3486 +               PK11err_add_data(PK11_F_CIPHER_FINAL, PK11_R_OPENSESSION, rv);
3487 +               return (0);
3488 +               }
3490 +       return (1);
3491 +       }
3494 + * An engine interface function. The calling function allocates sufficient
3495 + * memory for the output buffer "out" to hold the results.
3496 + */
3497 +#if OPENSSL_VERSION_NUMBER < 0x10000000L
3498 +static int
3499 +pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
3500 +       const unsigned char *in, unsigned int inl)
3501 +#else
3502 +static int
3503 +pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
3504 +       const unsigned char *in, size_t inl)
3505 +#endif
3506 +       {
3507 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
3508 +       PK11_SESSION *sp;
3509 +       CK_RV rv;
3510 +       unsigned long outl = inl;
3512 +       if (state == NULL || state->sp == NULL)
3513 +               return (0);
3515 +       sp = (PK11_SESSION *) state->sp;
3517 +       if (!inl)
3518 +               return (1);
3520 +       /* RC4 is the only stream cipher we support */
3521 +       if (ctx->cipher->nid != NID_rc4 && (inl % ctx->cipher->block_size) != 0)
3522 +               return (0);
3524 +       if (ctx->encrypt)
3525 +               {
3526 +               rv = pFuncList->C_EncryptUpdate(sp->session,
3527 +                       (unsigned char *)in, inl, out, &outl);
3529 +               if (rv != CKR_OK)
3530 +                       {
3531 +                       PK11err_add_data(PK11_F_CIPHER_DO_CIPHER,
3532 +                           PK11_R_ENCRYPTUPDATE, rv);
3533 +                       return (0);
3534 +                       }
3535 +               }
3536 +       else
3537 +               {
3538 +               rv = pFuncList->C_DecryptUpdate(sp->session,
3539 +                       (unsigned char *)in, inl, out, &outl);
3541 +               if (rv != CKR_OK)
3542 +                       {
3543 +                       PK11err_add_data(PK11_F_CIPHER_DO_CIPHER,
3544 +                           PK11_R_DECRYPTUPDATE, rv);
3545 +                       return (0);
3546 +                       }
3547 +               }
3549 +       /*
3550 +        * For DES_CBC, DES3_CBC, AES_CBC, and RC4, the output size is always
3551 +        * the same size of input.
3552 +        * The application has guaranteed to call the block ciphers with
3553 +        * correctly aligned buffers.
3554 +        */
3555 +       if (inl != outl)
3556 +               return (0);
3558 +       return (1);
3559 +       }
3562 + * Return the session to the pool. Calling C_EncryptFinal() and C_DecryptFinal()
3563 + * here is the right thing because in EVP_DecryptFinal_ex(), engine's
3564 + * do_cipher() is not even called, and in EVP_EncryptFinal_ex() it is called but
3565 + * the engine can't find out that it's the finalizing call. We wouldn't
3566 + * necessarily have to finalize the context here since reinitializing it with
3567 + * C_(Encrypt|Decrypt)Init() should be fine but for the sake of correctness,
3568 + * let's do it. Some implementations might leak memory if the previously used
3569 + * context is initialized without finalizing it first.
3570 + */
3571 +static int
3572 +pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx)
3573 +       {
3574 +       CK_RV rv;
3575 +       CK_ULONG len = EVP_MAX_BLOCK_LENGTH;
3576 +       CK_BYTE buf[EVP_MAX_BLOCK_LENGTH];
3577 +       PK11_CIPHER_STATE *state = ctx->cipher_data;
3579 +       if (state != NULL && state->sp != NULL)
3580 +               {
3581 +               /*
3582 +                * We are not interested in the data here, we just need to get
3583 +                * rid of the context.
3584 +                */
3585 +               if (ctx->encrypt)
3586 +                       rv = pFuncList->C_EncryptFinal(
3587 +                           state->sp->session, buf, &len);
3588 +               else
3589 +                       rv = pFuncList->C_DecryptFinal(
3590 +                           state->sp->session, buf, &len);
3592 +               if (rv != CKR_OK)
3593 +                       {
3594 +                       PK11err_add_data(PK11_F_CIPHER_CLEANUP, ctx->encrypt ?
3595 +                           PK11_R_ENCRYPTFINAL : PK11_R_DECRYPTFINAL, rv);
3596 +                       pk11_return_session(state->sp, OP_CIPHER);
3597 +                       return (0);
3598 +                       }
3600 +               pk11_return_session(state->sp, OP_CIPHER);
3601 +               state->sp = NULL;
3602 +               }
3604 +       return (1);
3605 +       }
3608 + * Registered by the ENGINE when used to find out how to deal with
3609 + * a particular NID in the ENGINE. This says what we'll do at the
3610 + * top level - note, that list is restricted by what we answer with
3611 + */
3612 +/* ARGSUSED */
3613 +static int
3614 +pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
3615 +       const int **nids, int nid)
3616 +       {
3617 +       if (!cipher)
3618 +               return (pk11_usable_ciphers(nids));
3620 +       switch (nid)
3621 +               {
3622 +               case NID_des_ede3_cbc:
3623 +                       *cipher = &pk11_3des_cbc;
3624 +                       break;
3625 +               case NID_des_cbc:
3626 +                       *cipher = &pk11_des_cbc;
3627 +                       break;
3628 +               case NID_des_ede3_ecb:
3629 +                       *cipher = &pk11_3des_ecb;
3630 +                       break;
3631 +               case NID_des_ecb:
3632 +                       *cipher = &pk11_des_ecb;
3633 +                       break;
3634 +               case NID_aes_128_cbc:
3635 +                       *cipher = &pk11_aes_128_cbc;
3636 +                       break;
3637 +               case NID_aes_192_cbc:
3638 +                       *cipher = &pk11_aes_192_cbc;
3639 +                       break;
3640 +               case NID_aes_256_cbc:
3641 +                       *cipher = &pk11_aes_256_cbc;
3642 +                       break;
3643 +               case NID_aes_128_ecb:
3644 +                       *cipher = &pk11_aes_128_ecb;
3645 +                       break;
3646 +               case NID_aes_192_ecb:
3647 +                       *cipher = &pk11_aes_192_ecb;
3648 +                       break;
3649 +               case NID_aes_256_ecb:
3650 +                       *cipher = &pk11_aes_256_ecb;
3651 +                       break;
3652 +               case NID_bf_cbc:
3653 +                       *cipher = &pk11_bf_cbc;
3654 +                       break;
3655 +               case NID_rc4:
3656 +                       *cipher = &pk11_rc4;
3657 +                       break;
3658 +               default:
3659 +#ifdef SOLARIS_AES_CTR
3660 +                       /*
3661 +                        * These can't be in separated cases because the NIDs
3662 +                        * here are not constants.
3663 +                        */
3664 +                       if (nid == NID_aes_128_ctr)
3665 +                               *cipher = &pk11_aes_128_ctr;
3666 +                       else if (nid == NID_aes_192_ctr)
3667 +                               *cipher = &pk11_aes_192_ctr;
3668 +                       else if (nid == NID_aes_256_ctr)
3669 +                               *cipher = &pk11_aes_256_ctr;
3670 +                       else
3671 +#endif /* SOLARIS_AES_CTR */
3672 +                       *cipher = NULL;
3673 +                       break;
3674 +               }
3675 +       return (*cipher != NULL);
3676 +       }
3678 +/* ARGSUSED */
3679 +static int
3680 +pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
3681 +       const int **nids, int nid)
3682 +       {
3683 +       if (!digest)
3684 +               return (pk11_usable_digests(nids));
3686 +       switch (nid)
3687 +               {
3688 +               case NID_md5:
3689 +                       *digest = &pk11_md5;
3690 +                       break;
3691 +               case NID_sha1:
3692 +                       *digest = &pk11_sha1;
3693 +                       break;
3694 +               case NID_sha224:
3695 +                       *digest = &pk11_sha224;
3696 +                       break;
3697 +               case NID_sha256:
3698 +                       *digest = &pk11_sha256;
3699 +                       break;
3700 +               case NID_sha384:
3701 +                       *digest = &pk11_sha384;
3702 +                       break;
3703 +               case NID_sha512:
3704 +                       *digest = &pk11_sha512;
3705 +                       break;
3706 +               default:
3707 +                       *digest = NULL;
3708 +                       break;
3709 +               }
3710 +       return (*digest != NULL);
3711 +       }
3714 +/* Create a secret key object in a PKCS#11 session */
3715 +static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
3716 +       const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp)
3717 +       {
3718 +       CK_RV rv;
3719 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
3720 +       CK_OBJECT_CLASS obj_key = CKO_SECRET_KEY;
3721 +       CK_ULONG ul_key_attr_count = 6;
3722 +       unsigned char key_buf[PK11_KEY_LEN_MAX];
3724 +       CK_ATTRIBUTE  a_key_template[] =
3725 +               {
3726 +               {CKA_CLASS, (void*) NULL, sizeof (CK_OBJECT_CLASS)},
3727 +               {CKA_KEY_TYPE, (void*) NULL, sizeof (CK_KEY_TYPE)},
3728 +               {CKA_TOKEN, &myfalse, sizeof (myfalse)},
3729 +               {CKA_ENCRYPT, &mytrue, sizeof (mytrue)},
3730 +               {CKA_DECRYPT, &mytrue, sizeof (mytrue)},
3731 +               {CKA_VALUE, (void*) NULL, 0},
3732 +               };
3734 +       /*
3735 +        * Create secret key object in global_session. All other sessions
3736 +        * can use the key handles. Here is why:
3737 +        * OpenSSL will call EncryptInit and EncryptUpdate using a secret key.
3738 +        * It may then call DecryptInit and DecryptUpdate using the same key.
3739 +        * To use the same key object, we need to call EncryptFinal with
3740 +        * a 0 length message. Currently, this does not work for 3DES
3741 +        * mechanism. To get around this problem, we close the session and
3742 +        * then create a new session to use the same key object. When a session
3743 +        * is closed, all the object handles will be invalid. Thus, create key
3744 +        * objects in a global session, an individual session may be closed to
3745 +        * terminate the active operation.
3746 +        */
3747 +       CK_SESSION_HANDLE session = global_session;
3748 +       a_key_template[0].pValue = &obj_key;
3749 +       a_key_template[1].pValue = &key_type;
3750 +       if (ctx->key_len > PK11_KEY_LEN_MAX)
3751 +               {
3752 +               a_key_template[5].pValue = (void *) key;
3753 +               }
3754 +       else
3755 +               {
3756 +               memset(key_buf, 0, PK11_KEY_LEN_MAX);
3757 +               memcpy(key_buf, key, ctx->key_len);
3758 +               if ((key_type == CKK_DES) ||
3759 +                   (key_type == CKK_DES2) ||
3760 +                   (key_type == CKK_DES3))
3761 +                       DES_fixup_key_parity((DES_cblock *) &key_buf[0]);
3762 +               if ((key_type == CKK_DES2) ||
3763 +                   (key_type == CKK_DES3))
3764 +                       DES_fixup_key_parity((DES_cblock *) &key_buf[8]);
3765 +               if (key_type == CKK_DES3)
3766 +                       DES_fixup_key_parity((DES_cblock *) &key_buf[16]);
3767 +               a_key_template[5].pValue = (void *) key_buf;
3768 +               }
3769 +       a_key_template[5].ulValueLen = (unsigned long) ctx->key_len;
3771 +       rv = pFuncList->C_CreateObject(session,
3772 +               a_key_template, ul_key_attr_count, &h_key);
3773 +       if (rv != CKR_OK)
3774 +               {
3775 +               memset(key_buf, 0, PK11_KEY_LEN_MAX);
3776 +               PK11err_add_data(PK11_F_GET_CIPHER_KEY, PK11_R_CREATEOBJECT,
3777 +                   rv);
3778 +               goto err;
3779 +               }
3781 +       /*
3782 +        * Save the key information used in this session.
3783 +        * The max can be saved is PK11_KEY_LEN_MAX.
3784 +        */
3785 +       if (ctx->key_len > PK11_KEY_LEN_MAX)
3786 +               {
3787 +               sp->opdata_key_len = PK11_KEY_LEN_MAX;
3788 +               (void) memcpy(sp->opdata_key, key, sp->opdata_key_len);
3789 +               }
3790 +       else
3791 +               {
3792 +               sp->opdata_key_len = ctx->key_len;
3793 +               (void) memcpy(sp->opdata_key, key_buf, sp->opdata_key_len);
3794 +               }
3795 +       memset(key_buf, 0, PK11_KEY_LEN_MAX);
3796 +err:
3798 +       return (h_key);
3799 +       }
3801 +static int
3802 +md_nid_to_pk11(int nid)
3803 +       {
3804 +       int i;
3806 +       for (i = 0; i < PK11_DIGEST_MAX; i++)
3807 +               if (digests[i].nid == nid)
3808 +                       return (digests[i].id);
3809 +       return (-1);
3810 +       }
3812 +static int
3813 +pk11_digest_init(EVP_MD_CTX *ctx)
3814 +       {
3815 +       CK_RV rv;
3816 +       CK_MECHANISM mech;
3817 +       int index;
3818 +       PK11_SESSION *sp;
3819 +       PK11_DIGEST *pdp;
3820 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
3822 +       state->sp = NULL;
3824 +       index = md_nid_to_pk11(ctx->digest->type);
3825 +       if (index < 0 || index >= PK11_DIGEST_MAX)
3826 +               return (0);
3828 +       pdp = &digests[index];
3829 +       if ((sp = pk11_get_session(OP_DIGEST)) == NULL)
3830 +               return (0);
3832 +       /* at present, no parameter is needed for supported digests */
3833 +       mech.mechanism = pdp->mech_type;
3834 +       mech.pParameter = NULL;
3835 +       mech.ulParameterLen = 0;
3837 +       rv = pFuncList->C_DigestInit(sp->session, &mech);
3839 +       if (rv != CKR_OK)
3840 +               {
3841 +               PK11err_add_data(PK11_F_DIGEST_INIT, PK11_R_DIGESTINIT, rv);
3842 +               pk11_return_session(sp, OP_DIGEST);
3843 +               return (0);
3844 +               }
3846 +       state->sp = sp;
3848 +       return (1);
3849 +       }
3851 +static int
3852 +pk11_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
3853 +       {
3854 +       CK_RV rv;
3855 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
3857 +       /* 0 length message will cause a failure in C_DigestFinal */
3858 +       if (count == 0)
3859 +               return (1);
3861 +       if (state == NULL || state->sp == NULL)
3862 +               return (0);
3864 +       rv = pFuncList->C_DigestUpdate(state->sp->session, (CK_BYTE *) data,
3865 +               count);
3867 +       if (rv != CKR_OK)
3868 +               {
3869 +               PK11err_add_data(PK11_F_DIGEST_UPDATE, PK11_R_DIGESTUPDATE, rv);
3870 +               pk11_return_session(state->sp, OP_DIGEST);
3871 +               state->sp = NULL;
3872 +               return (0);
3873 +               }
3875 +       return (1);
3876 +       }
3878 +static int
3879 +pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
3880 +       {
3881 +       CK_RV rv;
3882 +       unsigned long len;
3883 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
3884 +       len = ctx->digest->md_size;
3886 +       if (state == NULL || state->sp == NULL)
3887 +               return (0);
3889 +       rv = pFuncList->C_DigestFinal(state->sp->session, md, &len);
3891 +       if (rv != CKR_OK)
3892 +               {
3893 +               PK11err_add_data(PK11_F_DIGEST_FINAL, PK11_R_DIGESTFINAL, rv);
3894 +               pk11_return_session(state->sp, OP_DIGEST);
3895 +               state->sp = NULL;
3896 +               return (0);
3897 +               }
3899 +       if (ctx->digest->md_size != len)
3900 +               return (0);
3902 +       /*
3903 +        * Final is called and digest is returned, so return the session
3904 +        * to the pool
3905 +        */
3906 +       pk11_return_session(state->sp, OP_DIGEST);
3907 +       state->sp = NULL;
3909 +       return (1);
3910 +       }
3912 +static int
3913 +pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
3914 +       {
3915 +       CK_RV rv;
3916 +       int ret = 0;
3917 +       PK11_CIPHER_STATE *state, *state_to;
3918 +       CK_BYTE_PTR pstate = NULL;
3919 +       CK_ULONG ul_state_len;
3921 +       /* The copy-from state */
3922 +       state = (PK11_CIPHER_STATE *) from->md_data;
3923 +       if (state == NULL || state->sp == NULL)
3924 +               goto err;
3926 +       /* Initialize the copy-to state */
3927 +       if (!pk11_digest_init(to))
3928 +               goto err;
3929 +       state_to = (PK11_CIPHER_STATE *) to->md_data;
3931 +       /* Get the size of the operation state of the copy-from session */
3932 +       rv = pFuncList->C_GetOperationState(state->sp->session, NULL,
3933 +               &ul_state_len);
3935 +       if (rv != CKR_OK)
3936 +               {
3937 +               PK11err_add_data(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE,
3938 +                   rv);
3939 +               goto err;
3940 +               }
3941 +       if (ul_state_len == 0)
3942 +               {
3943 +               goto err;
3944 +               }
3946 +       pstate = OPENSSL_malloc(ul_state_len);
3947 +       if (pstate == NULL)
3948 +               {
3949 +               PK11err(PK11_F_DIGEST_COPY, PK11_R_MALLOC_FAILURE);
3950 +               goto err;
3951 +               }
3953 +       /* Get the operation state of the copy-from session */
3954 +       rv = pFuncList->C_GetOperationState(state->sp->session, pstate,
3955 +               &ul_state_len);
3957 +       if (rv != CKR_OK)
3958 +               {
3959 +               PK11err_add_data(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE,
3960 +                   rv);
3961 +               goto err;
3962 +               }
3964 +       /* Set the operation state of the copy-to session */
3965 +       rv = pFuncList->C_SetOperationState(state_to->sp->session, pstate,
3966 +               ul_state_len, 0, 0);
3968 +       if (rv != CKR_OK)
3969 +               {
3970 +               PK11err_add_data(PK11_F_DIGEST_COPY,
3971 +                   PK11_R_SET_OPERATION_STATE, rv);
3972 +               goto err;
3973 +               }
3975 +       ret = 1;
3976 +err:
3977 +       if (pstate != NULL)
3978 +               OPENSSL_free(pstate);
3980 +       return (ret);
3981 +       }
3983 +/* Return any pending session state to the pool */
3984 +static int
3985 +pk11_digest_cleanup(EVP_MD_CTX *ctx)
3986 +       {
3987 +       PK11_CIPHER_STATE *state = ctx->md_data;
3988 +       unsigned char buf[EVP_MAX_MD_SIZE];
3990 +       if (state != NULL && state->sp != NULL)
3991 +               {
3992 +               /*
3993 +                * If state->sp is not NULL then pk11_digest_final() has not
3994 +                * been called yet. We must call it now to free any memory
3995 +                * that might have been allocated in the token when
3996 +                * pk11_digest_init() was called. pk11_digest_final()
3997 +                * will return the session to the cache.
3998 +                */
3999 +               if (!pk11_digest_final(ctx, buf))
4000 +                       return (0);
4001 +               }
4003 +       return (1);
4004 +       }
4007 + * Check if the new key is the same as the key object in the session. If the key
4008 + * is the same, no need to create a new key object. Otherwise, the old key
4009 + * object needs to be destroyed and a new one will be created. Return 1 for
4010 + * cache hit, 0 for cache miss. Note that we must check the key length first
4011 + * otherwise we could end up reusing a different, longer key with the same
4012 + * prefix.
4013 + */
4014 +static int check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key,
4015 +       int key_len)
4016 +       {
4017 +       if (sp->opdata_key_len != key_len ||
4018 +           memcmp(sp->opdata_key, key, key_len) != 0)
4019 +               {
4020 +               (void) pk11_destroy_cipher_key_objects(sp);
4021 +               return (0);
4022 +               }
4023 +       return (1);
4024 +       }
4026 +/* Destroy one or more secret key objects. */
4027 +static int pk11_destroy_cipher_key_objects(PK11_SESSION *session)
4028 +       {
4029 +       int ret = 0;
4030 +       PK11_SESSION *sp = NULL;
4031 +       PK11_SESSION *local_free_session;
4033 +       if (session != NULL)
4034 +               local_free_session = session;
4035 +       else
4036 +               {
4037 +#ifndef NOPTHREADS
4038 +               OPENSSL_assert(pthread_mutex_lock(session_cache[OP_CIPHER].lock) == 0);
4039 +#else
4040 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
4041 +#endif
4042 +               local_free_session = session_cache[OP_CIPHER].head;
4043 +               }
4045 +       while ((sp = local_free_session) != NULL)
4046 +               {
4047 +               local_free_session = sp->next;
4049 +               if (sp->opdata_cipher_key != CK_INVALID_HANDLE)
4050 +                       {
4051 +                       /*
4052 +                        * The secret key object is created in the
4053 +                        * global_session. See pk11_get_cipher_key().
4054 +                        */
4055 +                       if (pk11_destroy_object(global_session,
4056 +                               sp->opdata_cipher_key, CK_FALSE) == 0)
4057 +                               goto err;
4058 +                       sp->opdata_cipher_key = CK_INVALID_HANDLE;
4059 +                       }
4060 +               }
4061 +       ret = 1;
4062 +err:
4064 +#ifndef NOPTHREADS
4065 +       if (session == NULL)
4066 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[OP_CIPHER].lock) == 0);
4067 +#else
4068 +       if (session == NULL)
4069 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
4070 +#endif
4072 +       return (ret);
4073 +       }
4077 + * Public key mechanisms optionally supported
4078 + *
4079 + * CKM_RSA_X_509
4080 + * CKM_RSA_PKCS
4081 + * CKM_DSA
4082 + *
4083 + * The first slot that supports at least one of those mechanisms is chosen as a
4084 + * public key slot.
4085 + *
4086 + * Symmetric ciphers optionally supported
4087 + *
4088 + * CKM_DES3_CBC
4089 + * CKM_DES_CBC
4090 + * CKM_AES_CBC
4091 + * CKM_DES3_ECB
4092 + * CKM_DES_ECB
4093 + * CKM_AES_ECB
4094 + * CKM_AES_CTR
4095 + * CKM_RC4
4096 + * CKM_BLOWFISH_CBC
4097 + *
4098 + * Digests optionally supported
4099 + *
4100 + * CKM_MD5
4101 + * CKM_SHA_1
4102 + * CKM_SHA224
4103 + * CKM_SHA256
4104 + * CKM_SHA384
4105 + * CKM_SHA512
4106 + *
4107 + * The output of this function is a set of global variables indicating which
4108 + * mechanisms from RSA, DSA, DH and RAND are present, and also two arrays of
4109 + * mechanisms, one for symmetric ciphers and one for digests. Also, 3 global
4110 + * variables carry information about which slot was chosen for (a) public key
4111 + * mechanisms, (b) random operations, and (c) symmetric ciphers and digests.
4112 + */
4113 +static int
4114 +pk11_choose_slots(int *any_slot_found)
4115 +       {
4116 +       CK_SLOT_ID_PTR pSlotList = NULL_PTR;
4117 +       CK_ULONG ulSlotCount = 0;
4118 +       CK_MECHANISM_INFO mech_info;
4119 +       CK_TOKEN_INFO token_info;
4120 +       unsigned int i;
4121 +       CK_RV rv;
4122 +       CK_SLOT_ID best_slot_sofar = 0;
4123 +       CK_BBOOL found_candidate_slot = CK_FALSE;
4124 +       int slot_n_cipher = 0;
4125 +       int slot_n_digest = 0;
4126 +       CK_SLOT_ID current_slot = 0;
4127 +       int current_slot_n_cipher = 0;
4128 +       int current_slot_n_digest = 0;
4130 +       int local_cipher_nids[PK11_CIPHER_MAX];
4131 +       int local_digest_nids[PK11_DIGEST_MAX];
4133 +       /* let's initialize the output parameter */
4134 +       if (any_slot_found != NULL)
4135 +               *any_slot_found = 0;
4137 +       /* Get slot list for memory allocation */
4138 +       rv = pFuncList->C_GetSlotList(CK_FALSE, NULL_PTR, &ulSlotCount);
4140 +       if (rv != CKR_OK)
4141 +               {
4142 +               PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
4143 +               return (0);
4144 +               }
4146 +       /* it's not an error if we didn't find any providers */
4147 +       if (ulSlotCount == 0)
4148 +               {
4149 +#ifdef DEBUG_SLOT_SELECTION
4150 +               fprintf(stderr, "%s: no crypto providers found\n", PK11_DBG);
4151 +#endif /* DEBUG_SLOT_SELECTION */
4152 +               return (1);
4153 +               }
4155 +       pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
4157 +       if (pSlotList == NULL)
4158 +               {
4159 +               PK11err(PK11_F_CHOOSE_SLOT, PK11_R_MALLOC_FAILURE);
4160 +               return (0);
4161 +               }
4163 +       /* Get the slot list for processing */
4164 +       rv = pFuncList->C_GetSlotList(CK_FALSE, pSlotList, &ulSlotCount);
4165 +       if (rv != CKR_OK)
4166 +               {
4167 +               PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
4168 +               OPENSSL_free(pSlotList);
4169 +               return (0);
4170 +               }
4172 +#ifdef DEBUG_SLOT_SELECTION
4173 +       fprintf(stderr, "%s: provider: %s\n", PK11_DBG, def_PK11_LIBNAME);
4174 +       fprintf(stderr, "%s: number of slots: %d\n", PK11_DBG, ulSlotCount);
4176 +       fprintf(stderr, "%s: == checking rand slots ==\n", PK11_DBG);
4177 +#endif /* DEBUG_SLOT_SELECTION */
4178 +       for (i = 0; i < ulSlotCount; i++)
4179 +               {
4180 +               current_slot = pSlotList[i];
4182 +#ifdef DEBUG_SLOT_SELECTION
4183 +       fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
4184 +#endif /* DEBUG_SLOT_SELECTION */
4185 +               /* Check if slot has random support. */
4186 +               rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
4187 +               if (rv != CKR_OK)
4188 +                       continue;
4190 +#ifdef DEBUG_SLOT_SELECTION
4191 +       fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
4192 +#endif /* DEBUG_SLOT_SELECTION */
4194 +               if (token_info.flags & CKF_RNG)
4195 +                       {
4196 +#ifdef DEBUG_SLOT_SELECTION
4197 +       fprintf(stderr, "%s: this token has CKF_RNG flag\n", PK11_DBG);
4198 +#endif /* DEBUG_SLOT_SELECTION */
4199 +                       pk11_have_random = CK_TRUE;
4200 +                       rand_SLOTID = current_slot;
4201 +                       break;
4202 +                       }
4203 +               }
4205 +#ifdef DEBUG_SLOT_SELECTION
4206 +       fprintf(stderr, "%s: == checking pubkey slots ==\n", PK11_DBG);
4207 +#endif /* DEBUG_SLOT_SELECTION */
4209 +       pubkey_SLOTID = pSlotList[0];
4210 +       for (i = 0; i < ulSlotCount; i++)
4211 +               {
4212 +               CK_BBOOL slot_has_rsa = CK_FALSE;
4213 +               CK_BBOOL slot_has_recover = CK_FALSE;
4214 +               CK_BBOOL slot_has_dsa = CK_FALSE;
4215 +               CK_BBOOL slot_has_dh = CK_FALSE;
4216 +               current_slot = pSlotList[i];
4218 +#ifdef DEBUG_SLOT_SELECTION
4219 +       fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
4220 +#endif /* DEBUG_SLOT_SELECTION */
4221 +               rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
4222 +               if (rv != CKR_OK)
4223 +                       continue;
4225 +#ifdef DEBUG_SLOT_SELECTION
4226 +       fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
4227 +#endif /* DEBUG_SLOT_SELECTION */
4229 +#ifndef OPENSSL_NO_RSA
4230 +               /*
4231 +                * Check if this slot is capable of signing and
4232 +                * verifying with CKM_RSA_PKCS.
4233 +                */
4234 +               rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS,
4235 +                       &mech_info);
4237 +               if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
4238 +                               (mech_info.flags & CKF_VERIFY)))
4239 +                       {
4240 +                       /*
4241 +                        * Check if this slot is capable of encryption,
4242 +                        * decryption, sign, and verify with CKM_RSA_X_509.
4243 +                        */
4244 +                       rv = pFuncList->C_GetMechanismInfo(current_slot,
4245 +                           CKM_RSA_X_509, &mech_info);
4247 +                       if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
4248 +                           (mech_info.flags & CKF_VERIFY) &&
4249 +                           (mech_info.flags & CKF_ENCRYPT) &&
4250 +                           (mech_info.flags & CKF_DECRYPT)))
4251 +                               {
4252 +                               slot_has_rsa = CK_TRUE;
4253 +                               if (mech_info.flags & CKF_VERIFY_RECOVER)
4254 +                                       {
4255 +                                       slot_has_recover = CK_TRUE;
4256 +                                       }
4257 +                               }
4258 +                       }
4259 +#endif /* OPENSSL_NO_RSA */
4261 +#ifndef OPENSSL_NO_DSA
4262 +               /*
4263 +                * Check if this slot is capable of signing and
4264 +                * verifying with CKM_DSA.
4265 +                */
4266 +               rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_DSA,
4267 +                       &mech_info);
4268 +               if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
4269 +                   (mech_info.flags & CKF_VERIFY)))
4270 +                       {
4271 +                       slot_has_dsa = CK_TRUE;
4272 +                       }
4274 +#endif /* OPENSSL_NO_DSA */
4276 +#ifndef OPENSSL_NO_DH
4277 +               /*
4278 +                * Check if this slot is capable of DH key generataion and
4279 +                * derivation.
4280 +                */
4281 +               rv = pFuncList->C_GetMechanismInfo(current_slot,
4282 +                   CKM_DH_PKCS_KEY_PAIR_GEN, &mech_info);
4284 +               if (rv == CKR_OK && (mech_info.flags & CKF_GENERATE_KEY_PAIR))
4285 +                       {
4286 +                       rv = pFuncList->C_GetMechanismInfo(current_slot,
4287 +                               CKM_DH_PKCS_DERIVE, &mech_info);
4288 +                       if (rv == CKR_OK && (mech_info.flags & CKF_DERIVE))
4289 +                               {
4290 +                               slot_has_dh = CK_TRUE;
4291 +                               }
4292 +                       }
4293 +#endif /* OPENSSL_NO_DH */
4295 +               if (!found_candidate_slot &&
4296 +                   (slot_has_rsa || slot_has_dsa || slot_has_dh))
4297 +                       {
4298 +#ifdef DEBUG_SLOT_SELECTION
4299 +                       fprintf(stderr,
4300 +                           "%s: potential slot: %d\n", PK11_DBG, current_slot);
4301 +#endif /* DEBUG_SLOT_SELECTION */
4302 +                       best_slot_sofar = current_slot;
4303 +                       pk11_have_rsa = slot_has_rsa;
4304 +                       pk11_have_recover = slot_has_recover;
4305 +                       pk11_have_dsa = slot_has_dsa;
4306 +                       pk11_have_dh = slot_has_dh;
4307 +                       found_candidate_slot = CK_TRUE;
4308 +                       /*
4309 +                        * Cache the flags for later use. We might
4310 +                        * need those if RSA keys by reference feature
4311 +                        * is used.
4312 +                        */
4313 +                       pubkey_token_flags = token_info.flags;
4314 +#ifdef DEBUG_SLOT_SELECTION
4315 +                       fprintf(stderr,
4316 +                           "%s: setting found_candidate_slot to CK_TRUE\n",
4317 +                           PK11_DBG);
4318 +                       fprintf(stderr,
4319 +                           "%s: best so far slot: %d\n", PK11_DBG,
4320 +                           best_slot_sofar);
4321 +                       fprintf(stderr, "%s: pubkey flags changed to "
4322 +                           "%lu.\n", PK11_DBG, pubkey_token_flags);
4323 +                       }
4324 +               else
4325 +                       {
4326 +                       fprintf(stderr,
4327 +                           "%s: no rsa/dsa/dh\n", PK11_DBG);
4328 +                       }
4329 +#else
4330 +                       } /* if */
4331 +#endif /* DEBUG_SLOT_SELECTION */
4332 +               } /* for */
4334 +       if (found_candidate_slot == CK_TRUE)
4335 +               {
4336 +               pubkey_SLOTID = best_slot_sofar;
4337 +               }
4339 +       found_candidate_slot = CK_FALSE;
4340 +       best_slot_sofar = 0;
4342 +#ifdef DEBUG_SLOT_SELECTION
4343 +       fprintf(stderr, "%s: == checking cipher/digest ==\n", PK11_DBG);
4344 +#endif /* DEBUG_SLOT_SELECTION */
4346 +       SLOTID = pSlotList[0];
4347 +       for (i = 0; i < ulSlotCount; i++)
4348 +               {
4349 +#ifdef DEBUG_SLOT_SELECTION
4350 +       fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
4351 +#endif /* DEBUG_SLOT_SELECTION */
4353 +               current_slot = pSlotList[i];
4354 +               current_slot_n_cipher = 0;
4355 +               current_slot_n_digest = 0;
4356 +               (void) memset(local_cipher_nids, 0, sizeof (local_cipher_nids));
4357 +               (void) memset(local_digest_nids, 0, sizeof (local_digest_nids));
4359 +               pk11_find_symmetric_ciphers(pFuncList, current_slot,
4360 +                   &current_slot_n_cipher, local_cipher_nids);
4362 +               pk11_find_digests(pFuncList, current_slot,
4363 +                   &current_slot_n_digest, local_digest_nids);
4365 +#ifdef DEBUG_SLOT_SELECTION
4366 +               fprintf(stderr, "%s: current_slot_n_cipher %d\n", PK11_DBG,
4367 +                       current_slot_n_cipher);
4368 +               fprintf(stderr, "%s: current_slot_n_digest %d\n", PK11_DBG,
4369 +                       current_slot_n_digest);
4370 +               fprintf(stderr, "%s: best so far cipher/digest slot: %d\n",
4371 +                       PK11_DBG, best_slot_sofar);
4372 +#endif /* DEBUG_SLOT_SELECTION */
4374 +               /*
4375 +                * If the current slot supports more ciphers/digests than
4376 +                * the previous best one we change the current best to this one,
4377 +                * otherwise leave it where it is.
4378 +                */
4379 +               if ((current_slot_n_cipher + current_slot_n_digest) >
4380 +                   (slot_n_cipher + slot_n_digest))
4381 +                       {
4382 +#ifdef DEBUG_SLOT_SELECTION
4383 +                       fprintf(stderr,
4384 +                               "%s: changing best so far slot to %d\n",
4385 +                               PK11_DBG, current_slot);
4386 +#endif /* DEBUG_SLOT_SELECTION */
4387 +                       best_slot_sofar = SLOTID = current_slot;
4388 +                       cipher_count = slot_n_cipher = current_slot_n_cipher;
4389 +                       digest_count = slot_n_digest = current_slot_n_digest;
4390 +                       (void) memcpy(cipher_nids, local_cipher_nids,
4391 +                           sizeof (local_cipher_nids));
4392 +                       (void) memcpy(digest_nids, local_digest_nids, 
4393 +                           sizeof (local_digest_nids));
4394 +                       }
4395 +               }
4397 +#ifdef DEBUG_SLOT_SELECTION
4398 +       fprintf(stderr,
4399 +           "%s: chosen pubkey slot: %d\n", PK11_DBG, pubkey_SLOTID);
4400 +       fprintf(stderr,
4401 +           "%s: chosen rand slot: %d\n", PK11_DBG, rand_SLOTID);
4402 +       fprintf(stderr,
4403 +           "%s: chosen cipher/digest slot: %d\n", PK11_DBG, SLOTID);
4404 +       fprintf(stderr,
4405 +           "%s: pk11_have_rsa %d\n", PK11_DBG, pk11_have_rsa);
4406 +       fprintf(stderr,
4407 +           "%s: pk11_have_recover %d\n", PK11_DBG, pk11_have_recover);
4408 +       fprintf(stderr,
4409 +           "%s: pk11_have_dsa %d\n", PK11_DBG, pk11_have_dsa);
4410 +       fprintf(stderr,
4411 +           "%s: pk11_have_dh %d\n", PK11_DBG, pk11_have_dh);
4412 +       fprintf(stderr,
4413 +           "%s: pk11_have_random %d\n", PK11_DBG, pk11_have_random);
4414 +       fprintf(stderr,
4415 +           "%s: cipher_count %d\n", PK11_DBG, cipher_count);
4416 +       fprintf(stderr,
4417 +           "%s: digest_count %d\n", PK11_DBG, digest_count);
4418 +#endif /* DEBUG_SLOT_SELECTION */
4420 +       if (pSlotList != NULL)
4421 +               OPENSSL_free(pSlotList);
4423 +#ifdef SOLARIS_HW_SLOT_SELECTION
4424 +       OPENSSL_free(hw_cnids);
4425 +       OPENSSL_free(hw_dnids);
4426 +#endif /* SOLARIS_HW_SLOT_SELECTION */
4428 +       if (any_slot_found != NULL)
4429 +               *any_slot_found = 1;
4430 +       return (1);
4431 +       }
4433 +static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR pflist,
4434 +    int slot_id, CK_MECHANISM_TYPE mech, int *current_slot_n_cipher,
4435 +    int *local_cipher_nids, int id)
4436 +       {
4437 +       CK_MECHANISM_INFO mech_info;
4438 +       CK_RV rv;
4440 +#ifdef DEBUG_SLOT_SELECTION
4441 +       fprintf(stderr, "%s: checking mech: %x", PK11_DBG, mech);
4442 +#endif /* DEBUG_SLOT_SELECTION */
4443 +       rv = pflist->C_GetMechanismInfo(slot_id, mech, &mech_info);
4445 +       if (rv != CKR_OK)
4446 +               {
4447 +#ifdef DEBUG_SLOT_SELECTION
4448 +               fprintf(stderr, " not found\n");
4449 +#endif /* DEBUG_SLOT_SELECTION */
4450 +               return;
4451 +               }
4453 +       if ((mech_info.flags & CKF_ENCRYPT) &&
4454 +           (mech_info.flags & CKF_DECRYPT))
4455 +               {
4456 +#ifdef SOLARIS_HW_SLOT_SELECTION
4457 +               if (nid_in_table(ciphers[id].nid, hw_cnids))
4458 +#endif /* SOLARIS_HW_SLOT_SELECTION */
4459 +                       {
4460 +#ifdef DEBUG_SLOT_SELECTION
4461 +               fprintf(stderr, " usable\n");
4462 +#endif /* DEBUG_SLOT_SELECTION */
4463 +                       local_cipher_nids[(*current_slot_n_cipher)++] =
4464 +                           ciphers[id].nid;
4465 +                       }
4466 +#ifdef SOLARIS_HW_SLOT_SELECTION
4467 +#ifdef DEBUG_SLOT_SELECTION
4468 +               else
4469 +                       {
4470 +               fprintf(stderr, " rejected, software implementation only\n");
4471 +                       }
4472 +#endif /* DEBUG_SLOT_SELECTION */
4473 +#endif /* SOLARIS_HW_SLOT_SELECTION */
4474 +               }
4475 +#ifdef DEBUG_SLOT_SELECTION
4476 +       else
4477 +               {
4478 +               fprintf(stderr, " unusable\n");
4479 +               }
4480 +#endif /* DEBUG_SLOT_SELECTION */
4482 +       return;
4483 +       }
4485 +static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
4486 +    CK_MECHANISM_TYPE mech, int *current_slot_n_digest, int *local_digest_nids,
4487 +    int id)
4488 +       {
4489 +       CK_MECHANISM_INFO mech_info;
4490 +       CK_RV rv;
4492 +#ifdef DEBUG_SLOT_SELECTION
4493 +       fprintf(stderr, "%s: checking mech: %x", PK11_DBG, mech);
4494 +#endif /* DEBUG_SLOT_SELECTION */
4495 +       rv = pflist->C_GetMechanismInfo(slot_id, mech, &mech_info);
4497 +       if (rv != CKR_OK)
4498 +               {
4499 +#ifdef DEBUG_SLOT_SELECTION
4500 +               fprintf(stderr, " not found\n");
4501 +#endif /* DEBUG_SLOT_SELECTION */
4502 +               return;
4503 +               }
4505 +       if (mech_info.flags & CKF_DIGEST)
4506 +               {
4507 +#ifdef SOLARIS_HW_SLOT_SELECTION
4508 +               if (nid_in_table(digests[id].nid, hw_dnids))
4509 +#endif /* SOLARIS_HW_SLOT_SELECTION */
4510 +                       {
4511 +#ifdef DEBUG_SLOT_SELECTION
4512 +               fprintf(stderr, " usable\n");
4513 +#endif /* DEBUG_SLOT_SELECTION */
4514 +                       local_digest_nids[(*current_slot_n_digest)++] =
4515 +                           digests[id].nid;
4516 +                       }
4517 +#ifdef SOLARIS_HW_SLOT_SELECTION
4518 +#ifdef DEBUG_SLOT_SELECTION
4519 +               else
4520 +                       {
4521 +               fprintf(stderr, " rejected, software implementation only\n");
4522 +                       }
4523 +#endif /* DEBUG_SLOT_SELECTION */
4524 +#endif /* SOLARIS_HW_SLOT_SELECTION */
4525 +               }
4526 +#ifdef DEBUG_SLOT_SELECTION
4527 +       else
4528 +               {
4529 +               fprintf(stderr, " unusable\n");
4530 +               }
4531 +#endif /* DEBUG_SLOT_SELECTION */
4533 +       return;
4534 +       }
4536 +#ifdef SOLARIS_AES_CTR
4537 +/* create a new NID when we have no OID for that mechanism */
4538 +static int pk11_add_NID(char *sn, char *ln)
4539 +       {
4540 +       ASN1_OBJECT *o;
4541 +       int nid;
4543 +       if ((o = ASN1_OBJECT_create(OBJ_new_nid(1), (unsigned char *)"",
4544 +           1, sn, ln)) == NULL)
4545 +               {
4546 +               return (0);
4547 +               }
4549 +       /* will return NID_undef on error */
4550 +       nid = OBJ_add_object(o);
4551 +       ASN1_OBJECT_free(o);
4553 +       return (nid);
4554 +       }
4557 + * Create new NIDs for AES counter mode. OpenSSL doesn't support them now so we
4558 + * have to help ourselves here.
4559 + */
4560 +static int pk11_add_aes_ctr_NIDs(void)
4561 +       {
4562 +       /* are we already set? */
4563 +       if (NID_aes_256_ctr != NID_undef)
4564 +               return (1);
4566 +       /*
4567 +        * There are no official names for AES counter modes yet so we just
4568 +        * follow the format of those that exist.
4569 +        */
4570 +       if ((NID_aes_128_ctr = pk11_add_NID("AES-128-CTR", "aes-128-ctr")) ==
4571 +           NID_undef)
4572 +               goto err;
4573 +       ciphers[PK11_AES_128_CTR].nid = pk11_aes_128_ctr.nid = NID_aes_128_ctr;
4574 +       if ((NID_aes_192_ctr = pk11_add_NID("AES-192-CTR", "aes-192-ctr")) ==
4575 +           NID_undef)
4576 +               goto err;
4577 +       ciphers[PK11_AES_192_CTR].nid = pk11_aes_192_ctr.nid = NID_aes_192_ctr;
4578 +       if ((NID_aes_256_ctr = pk11_add_NID("AES-256-CTR", "aes-256-ctr")) ==
4579 +           NID_undef)
4580 +               goto err;
4581 +       ciphers[PK11_AES_256_CTR].nid = pk11_aes_256_ctr.nid = NID_aes_256_ctr;
4582 +       return (1);
4584 +err:
4585 +       PK11err(PK11_F_ADD_AES_CTR_NIDS, PK11_R_ADD_NID_FAILED);
4586 +       return (0);
4587 +       }
4588 +#endif /* SOLARIS_AES_CTR */
4590 +/* Find what symmetric ciphers this slot supports. */
4591 +static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
4592 +    CK_SLOT_ID current_slot, int *current_slot_n_cipher, int *local_cipher_nids)
4593 +       {
4594 +       int i;
4596 +       for (i = 0; i < PK11_CIPHER_MAX; ++i)
4597 +               {
4598 +               pk11_get_symmetric_cipher(pflist, current_slot,
4599 +                   ciphers[i].mech_type, current_slot_n_cipher,
4600 +                   local_cipher_nids, ciphers[i].id);
4601 +               }
4602 +       }
4604 +/* Find what digest algorithms this slot supports. */
4605 +static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
4606 +    CK_SLOT_ID current_slot, int *current_slot_n_digest, int *local_digest_nids)
4607 +       {
4608 +       int i;
4610 +       for (i = 0; i < PK11_DIGEST_MAX; ++i)
4611 +               {
4612 +               pk11_get_digest(pflist, current_slot, digests[i].mech_type,
4613 +                   current_slot_n_digest, local_digest_nids, digests[i].id);
4614 +               }
4615 +       }
4617 +#ifdef SOLARIS_HW_SLOT_SELECTION
4619 + * It would be great if we could use pkcs11_kernel directly since this library
4620 + * offers hardware slots only. That's the easiest way to achieve the situation
4621 + * where we use the hardware accelerators when present and OpenSSL native code
4622 + * otherwise. That presumes the fact that OpenSSL native code is faster than the
4623 + * code in the soft token. It's a logical assumption - Crypto Framework has some
4624 + * inherent overhead so going there for the software implementation of a
4625 + * mechanism should be logically slower in contrast to the OpenSSL native code,
4626 + * presuming that both implementations are of similar speed. For example, the
4627 + * soft token for AES is roughly three times slower than OpenSSL for 64 byte
4628 + * blocks and still 20% slower for 8KB blocks. So, if we want to ship products
4629 + * that use the PKCS#11 engine by default, we must somehow avoid that regression
4630 + * on machines without hardware acceleration. That's why switching to the
4631 + * pkcs11_kernel library seems like a very good idea.
4632 + *
4633 + * The problem is that OpenSSL built with SunStudio is roughly 2x slower for
4634 + * asymmetric operations (RSA/DSA/DH) than the soft token built with the same
4635 + * compiler. That means that if we switched to pkcs11_kernel from the libpkcs11
4636 + * library, we would have had a performance regression on machines without
4637 + * hardware acceleration for asymmetric operations for all applications that use
4638 + * the PKCS#11 engine. There is one such application - Apache web server since
4639 + * it's shipped configured to use the PKCS#11 engine by default. Having said
4640 + * that, we can't switch to the pkcs11_kernel library now and have to come with
4641 + * a solution that, on non-accelerated machines, uses the OpenSSL native code
4642 + * for all symmetric ciphers and digests while it uses the soft token for
4643 + * asymmetric operations.
4644 + *
4645 + * This is the idea: dlopen() pkcs11_kernel directly and find out what
4646 + * mechanisms are there. We don't care about duplications (more slots can
4647 + * support the same mechanism), we just want to know what mechanisms can be
4648 + * possibly supported in hardware on that particular machine. As said before,
4649 + * pkcs11_kernel will show you hardware providers only.
4650 + *
4651 + * Then, we rely on the fact that since we use libpkcs11 library we will find
4652 + * the metaslot. When we go through the metaslot's mechanisms for symmetric
4653 + * ciphers and digests, we check that any found mechanism is in the table
4654 + * created using the pkcs11_kernel library. So, as a result we have two arrays
4655 + * of mechanisms that were advertised as supported in hardware which was the
4656 + * goal of that whole excercise. Thus, we can use libpkcs11 but avoid soft token
4657 + * code for symmetric ciphers and digests. See pk11_choose_slots() for more
4658 + * information.
4659 + *
4660 + * This is Solaris specific code, if SOLARIS_HW_SLOT_SELECTION is not defined
4661 + * the code won't be used.
4662 + */
4663 +#if defined(__sparcv9) || defined(__x86_64) || defined(__amd64)
4664 +static const char pkcs11_kernel[] = "/usr/lib/security/64/pkcs11_kernel.so.1";
4665 +#else
4666 +static const char pkcs11_kernel[] = "/usr/lib/security/pkcs11_kernel.so.1";
4667 +#endif
4670 + * Check hardware capabilities of the machines. The output are two lists,
4671 + * hw_cnids and hw_dnids, that contain hardware mechanisms found in all hardware
4672 + * providers together. They are not sorted and may contain duplicate mechanisms.
4673 + */
4674 +static int check_hw_mechanisms(void)
4675 +       {
4676 +       int i;
4677 +       CK_RV rv;
4678 +       void *handle;
4679 +       CK_C_GetFunctionList p;
4680 +       CK_TOKEN_INFO token_info;
4681 +       CK_ULONG ulSlotCount = 0;
4682 +       int n_cipher = 0, n_digest = 0;
4683 +       CK_FUNCTION_LIST_PTR pflist = NULL;
4684 +       CK_SLOT_ID_PTR pSlotList = NULL_PTR;
4685 +       int *tmp_hw_cnids = NULL, *tmp_hw_dnids = NULL;
4686 +       int hw_ctable_size, hw_dtable_size;
4688 +#ifdef DEBUG_SLOT_SELECTION
4689 +       fprintf(stderr, "%s: SOLARIS_HW_SLOT_SELECTION code running\n",
4690 +           PK11_DBG);
4691 +#endif
4692 +       if ((handle = dlopen(pkcs11_kernel, RTLD_LAZY)) == NULL)
4693 +               {
4694 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
4695 +               goto err;
4696 +               }
4698 +       if ((p = (CK_C_GetFunctionList)dlsym(handle,
4699 +           PK11_GET_FUNCTION_LIST)) == NULL)
4700 +               {
4701 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
4702 +               goto err;
4703 +               }
4705 +       /* get the full function list from the loaded library */
4706 +       if (p(&pflist) != CKR_OK)
4707 +               {
4708 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
4709 +               goto err;
4710 +               }
4712 +       rv = pflist->C_Initialize((CK_VOID_PTR)&pk11_init_args);
4713 +       if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
4714 +               {
4715 +               PK11err_add_data(PK11_F_CHECK_HW_MECHANISMS,
4716 +                   PK11_R_INITIALIZE, rv);
4717 +               goto err;
4718 +               }
4720 +       if (pflist->C_GetSlotList(0, NULL_PTR, &ulSlotCount) != CKR_OK)
4721 +               {
4722 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_GETSLOTLIST);
4723 +               goto err;
4724 +               }
4726 +       /* no slots, set the hw mechanism tables as empty */
4727 +       if (ulSlotCount == 0)
4728 +               {
4729 +#ifdef DEBUG_SLOT_SELECTION
4730 +       fprintf(stderr, "%s: no hardware mechanisms found\n", PK11_DBG);
4731 +#endif
4732 +               hw_cnids = OPENSSL_malloc(sizeof (int));
4733 +               hw_dnids = OPENSSL_malloc(sizeof (int));
4734 +               if (hw_cnids == NULL || hw_dnids == NULL)
4735 +                       {
4736 +                       PK11err(PK11_F_CHECK_HW_MECHANISMS,
4737 +                           PK11_R_MALLOC_FAILURE);
4738 +                       return (0);
4739 +                       }
4740 +               /* this means empty tables */
4741 +               hw_cnids[0] = NID_undef;
4742 +               hw_dnids[0] = NID_undef;
4743 +               return (1);
4744 +               }
4746 +       pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
4747 +       if (pSlotList == NULL)
4748 +               {
4749 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_MALLOC_FAILURE);
4750 +               goto err;
4751 +               }
4753 +       /* Get the slot list for processing */
4754 +       if (pflist->C_GetSlotList(0, pSlotList, &ulSlotCount) != CKR_OK)
4755 +               {
4756 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_GETSLOTLIST);
4757 +               goto err;
4758 +               }
4760 +       /*
4761 +        * We don't care about duplicit mechanisms in multiple slots and also
4762 +        * reserve one slot for the terminal NID_undef which we use to stop the
4763 +        * search.
4764 +        */
4765 +       hw_ctable_size = ulSlotCount * PK11_CIPHER_MAX + 1;
4766 +       hw_dtable_size = ulSlotCount * PK11_DIGEST_MAX + 1;
4767 +       tmp_hw_cnids = OPENSSL_malloc(hw_ctable_size * sizeof (int));
4768 +       tmp_hw_dnids = OPENSSL_malloc(hw_dtable_size * sizeof (int));
4769 +       if (tmp_hw_cnids == NULL || tmp_hw_dnids == NULL)
4770 +               {
4771 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_MALLOC_FAILURE);
4772 +               goto err;
4773 +               }
4775 +       /*
4776 +        * Do not use memset since we should not rely on the fact that NID_undef
4777 +        * is zero now.
4778 +        */
4779 +       for (i = 0; i < hw_ctable_size; ++i)
4780 +               tmp_hw_cnids[i] = NID_undef;
4781 +       for (i = 0; i < hw_dtable_size; ++i)
4782 +               tmp_hw_dnids[i] = NID_undef;
4784 +#ifdef DEBUG_SLOT_SELECTION
4785 +       fprintf(stderr, "%s: provider: %s\n", PK11_DBG, pkcs11_kernel);
4786 +       fprintf(stderr, "%s: found %d hardware slots\n", PK11_DBG, ulSlotCount);
4787 +       fprintf(stderr, "%s: now looking for mechs supported in hw\n",
4788 +           PK11_DBG);
4789 +#endif /* DEBUG_SLOT_SELECTION */
4791 +       for (i = 0; i < ulSlotCount; i++)
4792 +               {
4793 +               if (pflist->C_GetTokenInfo(pSlotList[i], &token_info) != CKR_OK)
4794 +                       continue;
4796 +#ifdef DEBUG_SLOT_SELECTION
4797 +       fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
4798 +#endif /* DEBUG_SLOT_SELECTION */
4800 +               /*
4801 +                * We are filling the hw mech tables here. Global tables are
4802 +                * still NULL so all mechanisms are put into tmp tables.
4803 +                */
4804 +               pk11_find_symmetric_ciphers(pflist, pSlotList[i],
4805 +                   &n_cipher, tmp_hw_cnids);
4806 +               pk11_find_digests(pflist, pSlotList[i],
4807 +                   &n_digest, tmp_hw_dnids);
4808 +               }
4810 +       /*
4811 +        * Since we are part of a library (libcrypto.so), calling this function
4812 +        * may have side-effects. Also, C_Finalize() is triggered by
4813 +        * dlclose(3C).
4814 +        */
4815 +#if 0
4816 +       pflist->C_Finalize(NULL);
4817 +#endif
4818 +       OPENSSL_free(pSlotList);
4819 +       (void) dlclose(handle);
4820 +       hw_cnids = tmp_hw_cnids;
4821 +       hw_dnids = tmp_hw_dnids;
4823 +#ifdef DEBUG_SLOT_SELECTION
4824 +       fprintf(stderr, "%s: hw mechs check complete\n", PK11_DBG);
4825 +#endif /* DEBUG_SLOT_SELECTION */
4826 +       return (1);
4828 +err:
4829 +       if (pSlotList != NULL)
4830 +               OPENSSL_free(pSlotList);
4831 +       if (tmp_hw_cnids != NULL)
4832 +               OPENSSL_free(tmp_hw_cnids);
4833 +       if (tmp_hw_dnids != NULL)
4834 +               OPENSSL_free(tmp_hw_dnids);
4836 +       return (0);
4837 +       }
4840 + * Check presence of a NID in the table of NIDs. The table may be NULL (i.e.,
4841 + * non-existent).
4842 + */
4843 +static int nid_in_table(int nid, int *nid_table)
4844 +       {
4845 +       int i = 0;
4847 +       /*
4848 +        * a special case. NULL means that we are initializing a new
4849 +        * table.
4850 +        */
4851 +       if (nid_table == NULL)
4852 +               return (1);
4854 +       /*
4855 +        * the table is never full, there is always at least one
4856 +        * NID_undef.
4857 +        */
4858 +       while (nid_table[i] != NID_undef)
4859 +               {
4860 +               if (nid_table[i++] == nid)
4861 +                       {
4862 +#ifdef DEBUG_SLOT_SELECTION
4863 +       fprintf(stderr, " (NID %d in hw table, idx %d)", nid, i);
4864 +#endif /* DEBUG_SLOT_SELECTION */
4865 +                       return (1);
4866 +                       }
4867 +               }
4869 +       return (0);
4870 +       }
4871 +#endif /* SOLARIS_HW_SLOT_SELECTION */
4873 +#endif /* OPENSSL_NO_HW_PK11CA */
4874 +#endif /* OPENSSL_NO_HW_PK11 */
4875 +#endif /* OPENSSL_NO_HW */
4876 Index: openssl/crypto/engine/hw_pk11_err.c
4877 diff -u /dev/null openssl/crypto/engine/hw_pk11_err.c:1.5
4878 --- /dev/null   Fri Jan  2 14:26:16 2015
4879 +++ openssl/crypto/engine/hw_pk11_err.c Tue Jun 14 00:43:26 2011
4880 @@ -0,0 +1,288 @@
4882 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
4883 + * Use is subject to license terms.
4884 + */
4886 +/* crypto/engine/hw_pk11_err.c */
4888 + * This product includes software developed by the OpenSSL Project for
4889 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
4890 + *
4891 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
4892 + * Afchine Madjlessi.
4893 + */
4895 + * ====================================================================
4896 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
4897 + *
4898 + * Redistribution and use in source and binary forms, with or without
4899 + * modification, are permitted provided that the following conditions
4900 + * are met:
4901 + *
4902 + * 1. Redistributions of source code must retain the above copyright
4903 + *    notice, this list of conditions and the following disclaimer.
4904 + *
4905 + * 2. Redistributions in binary form must reproduce the above copyright
4906 + *    notice, this list of conditions and the following disclaimer in
4907 + *    the documentation and/or other materials provided with the
4908 + *    distribution.
4909 + *
4910 + * 3. All advertising materials mentioning features or use of this
4911 + *    software must display the following acknowledgment:
4912 + *    "This product includes software developed by the OpenSSL Project
4913 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
4914 + *
4915 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
4916 + *    endorse or promote products derived from this software without
4917 + *    prior written permission. For written permission, please contact
4918 + *    licensing@OpenSSL.org.
4919 + *
4920 + * 5. Products derived from this software may not be called "OpenSSL"
4921 + *    nor may "OpenSSL" appear in their names without prior written
4922 + *    permission of the OpenSSL Project.
4923 + *
4924 + * 6. Redistributions of any form whatsoever must retain the following
4925 + *    acknowledgment:
4926 + *    "This product includes software developed by the OpenSSL Project
4927 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
4928 + *
4929 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
4930 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4931 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
4932 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
4933 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4934 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
4935 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
4936 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4937 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4938 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
4939 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
4940 + * OF THE POSSIBILITY OF SUCH DAMAGE.
4941 + * ====================================================================
4942 + *
4943 + * This product includes cryptographic software written by Eric Young
4944 + * (eay@cryptsoft.com).  This product includes software written by Tim
4945 + * Hudson (tjh@cryptsoft.com).
4946 + *
4947 + */
4949 +#include <stdio.h>
4950 +#include <openssl/err.h>
4951 +#include "hw_pk11_err.h"
4953 +/* BEGIN ERROR CODES */
4954 +#ifndef OPENSSL_NO_ERR
4955 +static ERR_STRING_DATA pk11_str_functs[]=
4957 +{ ERR_PACK(0, PK11_F_INIT, 0),                 "PK11_INIT"},
4958 +{ ERR_PACK(0, PK11_F_FINISH, 0),               "PK11_FINISH"},
4959 +{ ERR_PACK(0, PK11_F_DESTROY, 0),              "PK11_DESTROY"},
4960 +{ ERR_PACK(0, PK11_F_CTRL, 0),                 "PK11_CTRL"},
4961 +{ ERR_PACK(0, PK11_F_RSA_INIT, 0),             "PK11_RSA_INIT"},
4962 +{ ERR_PACK(0, PK11_F_RSA_FINISH, 0),           "PK11_RSA_FINISH"},
4963 +{ ERR_PACK(0, PK11_F_GET_PUB_RSA_KEY, 0),      "PK11_GET_PUB_RSA_KEY"},
4964 +{ ERR_PACK(0, PK11_F_GET_PRIV_RSA_KEY, 0),     "PK11_GET_PRIV_RSA_KEY"},
4965 +{ ERR_PACK(0, PK11_F_RSA_GEN_KEY, 0),          "PK11_RSA_GEN_KEY"},
4966 +{ ERR_PACK(0, PK11_F_RSA_PUB_ENC, 0),          "PK11_RSA_PUB_ENC"},
4967 +{ ERR_PACK(0, PK11_F_RSA_PRIV_ENC, 0),         "PK11_RSA_PRIV_ENC"},
4968 +{ ERR_PACK(0, PK11_F_RSA_PUB_DEC, 0),          "PK11_RSA_PUB_DEC"},
4969 +{ ERR_PACK(0, PK11_F_RSA_PRIV_DEC, 0),         "PK11_RSA_PRIV_DEC"},
4970 +{ ERR_PACK(0, PK11_F_RSA_SIGN, 0),             "PK11_RSA_SIGN"},
4971 +{ ERR_PACK(0, PK11_F_RSA_VERIFY, 0),           "PK11_RSA_VERIFY"},
4972 +{ ERR_PACK(0, PK11_F_RAND_ADD, 0),             "PK11_RAND_ADD"},
4973 +{ ERR_PACK(0, PK11_F_RAND_BYTES, 0),           "PK11_RAND_BYTES"},
4974 +{ ERR_PACK(0, PK11_F_GET_SESSION, 0),          "PK11_GET_SESSION"},
4975 +{ ERR_PACK(0, PK11_F_FREE_SESSION, 0),         "PK11_FREE_SESSION"},
4976 +{ ERR_PACK(0, PK11_F_LOAD_PUBKEY, 0),          "PK11_LOAD_PUBKEY"},
4977 +{ ERR_PACK(0, PK11_F_LOAD_PRIVKEY, 0),         "PK11_LOAD_PRIV_KEY"},
4978 +{ ERR_PACK(0, PK11_F_RSA_PUB_ENC_LOW, 0),      "PK11_RSA_PUB_ENC_LOW"},
4979 +{ ERR_PACK(0, PK11_F_RSA_PRIV_ENC_LOW, 0),     "PK11_RSA_PRIV_ENC_LOW"},
4980 +{ ERR_PACK(0, PK11_F_RSA_PUB_DEC_LOW, 0),      "PK11_RSA_PUB_DEC_LOW"},
4981 +{ ERR_PACK(0, PK11_F_RSA_PRIV_DEC_LOW, 0),     "PK11_RSA_PRIV_DEC_LOW"},
4982 +{ ERR_PACK(0, PK11_F_DSA_SIGN, 0),             "PK11_DSA_SIGN"},
4983 +{ ERR_PACK(0, PK11_F_DSA_VERIFY, 0),           "PK11_DSA_VERIFY"},
4984 +{ ERR_PACK(0, PK11_F_DSA_INIT, 0),             "PK11_DSA_INIT"},
4985 +{ ERR_PACK(0, PK11_F_DSA_FINISH, 0),           "PK11_DSA_FINISH"},
4986 +{ ERR_PACK(0, PK11_F_GET_PUB_DSA_KEY, 0),      "PK11_GET_PUB_DSA_KEY"},
4987 +{ ERR_PACK(0, PK11_F_GET_PRIV_DSA_KEY, 0),     "PK11_GET_PRIV_DSA_KEY"},
4988 +{ ERR_PACK(0, PK11_F_DH_INIT, 0),              "PK11_DH_INIT"},
4989 +{ ERR_PACK(0, PK11_F_DH_FINISH, 0),            "PK11_DH_FINISH"},
4990 +{ ERR_PACK(0, PK11_F_MOD_EXP_DH, 0),           "PK11_MOD_EXP_DH"},
4991 +{ ERR_PACK(0, PK11_F_GET_DH_KEY, 0),           "PK11_GET_DH_KEY"},
4992 +{ ERR_PACK(0, PK11_F_FREE_ALL_SESSIONS, 0),    "PK11_FREE_ALL_SESSIONS"},
4993 +{ ERR_PACK(0, PK11_F_SETUP_SESSION, 0),                "PK11_SETUP_SESSION"},
4994 +{ ERR_PACK(0, PK11_F_DESTROY_OBJECT, 0),       "PK11_DESTROY_OBJECT"},
4995 +{ ERR_PACK(0, PK11_F_CIPHER_INIT, 0),          "PK11_CIPHER_INIT"},
4996 +{ ERR_PACK(0, PK11_F_CIPHER_DO_CIPHER, 0),     "PK11_CIPHER_DO_CIPHER"},
4997 +{ ERR_PACK(0, PK11_F_GET_CIPHER_KEY, 0),       "PK11_GET_CIPHER_KEY"},
4998 +{ ERR_PACK(0, PK11_F_DIGEST_INIT, 0),          "PK11_DIGEST_INIT"},
4999 +{ ERR_PACK(0, PK11_F_DIGEST_UPDATE, 0),                "PK11_DIGEST_UPDATE"},
5000 +{ ERR_PACK(0, PK11_F_DIGEST_FINAL, 0),         "PK11_DIGEST_FINAL"},
5001 +{ ERR_PACK(0, PK11_F_CHOOSE_SLOT, 0),          "PK11_CHOOSE_SLOT"},
5002 +{ ERR_PACK(0, PK11_F_CIPHER_FINAL, 0),         "PK11_CIPHER_FINAL"},
5003 +{ ERR_PACK(0, PK11_F_LIBRARY_INIT, 0),         "PK11_LIBRARY_INIT"},
5004 +{ ERR_PACK(0, PK11_F_LOAD, 0),                 "ENGINE_LOAD_PK11"},
5005 +{ ERR_PACK(0, PK11_F_DH_GEN_KEY, 0),           "PK11_DH_GEN_KEY"},
5006 +{ ERR_PACK(0, PK11_F_DH_COMP_KEY, 0),          "PK11_DH_COMP_KEY"},
5007 +{ ERR_PACK(0, PK11_F_DIGEST_COPY, 0),          "PK11_DIGEST_COPY"},
5008 +{ ERR_PACK(0, PK11_F_CIPHER_CLEANUP, 0),       "PK11_CIPHER_CLEANUP"},
5009 +{ ERR_PACK(0, PK11_F_ACTIVE_ADD, 0),           "PK11_ACTIVE_ADD"},
5010 +{ ERR_PACK(0, PK11_F_ACTIVE_DELETE, 0),                "PK11_ACTIVE_DELETE"},
5011 +{ ERR_PACK(0, PK11_F_CHECK_HW_MECHANISMS, 0),  "PK11_CHECK_HW_MECHANISMS"},
5012 +{ ERR_PACK(0, PK11_F_INIT_SYMMETRIC, 0),       "PK11_INIT_SYMMETRIC"},
5013 +{ ERR_PACK(0, PK11_F_ADD_AES_CTR_NIDS, 0),     "PK11_ADD_AES_CTR_NIDS"},
5014 +{ ERR_PACK(0, PK11_F_INIT_ALL_LOCKS, 0),       "PK11_INIT_ALL_LOCKS"},
5015 +{ ERR_PACK(0, PK11_F_RETURN_SESSION, 0),       "PK11_RETURN_SESSION"},
5016 +{ ERR_PACK(0, PK11_F_GET_PIN, 0),              "PK11_GET_PIN"},
5017 +{ ERR_PACK(0, PK11_F_FIND_ONE_OBJECT, 0),      "PK11_FIND_ONE_OBJECT"},
5018 +{ ERR_PACK(0, PK11_F_CHECK_TOKEN_ATTRS, 0),    "PK11_CHECK_TOKEN_ATTRS"},
5019 +{ ERR_PACK(0, PK11_F_CACHE_PIN, 0),            "PK11_CACHE_PIN"},
5020 +{ ERR_PACK(0, PK11_F_MLOCK_PIN_IN_MEMORY, 0),  "PK11_MLOCK_PIN_IN_MEMORY"},
5021 +{ ERR_PACK(0, PK11_F_TOKEN_LOGIN, 0),          "PK11_TOKEN_LOGIN"},
5022 +{ ERR_PACK(0, PK11_F_TOKEN_RELOGIN, 0),                "PK11_TOKEN_RELOGIN"},
5023 +{ ERR_PACK(0, PK11_F_RUN_ASKPASS, 0),          "PK11_F_RUN_ASKPASS"},
5024 +{ 0, NULL}
5027 +static ERR_STRING_DATA pk11_str_reasons[]=
5029 +{ PK11_R_ALREADY_LOADED,               "PKCS#11 DSO already loaded"},
5030 +{ PK11_R_DSO_FAILURE,                  "unable to load PKCS#11 DSO"},
5031 +{ PK11_R_NOT_LOADED,                   "PKCS#11 DSO not loaded"},
5032 +{ PK11_R_PASSED_NULL_PARAMETER,                "null parameter passed"},
5033 +{ PK11_R_COMMAND_NOT_IMPLEMENTED,      "command not implemented"},
5034 +{ PK11_R_INITIALIZE,                   "C_Initialize failed"},
5035 +{ PK11_R_FINALIZE,                     "C_Finalize failed"},
5036 +{ PK11_R_GETINFO,                      "C_GetInfo faile"},
5037 +{ PK11_R_GETSLOTLIST,                  "C_GetSlotList failed"},
5038 +{ PK11_R_NO_MODULUS_OR_NO_EXPONENT,    "no modulus or no exponent"},
5039 +{ PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID,        "attr sensitive or invalid"},
5040 +{ PK11_R_GETATTRIBUTVALUE,             "C_GetAttributeValue failed"},
5041 +{ PK11_R_NO_MODULUS,                   "no modulus"},
5042 +{ PK11_R_NO_EXPONENT,                  "no exponent"},
5043 +{ PK11_R_FINDOBJECTSINIT,              "C_FindObjectsInit failed"},
5044 +{ PK11_R_FINDOBJECTS,                  "C_FindObjects failed"},
5045 +{ PK11_R_FINDOBJECTSFINAL,             "C_FindObjectsFinal failed"},
5046 +{ PK11_R_CREATEOBJECT,                 "C_CreateObject failed"},
5047 +{ PK11_R_DESTROYOBJECT,                        "C_DestroyObject failed"},
5048 +{ PK11_R_OPENSESSION,                  "C_OpenSession failed"},
5049 +{ PK11_R_CLOSESESSION,                 "C_CloseSession failed"},
5050 +{ PK11_R_ENCRYPTINIT,                  "C_EncryptInit failed"},
5051 +{ PK11_R_ENCRYPT,                      "C_Encrypt failed"},
5052 +{ PK11_R_SIGNINIT,                     "C_SignInit failed"},
5053 +{ PK11_R_SIGN,                         "C_Sign failed"},
5054 +{ PK11_R_DECRYPTINIT,                  "C_DecryptInit failed"},
5055 +{ PK11_R_DECRYPT,                      "C_Decrypt failed"},
5056 +{ PK11_R_VERIFYINIT,                   "C_VerifyRecover failed"},
5057 +{ PK11_R_VERIFY,                       "C_Verify failed"},
5058 +{ PK11_R_VERIFYRECOVERINIT,            "C_VerifyRecoverInit failed"},
5059 +{ PK11_R_VERIFYRECOVER,                        "C_VerifyRecover failed"},
5060 +{ PK11_R_GEN_KEY,                      "C_GenerateKeyPair failed"},
5061 +{ PK11_R_SEEDRANDOM,                   "C_SeedRandom failed"},
5062 +{ PK11_R_GENERATERANDOM,               "C_GenerateRandom failed"},
5063 +{ PK11_R_INVALID_MESSAGE_LENGTH,       "invalid message length"},
5064 +{ PK11_R_UNKNOWN_ALGORITHM_TYPE,       "unknown algorithm type"},
5065 +{ PK11_R_UNKNOWN_ASN1_OBJECT_ID,       "unknown asn1 onject id"},
5066 +{ PK11_R_UNKNOWN_PADDING_TYPE,         "unknown padding type"},
5067 +{ PK11_R_PADDING_CHECK_FAILED,         "padding check failed"},
5068 +{ PK11_R_DIGEST_TOO_BIG,               "digest too big"},
5069 +{ PK11_R_MALLOC_FAILURE,               "malloc failure"},
5070 +{ PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED, "ctl command not implemented"},
5071 +{ PK11_R_DATA_GREATER_THAN_MOD_LEN,    "data is bigger than mod"},
5072 +{ PK11_R_DATA_TOO_LARGE_FOR_MODULUS,   "data is too larger for mod"},
5073 +{ PK11_R_MISSING_KEY_COMPONENT,                "a dsa component is missing"},
5074 +{ PK11_R_INVALID_SIGNATURE_LENGTH,     "invalid signature length"},
5075 +{ PK11_R_INVALID_DSA_SIGNATURE_R,      "missing r in dsa verify"},
5076 +{ PK11_R_INVALID_DSA_SIGNATURE_S,      "missing s in dsa verify"},
5077 +{ PK11_R_INCONSISTENT_KEY,             "inconsistent key type"},
5078 +{ PK11_R_ENCRYPTUPDATE,                        "C_EncryptUpdate failed"},
5079 +{ PK11_R_DECRYPTUPDATE,                        "C_DecryptUpdate failed"},
5080 +{ PK11_R_DIGESTINIT,                   "C_DigestInit failed"},
5081 +{ PK11_R_DIGESTUPDATE,                 "C_DigestUpdate failed"},
5082 +{ PK11_R_DIGESTFINAL,                  "C_DigestFinal failed"},
5083 +{ PK11_R_ENCRYPTFINAL,                 "C_EncryptFinal failed"},
5084 +{ PK11_R_DECRYPTFINAL,                 "C_DecryptFinal failed"},
5085 +{ PK11_R_NO_PRNG_SUPPORT,              "Slot does not support PRNG"},
5086 +{ PK11_R_GETTOKENINFO,                 "C_GetTokenInfo failed"},
5087 +{ PK11_R_DERIVEKEY,                    "C_DeriveKey failed"},
5088 +{ PK11_R_GET_OPERATION_STATE,          "C_GetOperationState failed"},
5089 +{ PK11_R_SET_OPERATION_STATE,          "C_SetOperationState failed"},
5090 +{ PK11_R_INVALID_HANDLE,               "invalid PKCS#11 object handle"},
5091 +{ PK11_R_KEY_OR_IV_LEN_PROBLEM,                "IV or key length incorrect"},
5092 +{ PK11_R_INVALID_OPERATION_TYPE,       "invalid operation type"},
5093 +{ PK11_R_ADD_NID_FAILED,               "failed to add NID" },
5094 +{ PK11_R_ATFORK_FAILED,                        "atfork() failed" },
5095 +{ PK11_R_TOKEN_LOGIN_FAILED,           "C_Login() failed on token" },
5096 +{ PK11_R_MORE_THAN_ONE_OBJECT_FOUND,   "more than one object found" },
5097 +{ PK11_R_INVALID_PKCS11_URI,           "pkcs11 URI provided is invalid" },
5098 +{ PK11_R_COULD_NOT_READ_PIN,           "could not read PIN from terminal" },
5099 +{ PK11_R_PIN_NOT_READ_FROM_COMMAND,    "PIN not read from external command" },
5100 +{ PK11_R_COULD_NOT_OPEN_COMMAND,       "could not popen() dialog command" },
5101 +{ PK11_R_PIPE_FAILED,                  "pipe() failed" },
5102 +{ PK11_R_BAD_PASSPHRASE_SPEC,          "bad passphrasedialog specification" },
5103 +{ PK11_R_TOKEN_NOT_INITIALIZED,                "token not initialized" },
5104 +{ PK11_R_TOKEN_PIN_NOT_SET,            "token PIN required but not set" },
5105 +{ PK11_R_TOKEN_PIN_NOT_PROVIDED,       "token PIN required but not provided" },
5106 +{ PK11_R_MISSING_OBJECT_LABEL,         "missing mandatory 'object' keyword" },
5107 +{ PK11_R_TOKEN_ATTRS_DO_NOT_MATCH,     "token attrs provided do not match" },
5108 +{ PK11_R_PRIV_KEY_NOT_FOUND,           "private key not found in keystore" },
5109 +{ PK11_R_NO_OBJECT_FOUND,              "specified object not found" },
5110 +{ PK11_R_PIN_CACHING_POLICY_INVALID,   "PIN set but caching policy invalid" },
5111 +{ PK11_R_SYSCONF_FAILED,               "sysconf() failed" },
5112 +{ PK11_R_MMAP_FAILED,                  "mmap() failed" },
5113 +{ PK11_R_PRIV_PROC_LOCK_MEMORY_MISSING,        "PROC_LOCK_MEMORY privilege missing" },
5114 +{ PK11_R_MLOCK_FAILED,                 "mlock() failed" },
5115 +{ PK11_R_FORK_FAILED,                  "fork() failed" },
5116 +{ 0,   NULL}
5118 +#endif /* OPENSSL_NO_ERR */
5120 +static int pk11_lib_error_code = 0;
5121 +static int pk11_error_init = 1;
5123 +static void
5124 +ERR_load_pk11_strings(void)
5125 +       {
5126 +       if (pk11_lib_error_code == 0)
5127 +               pk11_lib_error_code = ERR_get_next_error_library();
5129 +       if (pk11_error_init)
5130 +               {
5131 +               pk11_error_init = 0;
5132 +#ifndef OPENSSL_NO_ERR
5133 +               ERR_load_strings(pk11_lib_error_code, pk11_str_functs);
5134 +               ERR_load_strings(pk11_lib_error_code, pk11_str_reasons);
5135 +#endif
5136 +               }
5139 +static void
5140 +ERR_unload_pk11_strings(void)
5141 +       {
5142 +       if (pk11_error_init == 0)
5143 +               {
5144 +#ifndef OPENSSL_NO_ERR
5145 +               ERR_unload_strings(pk11_lib_error_code, pk11_str_functs);
5146 +               ERR_unload_strings(pk11_lib_error_code, pk11_str_reasons);
5147 +#endif
5148 +               pk11_error_init = 1;
5149 +               }
5152 +void
5153 +ERR_pk11_error(int function, int reason, char *file, int line)
5155 +       if (pk11_lib_error_code == 0)
5156 +               pk11_lib_error_code = ERR_get_next_error_library();
5157 +       ERR_PUT_error(pk11_lib_error_code, function, reason, file, line);
5160 +void
5161 +PK11err_add_data(int function, int reason, CK_RV rv)
5163 +       char tmp_buf[20];
5165 +       PK11err(function, reason);
5166 +       (void) BIO_snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
5167 +       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
5169 Index: openssl/crypto/engine/hw_pk11_err.h
5170 diff -u /dev/null openssl/crypto/engine/hw_pk11_err.h:1.12.4.1
5171 --- /dev/null   Fri Jan  2 14:26:16 2015
5172 +++ openssl/crypto/engine/hw_pk11_err.h Fri Oct  4 14:33:56 2013
5173 @@ -0,0 +1,440 @@
5175 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
5176 + * Use is subject to license terms.
5177 + */
5180 + * This product includes software developed by the OpenSSL Project for
5181 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
5182 + *
5183 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
5184 + * Afchine Madjlessi.
5185 + */
5187 + * ====================================================================
5188 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
5189 + *
5190 + * Redistribution and use in source and binary forms, with or without
5191 + * modification, are permitted provided that the following conditions
5192 + * are met:
5193 + *
5194 + * 1. Redistributions of source code must retain the above copyright
5195 + *    notice, this list of conditions and the following disclaimer.
5196 + *
5197 + * 2. Redistributions in binary form must reproduce the above copyright
5198 + *    notice, this list of conditions and the following disclaimer in
5199 + *    the documentation and/or other materials provided with the
5200 + *    distribution.
5201 + *
5202 + * 3. All advertising materials mentioning features or use of this
5203 + *    software must display the following acknowledgment:
5204 + *    "This product includes software developed by the OpenSSL Project
5205 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
5206 + *
5207 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
5208 + *    endorse or promote products derived from this software without
5209 + *    prior written permission. For written permission, please contact
5210 + *    licensing@OpenSSL.org.
5211 + *
5212 + * 5. Products derived from this software may not be called "OpenSSL"
5213 + *    nor may "OpenSSL" appear in their names without prior written
5214 + *    permission of the OpenSSL Project.
5215 + *
5216 + * 6. Redistributions of any form whatsoever must retain the following
5217 + *    acknowledgment:
5218 + *    "This product includes software developed by the OpenSSL Project
5219 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
5220 + *
5221 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
5222 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5223 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
5224 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
5225 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
5226 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
5227 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5228 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5229 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
5230 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
5231 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
5232 + * OF THE POSSIBILITY OF SUCH DAMAGE.
5233 + * ====================================================================
5234 + *
5235 + * This product includes cryptographic software written by Eric Young
5236 + * (eay@cryptsoft.com).  This product includes software written by Tim
5237 + * Hudson (tjh@cryptsoft.com).
5238 + *
5239 + */
5241 +#ifndef        HW_PK11_ERR_H
5242 +#define        HW_PK11_ERR_H
5244 +void ERR_pk11_error(int function, int reason, char *file, int line);
5245 +void PK11err_add_data(int function, int reason, CK_RV rv);
5246 +#define        PK11err(f, r)   ERR_pk11_error((f), (r), __FILE__, __LINE__)
5248 +/* Error codes for the PK11 functions. */
5250 +/* Function codes. */
5252 +#define        PK11_F_INIT                             100
5253 +#define        PK11_F_FINISH                           101
5254 +#define        PK11_F_DESTROY                          102
5255 +#define        PK11_F_CTRL                             103
5256 +#define        PK11_F_RSA_INIT                         104
5257 +#define        PK11_F_RSA_FINISH                       105
5258 +#define        PK11_F_GET_PUB_RSA_KEY                  106
5259 +#define        PK11_F_GET_PRIV_RSA_KEY                 107
5260 +#define        PK11_F_RSA_GEN_KEY                      108
5261 +#define        PK11_F_RSA_PUB_ENC                      109
5262 +#define        PK11_F_RSA_PRIV_ENC                     110
5263 +#define        PK11_F_RSA_PUB_DEC                      111
5264 +#define        PK11_F_RSA_PRIV_DEC                     112
5265 +#define        PK11_F_RSA_SIGN                         113
5266 +#define        PK11_F_RSA_VERIFY                       114
5267 +#define        PK11_F_RAND_ADD                         115
5268 +#define        PK11_F_RAND_BYTES                       116
5269 +#define        PK11_F_GET_SESSION                      117
5270 +#define        PK11_F_FREE_SESSION                     118
5271 +#define        PK11_F_LOAD_PUBKEY                      119
5272 +#define        PK11_F_LOAD_PRIVKEY                     120
5273 +#define        PK11_F_RSA_PUB_ENC_LOW                  121
5274 +#define        PK11_F_RSA_PRIV_ENC_LOW                 122
5275 +#define        PK11_F_RSA_PUB_DEC_LOW                  123
5276 +#define        PK11_F_RSA_PRIV_DEC_LOW                 124
5277 +#define        PK11_F_DSA_SIGN                         125
5278 +#define        PK11_F_DSA_VERIFY                       126
5279 +#define        PK11_F_DSA_INIT                         127
5280 +#define        PK11_F_DSA_FINISH                       128
5281 +#define        PK11_F_GET_PUB_DSA_KEY                  129
5282 +#define        PK11_F_GET_PRIV_DSA_KEY                 130
5283 +#define        PK11_F_DH_INIT                          131
5284 +#define        PK11_F_DH_FINISH                        132
5285 +#define        PK11_F_MOD_EXP_DH                       133
5286 +#define        PK11_F_GET_DH_KEY                       134
5287 +#define        PK11_F_FREE_ALL_SESSIONS                135
5288 +#define        PK11_F_SETUP_SESSION                    136
5289 +#define        PK11_F_DESTROY_OBJECT                   137
5290 +#define        PK11_F_CIPHER_INIT                      138
5291 +#define        PK11_F_CIPHER_DO_CIPHER                 139
5292 +#define        PK11_F_GET_CIPHER_KEY                   140
5293 +#define        PK11_F_DIGEST_INIT                      141
5294 +#define        PK11_F_DIGEST_UPDATE                    142
5295 +#define        PK11_F_DIGEST_FINAL                     143
5296 +#define        PK11_F_CHOOSE_SLOT                      144
5297 +#define        PK11_F_CIPHER_FINAL                     145
5298 +#define        PK11_F_LIBRARY_INIT                     146
5299 +#define        PK11_F_LOAD                             147
5300 +#define        PK11_F_DH_GEN_KEY                       148
5301 +#define        PK11_F_DH_COMP_KEY                      149
5302 +#define        PK11_F_DIGEST_COPY                      150
5303 +#define        PK11_F_CIPHER_CLEANUP                   151
5304 +#define        PK11_F_ACTIVE_ADD                       152
5305 +#define        PK11_F_ACTIVE_DELETE                    153
5306 +#define        PK11_F_CHECK_HW_MECHANISMS              154
5307 +#define        PK11_F_INIT_SYMMETRIC                   155
5308 +#define        PK11_F_ADD_AES_CTR_NIDS                 156
5309 +#define        PK11_F_INIT_ALL_LOCKS                   157
5310 +#define        PK11_F_RETURN_SESSION                   158
5311 +#define        PK11_F_GET_PIN                          159
5312 +#define        PK11_F_FIND_ONE_OBJECT                  160
5313 +#define        PK11_F_CHECK_TOKEN_ATTRS                161
5314 +#define        PK11_F_CACHE_PIN                        162
5315 +#define        PK11_F_MLOCK_PIN_IN_MEMORY              163
5316 +#define        PK11_F_TOKEN_LOGIN                      164
5317 +#define        PK11_F_TOKEN_RELOGIN                    165
5318 +#define        PK11_F_RUN_ASKPASS                      166
5320 +/* Reason codes. */
5321 +#define        PK11_R_ALREADY_LOADED                   100
5322 +#define        PK11_R_DSO_FAILURE                      101
5323 +#define        PK11_R_NOT_LOADED                       102
5324 +#define        PK11_R_PASSED_NULL_PARAMETER            103
5325 +#define        PK11_R_COMMAND_NOT_IMPLEMENTED          104
5326 +#define        PK11_R_INITIALIZE                       105
5327 +#define        PK11_R_FINALIZE                         106
5328 +#define        PK11_R_GETINFO                          107
5329 +#define        PK11_R_GETSLOTLIST                      108
5330 +#define        PK11_R_NO_MODULUS_OR_NO_EXPONENT        109
5331 +#define        PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID    110
5332 +#define        PK11_R_GETATTRIBUTVALUE                 111
5333 +#define        PK11_R_NO_MODULUS                       112
5334 +#define        PK11_R_NO_EXPONENT                      113
5335 +#define        PK11_R_FINDOBJECTSINIT                  114
5336 +#define        PK11_R_FINDOBJECTS                      115
5337 +#define        PK11_R_FINDOBJECTSFINAL                 116
5338 +#define        PK11_R_CREATEOBJECT                     118
5339 +#define        PK11_R_DESTROYOBJECT                    119
5340 +#define        PK11_R_OPENSESSION                      120
5341 +#define        PK11_R_CLOSESESSION                     121
5342 +#define        PK11_R_ENCRYPTINIT                      122
5343 +#define        PK11_R_ENCRYPT                          123
5344 +#define        PK11_R_SIGNINIT                         124
5345 +#define        PK11_R_SIGN                             125
5346 +#define        PK11_R_DECRYPTINIT                      126
5347 +#define        PK11_R_DECRYPT                          127
5348 +#define        PK11_R_VERIFYINIT                       128
5349 +#define        PK11_R_VERIFY                           129
5350 +#define        PK11_R_VERIFYRECOVERINIT                130
5351 +#define        PK11_R_VERIFYRECOVER                    131
5352 +#define        PK11_R_GEN_KEY                          132
5353 +#define        PK11_R_SEEDRANDOM                       133
5354 +#define        PK11_R_GENERATERANDOM                   134
5355 +#define        PK11_R_INVALID_MESSAGE_LENGTH           135
5356 +#define        PK11_R_UNKNOWN_ALGORITHM_TYPE           136
5357 +#define        PK11_R_UNKNOWN_ASN1_OBJECT_ID           137
5358 +#define        PK11_R_UNKNOWN_PADDING_TYPE             138
5359 +#define        PK11_R_PADDING_CHECK_FAILED             139
5360 +#define        PK11_R_DIGEST_TOO_BIG                   140
5361 +#define        PK11_R_MALLOC_FAILURE                   141
5362 +#define        PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED     142
5363 +#define        PK11_R_DATA_GREATER_THAN_MOD_LEN        143
5364 +#define        PK11_R_DATA_TOO_LARGE_FOR_MODULUS       144
5365 +#define        PK11_R_MISSING_KEY_COMPONENT            145
5366 +#define        PK11_R_INVALID_SIGNATURE_LENGTH         146
5367 +#define        PK11_R_INVALID_DSA_SIGNATURE_R          147
5368 +#define        PK11_R_INVALID_DSA_SIGNATURE_S          148
5369 +#define        PK11_R_INCONSISTENT_KEY                 149
5370 +#define        PK11_R_ENCRYPTUPDATE                    150
5371 +#define        PK11_R_DECRYPTUPDATE                    151
5372 +#define        PK11_R_DIGESTINIT                       152
5373 +#define        PK11_R_DIGESTUPDATE                     153
5374 +#define        PK11_R_DIGESTFINAL                      154
5375 +#define        PK11_R_ENCRYPTFINAL                     155
5376 +#define        PK11_R_DECRYPTFINAL                     156
5377 +#define        PK11_R_NO_PRNG_SUPPORT                  157
5378 +#define        PK11_R_GETTOKENINFO                     158
5379 +#define        PK11_R_DERIVEKEY                        159
5380 +#define        PK11_R_GET_OPERATION_STATE              160
5381 +#define        PK11_R_SET_OPERATION_STATE              161
5382 +#define        PK11_R_INVALID_HANDLE                   162
5383 +#define        PK11_R_KEY_OR_IV_LEN_PROBLEM            163
5384 +#define        PK11_R_INVALID_OPERATION_TYPE           164
5385 +#define        PK11_R_ADD_NID_FAILED                   165
5386 +#define        PK11_R_ATFORK_FAILED                    166
5388 +#define        PK11_R_TOKEN_LOGIN_FAILED               167
5389 +#define        PK11_R_MORE_THAN_ONE_OBJECT_FOUND       168
5390 +#define        PK11_R_INVALID_PKCS11_URI               169
5391 +#define        PK11_R_COULD_NOT_READ_PIN               170
5392 +#define        PK11_R_COULD_NOT_OPEN_COMMAND           171
5393 +#define        PK11_R_PIPE_FAILED                      172
5394 +#define        PK11_R_PIN_NOT_READ_FROM_COMMAND        173
5395 +#define        PK11_R_BAD_PASSPHRASE_SPEC              174
5396 +#define        PK11_R_TOKEN_NOT_INITIALIZED            175
5397 +#define        PK11_R_TOKEN_PIN_NOT_SET                176
5398 +#define        PK11_R_TOKEN_PIN_NOT_PROVIDED           177
5399 +#define        PK11_R_MISSING_OBJECT_LABEL             178
5400 +#define        PK11_R_TOKEN_ATTRS_DO_NOT_MATCH         179
5401 +#define        PK11_R_PRIV_KEY_NOT_FOUND               180
5402 +#define        PK11_R_NO_OBJECT_FOUND                  181
5403 +#define        PK11_R_PIN_CACHING_POLICY_INVALID       182
5404 +#define        PK11_R_SYSCONF_FAILED                   183
5405 +#define        PK11_R_MMAP_FAILED                      183
5406 +#define        PK11_R_PRIV_PROC_LOCK_MEMORY_MISSING    184
5407 +#define        PK11_R_MLOCK_FAILED                     185
5408 +#define        PK11_R_FORK_FAILED                      186
5410 +/* max byte length of a symetric key we support */
5411 +#define        PK11_KEY_LEN_MAX                        32
5413 +#ifdef NOPTHREADS
5415 + * CRYPTO_LOCK_PK11_ENGINE lock is primarily used for the protection of the
5416 + * free_session list and active_list but generally serves as a global
5417 + * per-process lock for the whole engine.
5418 + *
5419 + * We reuse CRYPTO_LOCK_EC lock (which is defined in OpenSSL for EC method) as
5420 + * the global engine lock. This is not optimal w.r.t. performance but
5421 + * it's safe.
5422 + */
5423 +#define CRYPTO_LOCK_PK11_ENGINE        CRYPTO_LOCK_EC
5424 +#endif
5427 + * This structure encapsulates all reusable information for a PKCS#11
5428 + * session. A list of these objects is created on behalf of the
5429 + * calling application using an on-demand method. Each operation
5430 + * type (see PK11_OPTYPE below) has its own per-process list.
5431 + * Each of the lists is basically a cache for faster PKCS#11 object
5432 + * access to avoid expensive C_Find{,Init,Final}Object() calls.
5433 + *
5434 + * When a new request comes in, an object will be taken from the list
5435 + * (if there is one) or a new one is created to handle the request
5436 + * (if the list is empty). See pk11_get_session() on how it is done.
5437 + */
5438 +typedef struct PK11_st_SESSION
5439 +       {
5440 +       struct PK11_st_SESSION  *next;
5441 +       CK_SESSION_HANDLE       session;        /* PK11 session handle */
5442 +       pid_t                   pid;            /* Current process ID */
5443 +       CK_BBOOL                pub_persistent; /* is pub key in keystore? */
5444 +       CK_BBOOL                priv_persistent;/* is priv key in keystore? */
5445 +       union
5446 +               {
5447 +#ifndef OPENSSL_NO_RSA
5448 +               struct
5449 +                       {
5450 +                       CK_OBJECT_HANDLE        rsa_pub_key; /* pub handle */
5451 +                       CK_OBJECT_HANDLE        rsa_priv_key; /* priv handle */
5452 +                       RSA                     *rsa_pub; /* pub key addr */
5453 +                       BIGNUM                  *rsa_n_num; /* pub modulus */
5454 +                       BIGNUM                  *rsa_e_num; /* pub exponent */
5455 +                       RSA                     *rsa_priv; /* priv key addr */
5456 +                       BIGNUM                  *rsa_pn_num; /* pub modulus */
5457 +                       BIGNUM                  *rsa_pe_num; /* pub exponent */
5458 +                       BIGNUM                  *rsa_d_num; /* priv exponent */
5459 +                       } u_RSA;
5460 +#endif /* OPENSSL_NO_RSA */
5461 +#ifndef OPENSSL_NO_DSA
5462 +               struct
5463 +                       {
5464 +                       CK_OBJECT_HANDLE        dsa_pub_key; /* pub handle */
5465 +                       CK_OBJECT_HANDLE        dsa_priv_key; /* priv handle */
5466 +                       DSA                     *dsa_pub; /* pub key addr */
5467 +                       BIGNUM                  *dsa_pub_num; /* pub key */
5468 +                       DSA                     *dsa_priv; /* priv key addr */
5469 +                       BIGNUM                  *dsa_priv_num; /* priv key */
5470 +                       } u_DSA;
5471 +#endif /* OPENSSL_NO_DSA */
5472 +#ifndef OPENSSL_NO_DH
5473 +               struct
5474 +                       {
5475 +                       CK_OBJECT_HANDLE        dh_key; /* key handle */
5476 +                       DH                      *dh; /* dh key addr */
5477 +                       BIGNUM                  *dh_priv_num; /* priv dh key */
5478 +                       } u_DH;
5479 +#endif /* OPENSSL_NO_DH */
5480 +               struct
5481 +                       {
5482 +                       CK_OBJECT_HANDLE        cipher_key; /* key handle */
5483 +                       unsigned char           key[PK11_KEY_LEN_MAX];
5484 +                       int                     key_len; /* priv key len */
5485 +                       int                     encrypt; /* 1/0 enc/decr */
5486 +                       } u_cipher;
5487 +               } opdata_u;
5488 +       } PK11_SESSION;
5490 +#define        opdata_rsa_pub_key      opdata_u.u_RSA.rsa_pub_key
5491 +#define        opdata_rsa_priv_key     opdata_u.u_RSA.rsa_priv_key
5492 +#define        opdata_rsa_pub          opdata_u.u_RSA.rsa_pub
5493 +#define        opdata_rsa_priv         opdata_u.u_RSA.rsa_priv
5494 +#define        opdata_rsa_n_num        opdata_u.u_RSA.rsa_n_num
5495 +#define        opdata_rsa_e_num        opdata_u.u_RSA.rsa_e_num
5496 +#define        opdata_rsa_pn_num       opdata_u.u_RSA.rsa_pn_num
5497 +#define        opdata_rsa_pe_num       opdata_u.u_RSA.rsa_pe_num
5498 +#define        opdata_rsa_d_num        opdata_u.u_RSA.rsa_d_num
5499 +#define        opdata_dsa_pub_key      opdata_u.u_DSA.dsa_pub_key
5500 +#define        opdata_dsa_priv_key     opdata_u.u_DSA.dsa_priv_key
5501 +#define        opdata_dsa_pub          opdata_u.u_DSA.dsa_pub
5502 +#define        opdata_dsa_pub_num      opdata_u.u_DSA.dsa_pub_num
5503 +#define        opdata_dsa_priv         opdata_u.u_DSA.dsa_priv
5504 +#define        opdata_dsa_priv_num     opdata_u.u_DSA.dsa_priv_num
5505 +#define        opdata_dh_key           opdata_u.u_DH.dh_key
5506 +#define        opdata_dh               opdata_u.u_DH.dh
5507 +#define        opdata_dh_priv_num      opdata_u.u_DH.dh_priv_num
5508 +#define        opdata_cipher_key       opdata_u.u_cipher.cipher_key
5509 +#define        opdata_key              opdata_u.u_cipher.key
5510 +#define        opdata_key_len          opdata_u.u_cipher.key_len
5511 +#define        opdata_encrypt          opdata_u.u_cipher.encrypt
5514 + * We have 3 different groups of operation types:
5515 + *   1) asymmetric operations
5516 + *   2) random operations
5517 + *   3) symmetric and digest operations
5518 + *
5519 + * This division into groups stems from the fact that it's common that hardware
5520 + * providers may support operations from one group only. For example, hardware
5521 + * providers on UltraSPARC T2, n2rng(7d), ncp(7d), and n2cp(7d), each support
5522 + * only a single group of operations.
5523 + *
5524 + * For every group a different slot can be chosen. That means that we must have
5525 + * at least 3 different lists of cached PKCS#11 sessions since sessions from
5526 + * different groups may be initialized in different slots.
5527 + *
5528 + * To provide locking granularity in multithreaded environment, the groups are
5529 + * further splitted into types with each type having a separate session cache.
5530 + */
5531 +typedef enum PK11_OPTYPE_ENUM
5532 +       {
5533 +       OP_RAND,
5534 +       OP_RSA,
5535 +       OP_DSA,
5536 +       OP_DH,
5537 +       OP_CIPHER,
5538 +       OP_DIGEST,
5539 +       OP_MAX
5540 +       } PK11_OPTYPE;
5543 + * This structure contains the heads of the lists forming the object caches
5544 + * and locks associated with the lists.
5545 + */
5546 +typedef struct PK11_st_CACHE
5547 +       {
5548 +       PK11_SESSION *head;
5549 +#ifndef NOPTHREADS
5550 +       pthread_mutex_t *lock;
5551 +#endif
5552 +       } PK11_CACHE;
5554 +/* structure for tracking handles of asymmetric key objects */
5555 +typedef struct PK11_active_st
5556 +       {
5557 +       CK_OBJECT_HANDLE h;
5558 +       unsigned int refcnt;
5559 +       struct PK11_active_st *prev;
5560 +       struct PK11_active_st *next;
5561 +       } PK11_active;
5563 +#ifndef NOPTHREADS
5564 +extern pthread_mutex_t *find_lock[];
5565 +#endif
5566 +extern PK11_active *active_list[];
5568 + * These variables are specific for the RSA keys by reference code. See
5569 + * hw_pk11_pub.c for explanation.
5570 + */
5571 +extern CK_FLAGS pubkey_token_flags;
5573 +#ifndef NOPTHREADS
5574 +#define        LOCK_OBJSTORE(alg_type) \
5575 +       OPENSSL_assert(pthread_mutex_lock(find_lock[alg_type]) == 0)
5576 +#define        UNLOCK_OBJSTORE(alg_type)       \
5577 +       OPENSSL_assert(pthread_mutex_unlock(find_lock[alg_type]) == 0)
5578 +#else
5579 +#define        LOCK_OBJSTORE(alg_type) \
5580 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE)
5581 +#define        UNLOCK_OBJSTORE(alg_type)       \
5582 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE)
5583 +#endif
5585 +extern PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
5586 +extern void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
5587 +extern int pk11_token_relogin(CK_SESSION_HANDLE session);
5589 +#ifndef OPENSSL_NO_RSA
5590 +extern int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
5591 +extern int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
5592 +extern int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
5593 +extern EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *pubkey_file,
5594 +       UI_METHOD *ui_method, void *callback_data);
5595 +extern EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
5596 +       UI_METHOD *ui_method, void *callback_data);
5597 +extern RSA_METHOD *PK11_RSA(void);
5598 +#endif /* OPENSSL_NO_RSA */
5599 +#ifndef OPENSSL_NO_DSA
5600 +extern int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
5601 +extern int pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
5602 +extern int pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
5603 +extern DSA_METHOD *PK11_DSA(void);
5604 +#endif /* OPENSSL_NO_DSA */
5605 +#ifndef OPENSSL_NO_DH
5606 +extern int pk11_destroy_dh_key_objects(PK11_SESSION *session);
5607 +extern int pk11_destroy_dh_object(PK11_SESSION *sp, CK_BBOOL uselock);
5608 +extern DH_METHOD *PK11_DH(void);
5609 +#endif /* OPENSSL_NO_DH */
5611 +extern CK_FUNCTION_LIST_PTR pFuncList;
5613 +#endif /* HW_PK11_ERR_H */
5614 Index: openssl/crypto/engine/hw_pk11_pub.c
5615 diff -u /dev/null openssl/crypto/engine/hw_pk11_pub.c:1.38.2.3
5616 --- /dev/null   Fri Jan  2 14:26:16 2015
5617 +++ openssl/crypto/engine/hw_pk11_pub.c Fri Oct  4 14:33:56 2013
5618 @@ -0,0 +1,3556 @@
5620 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
5621 + * Use is subject to license terms.
5622 + */
5624 +/* crypto/engine/hw_pk11_pub.c */
5626 + * This product includes software developed by the OpenSSL Project for
5627 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
5628 + *
5629 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
5630 + * Afchine Madjlessi.
5631 + */
5633 + * ====================================================================
5634 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
5635 + *
5636 + * Redistribution and use in source and binary forms, with or without
5637 + * modification, are permitted provided that the following conditions
5638 + * are met:
5639 + *
5640 + * 1. Redistributions of source code must retain the above copyright
5641 + *    notice, this list of conditions and the following disclaimer.
5642 + *
5643 + * 2. Redistributions in binary form must reproduce the above copyright
5644 + *    notice, this list of conditions and the following disclaimer in
5645 + *    the documentation and/or other materials provided with the
5646 + *    distribution.
5647 + *
5648 + * 3. All advertising materials mentioning features or use of this
5649 + *    software must display the following acknowledgment:
5650 + *    "This product includes software developed by the OpenSSL Project
5651 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
5652 + *
5653 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
5654 + *    endorse or promote products derived from this software without
5655 + *    prior written permission. For written permission, please contact
5656 + *    licensing@OpenSSL.org.
5657 + *
5658 + * 5. Products derived from this software may not be called "OpenSSL"
5659 + *    nor may "OpenSSL" appear in their names without prior written
5660 + *    permission of the OpenSSL Project.
5661 + *
5662 + * 6. Redistributions of any form whatsoever must retain the following
5663 + *    acknowledgment:
5664 + *    "This product includes software developed by the OpenSSL Project
5665 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
5666 + *
5667 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
5668 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5669 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
5670 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
5671 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
5672 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
5673 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5674 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5675 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
5676 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
5677 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
5678 + * OF THE POSSIBILITY OF SUCH DAMAGE.
5679 + * ====================================================================
5680 + *
5681 + * This product includes cryptographic software written by Eric Young
5682 + * (eay@cryptsoft.com).  This product includes software written by Tim
5683 + * Hudson (tjh@cryptsoft.com).
5684 + *
5685 + */
5687 +#include <stdio.h>
5688 +#include <stdlib.h>
5689 +#include <string.h>
5690 +#include <sys/types.h>
5692 +#include <openssl/e_os2.h>
5693 +#include <openssl/crypto.h>
5694 +#include <cryptlib.h>
5695 +#include <openssl/engine.h>
5696 +#include <openssl/dso.h>
5697 +#include <openssl/err.h>
5698 +#include <openssl/bn.h>
5699 +#include <openssl/pem.h>
5700 +#ifndef OPENSSL_NO_RSA
5701 +#include <openssl/rsa.h>
5702 +#endif /* OPENSSL_NO_RSA */
5703 +#ifndef OPENSSL_NO_DSA
5704 +#include <openssl/dsa.h>
5705 +#endif /* OPENSSL_NO_DSA */
5706 +#ifndef OPENSSL_NO_DH
5707 +#include <openssl/dh.h>
5708 +#endif /* OPENSSL_NO_DH */
5709 +#include <openssl/rand.h>
5710 +#include <openssl/objects.h>
5711 +#include <openssl/x509.h>
5713 +#ifdef OPENSSL_SYS_WIN32
5714 +#define NOPTHREADS
5715 +typedef int pid_t;
5716 +#define HAVE_GETPASSPHRASE
5717 +static char *getpassphrase(const char *prompt);
5718 +#ifndef NULL_PTR
5719 +#define NULL_PTR NULL
5720 +#endif
5721 +#define CK_DEFINE_FUNCTION(returnType, name) \
5722 +       returnType __declspec(dllexport) name
5723 +#define CK_DECLARE_FUNCTION(returnType, name) \
5724 +       returnType __declspec(dllimport) name
5725 +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
5726 +       returnType __declspec(dllimport) (* name)
5727 +#else
5728 +#include <unistd.h>
5729 +#endif
5731 +#ifndef NOPTHREADS
5732 +#include <pthread.h>
5733 +#endif
5735 +#ifndef OPENSSL_NO_HW
5736 +#ifndef OPENSSL_NO_HW_PK11
5737 +#ifndef OPENSSL_NO_HW_PK11CA
5739 +#ifdef OPENSSL_SYS_WIN32
5740 +#pragma pack(push, cryptoki, 1)
5741 +#include "cryptoki.h"
5742 +#include "pkcs11.h"
5743 +#pragma pack(pop, cryptoki)
5744 +#else
5745 +#include "cryptoki.h"
5746 +#include "pkcs11.h"
5747 +#endif
5748 +#include "hw_pk11ca.h"
5749 +#include "hw_pk11_err.h"
5751 +static CK_BBOOL pk11_login_done = CK_FALSE;
5752 +extern CK_SLOT_ID pubkey_SLOTID;
5753 +#ifndef NOPTHREADS
5754 +extern pthread_mutex_t *token_lock;
5755 +#endif
5757 +#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun)))
5758 +#define getpassphrase(x)       getpass(x)
5759 +#endif
5761 +#ifndef OPENSSL_NO_RSA
5762 +/* RSA stuff */
5763 +static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
5764 +       unsigned char *to, RSA *rsa, int padding);
5765 +static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
5766 +       unsigned char *to, RSA *rsa, int padding);
5767 +static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
5768 +       unsigned char *to, RSA *rsa, int padding);
5769 +static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
5770 +       unsigned char *to, RSA *rsa, int padding);
5771 +static int pk11_RSA_init(RSA *rsa);
5772 +static int pk11_RSA_finish(RSA *rsa);
5773 +static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
5774 +       unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
5775 +#if OPENSSL_VERSION_NUMBER < 0x10000000L
5776 +static int pk11_RSA_verify(int dtype, const unsigned char *m,
5777 +       unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
5778 +       const RSA *rsa);
5779 +#else
5780 +static int pk11_RSA_verify(int dtype, const unsigned char *m,
5781 +       unsigned int m_len, const unsigned char *sigbuf, unsigned int siglen,
5782 +       const RSA *rsa);
5783 +#endif
5784 +EVP_PKEY *pk11_load_privkey(ENGINE*, const char *privkey_file,
5785 +       UI_METHOD *ui_method, void *callback_data);
5786 +EVP_PKEY *pk11_load_pubkey(ENGINE*, const char *pubkey_file,
5787 +       UI_METHOD *ui_method, void *callback_data);
5789 +static int pk11_RSA_public_encrypt_low(int flen, const unsigned char *from,
5790 +       unsigned char *to, RSA *rsa);
5791 +static int pk11_RSA_private_encrypt_low(int flen, const unsigned char *from,
5792 +       unsigned char *to, RSA *rsa);
5793 +static int pk11_RSA_public_decrypt_low(int flen, const unsigned char *from,
5794 +       unsigned char *to, RSA *rsa);
5795 +static int pk11_RSA_private_decrypt_low(int flen, const unsigned char *from,
5796 +       unsigned char *to, RSA *rsa);
5798 +static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA* rsa, RSA** key_ptr,
5799 +       BIGNUM **rsa_n_num, BIGNUM **rsa_e_num, CK_SESSION_HANDLE session);
5800 +static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa, RSA** key_ptr,
5801 +       BIGNUM **rsa_d_num, BIGNUM **rsa_n_num, BIGNUM **rsa_e_num,
5802 +       CK_SESSION_HANDLE session);
5804 +static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa);
5805 +static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa);
5806 +#endif
5808 +/* DSA stuff */
5809 +#ifndef OPENSSL_NO_DSA
5810 +static int pk11_DSA_init(DSA *dsa);
5811 +static int pk11_DSA_finish(DSA *dsa);
5812 +static DSA_SIG *pk11_dsa_do_sign(const unsigned char *dgst, int dlen,
5813 +       DSA *dsa);
5814 +static int pk11_dsa_do_verify(const unsigned char *dgst, int dgst_len,
5815 +       DSA_SIG *sig, DSA *dsa);
5817 +static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa, DSA **key_ptr,
5818 +       BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session);
5819 +static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa, DSA **key_ptr,
5820 +       BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session);
5822 +static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa);
5823 +static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa);
5824 +#endif
5826 +/* DH stuff */
5827 +#ifndef OPENSSL_NO_DH
5828 +static int pk11_DH_init(DH *dh);
5829 +static int pk11_DH_finish(DH *dh);
5830 +static int pk11_DH_generate_key(DH *dh);
5831 +static int pk11_DH_compute_key(unsigned char *key,
5832 +       const BIGNUM *pub_key, DH *dh);
5834 +static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh, DH **key_ptr,
5835 +       BIGNUM **priv_key, CK_SESSION_HANDLE session);
5837 +static int check_new_dh_key(PK11_SESSION *sp, DH *dh);
5838 +#endif
5840 +static int find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
5841 +       CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey);
5842 +static int init_template_value(BIGNUM *bn, CK_VOID_PTR *pValue,
5843 +       CK_ULONG *ulValueLen);
5844 +static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn);
5846 +static int pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
5847 +       CK_BBOOL is_private);
5849 +/* Read mode string to be used for fopen() */
5850 +#if SOLARIS_OPENSSL
5851 +static char *read_mode_flags = "rF";
5852 +#else
5853 +static char *read_mode_flags = "r";
5854 +#endif
5857 + * increment/create reference for an asymmetric key handle via active list
5858 + * manipulation. If active list operation fails, unlock (if locked), set error
5859 + * variable and jump to the specified label.
5860 + */
5861 +#define        KEY_HANDLE_REFHOLD(key_handle, alg_type, unlock, var, label)    \
5862 +       {                                                               \
5863 +       if (pk11_active_add(key_handle, alg_type) < 0)                  \
5864 +               {                                                       \
5865 +               var = TRUE;                                             \
5866 +               if (unlock)                                             \
5867 +                       UNLOCK_OBJSTORE(alg_type);                      \
5868 +               goto label;                                             \
5869 +               }                                                       \
5870 +       }
5873 + * Find active list entry according to object handle and return pointer to the
5874 + * entry otherwise return NULL.
5875 + *
5876 + * This function presumes it is called with lock protecting the active list
5877 + * held.
5878 + */
5879 +static PK11_active *pk11_active_find(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
5880 +       {
5881 +       PK11_active *entry;
5883 +       for (entry = active_list[type]; entry != NULL; entry = entry->next)
5884 +               if (entry->h == h)
5885 +                       return (entry);
5887 +       return (NULL);
5888 +       }
5891 + * Search for an entry in the active list using PKCS#11 object handle as a
5892 + * search key and return refcnt of the found/created entry or -1 in case of
5893 + * failure.
5894 + *
5895 + * This function presumes it is called with lock protecting the active list
5896 + * held.
5897 + */
5898 +int
5899 +pk11_active_add(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
5900 +       {
5901 +       PK11_active *entry = NULL;
5903 +       if (h == CK_INVALID_HANDLE)
5904 +               {
5905 +               PK11err(PK11_F_ACTIVE_ADD, PK11_R_INVALID_HANDLE);
5906 +               return (-1);
5907 +               }
5909 +       /* search for entry in the active list */
5910 +       if ((entry = pk11_active_find(h, type)) != NULL)
5911 +               entry->refcnt++;
5912 +       else
5913 +               {
5914 +               /* not found, create new entry and add it to the list */
5915 +               entry = OPENSSL_malloc(sizeof (PK11_active));
5916 +               if (entry == NULL)
5917 +                       {
5918 +                       PK11err(PK11_F_ACTIVE_ADD, PK11_R_MALLOC_FAILURE);
5919 +                       return (-1);
5920 +                       }
5921 +               entry->h = h;
5922 +               entry->refcnt = 1;
5923 +               entry->prev = NULL;
5924 +               entry->next = NULL;
5925 +               /* connect the newly created entry to the list */
5926 +               if (active_list[type] == NULL)
5927 +                       active_list[type] = entry;
5928 +               else /* make the entry first in the list */
5929 +                       {
5930 +                       entry->next = active_list[type];
5931 +                       active_list[type]->prev = entry;
5932 +                       active_list[type] = entry;
5933 +                       }
5934 +               }
5936 +       return (entry->refcnt);
5937 +       }
5940 + * Remove active list entry from the list and free it.
5941 + *
5942 + * This function presumes it is called with lock protecting the active list
5943 + * held.
5944 + */
5945 +void
5946 +pk11_active_remove(PK11_active *entry, PK11_OPTYPE type)
5947 +       {
5948 +       PK11_active *prev_entry;
5950 +       /* remove the entry from the list and free it */
5951 +       if ((prev_entry = entry->prev) != NULL)
5952 +               {
5953 +               prev_entry->next = entry->next;
5954 +               if (entry->next != NULL)
5955 +                       entry->next->prev = prev_entry;
5956 +               }
5957 +       else
5958 +               {
5959 +               active_list[type] = entry->next;
5960 +               /* we were the first but not the only one */
5961 +               if (entry->next != NULL)
5962 +                       entry->next->prev = NULL;
5963 +               }
5965 +       /* sanitization */
5966 +       entry->h = CK_INVALID_HANDLE;
5967 +       entry->prev = NULL;
5968 +       entry->next = NULL;
5969 +       OPENSSL_free(entry);
5970 +       }
5972 +/* Free all entries from the active list. */
5973 +void
5974 +pk11_free_active_list(PK11_OPTYPE type)
5975 +       {
5976 +       PK11_active *entry;
5978 +       /* only for asymmetric types since only they have C_Find* locks. */
5979 +       switch (type)
5980 +               {
5981 +               case OP_RSA:
5982 +               case OP_DSA:
5983 +               case OP_DH:
5984 +                       break;
5985 +               default:
5986 +                       return;
5987 +               }
5989 +       /* see find_lock array definition for more info on object locking */
5990 +       LOCK_OBJSTORE(type);
5991 +       while ((entry = active_list[type]) != NULL)
5992 +               pk11_active_remove(entry, type);
5993 +       UNLOCK_OBJSTORE(type);
5994 +       }
5997 + * Search for active list entry associated with given PKCS#11 object handle,
5998 + * decrement its refcnt and if it drops to 0, disconnect the entry and free it.
5999 + *
6000 + * Return 1 if the PKCS#11 object associated with the entry has no references,
6001 + * return 0 if there is at least one reference, -1 on error.
6002 + *
6003 + * This function presumes it is called with lock protecting the active list
6004 + * held.
6005 + */
6006 +int
6007 +pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
6008 +       {
6009 +       PK11_active *entry = NULL;
6011 +       if ((entry = pk11_active_find(h, type)) == NULL)
6012 +               {
6013 +               PK11err(PK11_F_ACTIVE_DELETE, PK11_R_INVALID_HANDLE);
6014 +               return (-1);
6015 +               }
6017 +       OPENSSL_assert(entry->refcnt > 0);
6018 +       entry->refcnt--;
6019 +       if (entry->refcnt == 0)
6020 +               {
6021 +               pk11_active_remove(entry, type);
6022 +               return (1);
6023 +               }
6025 +       return (0);
6026 +       }
6028 +#ifndef OPENSSL_NO_RSA
6029 +/* Our internal RSA_METHOD that we provide pointers to */
6030 +static RSA_METHOD pk11_rsa =
6031 +       {
6032 +       "PKCS#11 RSA method",
6033 +       pk11_RSA_public_encrypt,                /* rsa_pub_encrypt */
6034 +       pk11_RSA_public_decrypt,                /* rsa_pub_decrypt */
6035 +       pk11_RSA_private_encrypt,               /* rsa_priv_encrypt */
6036 +       pk11_RSA_private_decrypt,               /* rsa_priv_decrypt */
6037 +       NULL,                                   /* rsa_mod_exp */
6038 +       NULL,                                   /* bn_mod_exp */
6039 +       pk11_RSA_init,                          /* init */
6040 +       pk11_RSA_finish,                        /* finish */
6041 +       RSA_FLAG_SIGN_VER,                      /* flags */
6042 +       NULL,                                   /* app_data */
6043 +       pk11_RSA_sign,                          /* rsa_sign */
6044 +       pk11_RSA_verify                         /* rsa_verify */
6045 +       };
6047 +RSA_METHOD *
6048 +PK11_RSA(void)
6049 +       {
6050 +       return (&pk11_rsa);
6051 +       }
6052 +#endif
6054 +#ifndef OPENSSL_NO_DSA
6055 +/* Our internal DSA_METHOD that we provide pointers to */
6056 +static DSA_METHOD pk11_dsa =
6057 +       {
6058 +       "PKCS#11 DSA method",
6059 +       pk11_dsa_do_sign,       /* dsa_do_sign */
6060 +       NULL,                   /* dsa_sign_setup */
6061 +       pk11_dsa_do_verify,     /* dsa_do_verify */
6062 +       NULL,                   /* dsa_mod_exp */
6063 +       NULL,                   /* bn_mod_exp */
6064 +       pk11_DSA_init,          /* init */
6065 +       pk11_DSA_finish,        /* finish */
6066 +       0,                      /* flags */
6067 +       NULL                    /* app_data */
6068 +       };
6070 +DSA_METHOD *
6071 +PK11_DSA(void)
6072 +       {
6073 +       return (&pk11_dsa);
6074 +       }
6075 +#endif
6077 +#ifndef OPENSSL_NO_DH
6079 + * PKCS #11 V2.20, section 11.2 specifies that the number of bytes needed for
6080 + * output buffer may somewhat exceed the precise number of bytes needed, but
6081 + * should not exceed it by a large amount. That may be caused, for example, by
6082 + * rounding it up to multiple of X in the underlying bignum library. 8 should be
6083 + * enough.
6084 + */
6085 +#define        DH_BUF_RESERVE  8
6087 +/* Our internal DH_METHOD that we provide pointers to */
6088 +static DH_METHOD pk11_dh =
6089 +       {
6090 +       "PKCS#11 DH method",
6091 +       pk11_DH_generate_key,   /* generate_key */
6092 +       pk11_DH_compute_key,    /* compute_key */
6093 +       NULL,                   /* bn_mod_exp */
6094 +       pk11_DH_init,           /* init */
6095 +       pk11_DH_finish,         /* finish */
6096 +       0,                      /* flags */
6097 +       NULL,                   /* app_data */
6098 +       NULL                    /* generate_params */
6099 +       };
6101 +DH_METHOD *
6102 +PK11_DH(void)
6103 +       {
6104 +       return (&pk11_dh);
6105 +       }
6106 +#endif
6108 +/* Size of an SSL signature: MD5+SHA1 */
6109 +#define        SSL_SIG_LENGTH          36
6111 +/* Lengths of DSA data and signature */
6112 +#define        DSA_DATA_LEN            20
6113 +#define        DSA_SIGNATURE_LEN       40
6115 +static CK_BBOOL mytrue = TRUE;
6116 +static CK_BBOOL myfalse = FALSE;
6118 +#ifndef OPENSSL_NO_RSA
6120 + * Similiar to OpenSSL to take advantage of the paddings. The goal is to
6121 + * support all paddings in this engine although PK11 library does not
6122 + * support all the paddings used in OpenSSL.
6123 + * The input errors should have been checked in the padding functions.
6124 + */
6125 +static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
6126 +               unsigned char *to, RSA *rsa, int padding)
6127 +       {
6128 +       int i, num = 0, r = -1;
6129 +       unsigned char *buf = NULL;
6131 +       num = BN_num_bytes(rsa->n);
6132 +       if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
6133 +               {
6134 +               RSAerr(PK11_F_RSA_PUB_ENC, PK11_R_MALLOC_FAILURE);
6135 +               goto err;
6136 +               }
6138 +       switch (padding)
6139 +               {
6140 +       case RSA_PKCS1_PADDING:
6141 +               i = RSA_padding_add_PKCS1_type_2(buf, num, from, flen);
6142 +               break;
6143 +#ifndef OPENSSL_NO_SHA
6144 +       case RSA_PKCS1_OAEP_PADDING:
6145 +               i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0);
6146 +               break;
6147 +#endif
6148 +       case RSA_SSLV23_PADDING:
6149 +               i = RSA_padding_add_SSLv23(buf, num, from, flen);
6150 +               break;
6151 +       case RSA_NO_PADDING:
6152 +               i = RSA_padding_add_none(buf, num, from, flen);
6153 +               break;
6154 +       default:
6155 +               RSAerr(PK11_F_RSA_PUB_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
6156 +               goto err;
6157 +               }
6158 +       if (i <= 0) goto err;
6160 +       /* PK11 functions are called here */
6161 +       r = pk11_RSA_public_encrypt_low(num, buf, to, rsa);
6162 +err:
6163 +       if (buf != NULL)
6164 +               {
6165 +               OPENSSL_cleanse(buf, num);
6166 +               OPENSSL_free(buf);
6167 +               }
6168 +       return (r);
6169 +       }
6173 + * Similar to Openssl to take advantage of the paddings. The input errors
6174 + * should be catched in the padding functions
6175 + */
6176 +static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
6177 +       unsigned char *to, RSA *rsa, int padding)
6178 +       {
6179 +       int i, num = 0, r = -1;
6180 +       unsigned char *buf = NULL;
6182 +       num = BN_num_bytes(rsa->n);
6183 +       if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
6184 +               {
6185 +               RSAerr(PK11_F_RSA_PRIV_ENC, PK11_R_MALLOC_FAILURE);
6186 +               goto err;
6187 +               }
6189 +       switch (padding)
6190 +               {
6191 +       case RSA_PKCS1_PADDING:
6192 +               i = RSA_padding_add_PKCS1_type_1(buf, num, from, flen);
6193 +               break;
6194 +       case RSA_NO_PADDING:
6195 +               i = RSA_padding_add_none(buf, num, from, flen);
6196 +               break;
6197 +       case RSA_SSLV23_PADDING:
6198 +       default:
6199 +               RSAerr(PK11_F_RSA_PRIV_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
6200 +               goto err;
6201 +               }
6202 +       if (i <= 0) goto err;
6204 +       /* PK11 functions are called here */
6205 +       r = pk11_RSA_private_encrypt_low(num, buf, to, rsa);
6206 +err:
6207 +       if (buf != NULL)
6208 +               {
6209 +               OPENSSL_cleanse(buf, num);
6210 +               OPENSSL_free(buf);
6211 +               }
6212 +       return (r);
6213 +       }
6215 +/* Similar to OpenSSL code. Input errors are also checked here */
6216 +static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
6217 +       unsigned char *to, RSA *rsa, int padding)
6218 +       {
6219 +       BIGNUM f;
6220 +       int j, num = 0, r = -1;
6221 +       unsigned char *p;
6222 +       unsigned char *buf = NULL;
6224 +       BN_init(&f);
6226 +       num = BN_num_bytes(rsa->n);
6228 +       if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
6229 +               {
6230 +               RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_MALLOC_FAILURE);
6231 +               goto err;
6232 +               }
6234 +       /*
6235 +        * This check was for equality but PGP does evil things
6236 +        * and chops off the top '0' bytes
6237 +        */
6238 +       if (flen > num)
6239 +               {
6240 +               RSAerr(PK11_F_RSA_PRIV_DEC,
6241 +                       PK11_R_DATA_GREATER_THAN_MOD_LEN);
6242 +               goto err;
6243 +               }
6245 +       /* make data into a big number */
6246 +       if (BN_bin2bn(from, (int)flen, &f) == NULL)
6247 +               goto err;
6249 +       if (BN_ucmp(&f, rsa->n) >= 0)
6250 +               {
6251 +               RSAerr(PK11_F_RSA_PRIV_DEC,
6252 +                       PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
6253 +               goto err;
6254 +               }
6256 +       /* PK11 functions are called here */
6257 +       r = pk11_RSA_private_decrypt_low(flen, from, buf, rsa);
6259 +       /*
6260 +        * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
6261 +        * Needs to skip these 0's paddings here.
6262 +        */
6263 +       for (j = 0; j < r; j++)
6264 +               if (buf[j] != 0)
6265 +                       break;
6267 +       p = buf + j;
6268 +       j = r - j;  /* j is only used with no-padding mode */
6270 +       switch (padding)
6271 +               {
6272 +       case RSA_PKCS1_PADDING:
6273 +               r = RSA_padding_check_PKCS1_type_2(to, num, p, j, num);
6274 +               break;
6275 +#ifndef OPENSSL_NO_SHA
6276 +       case RSA_PKCS1_OAEP_PADDING:
6277 +               r = RSA_padding_check_PKCS1_OAEP(to, num, p, j, num, NULL, 0);
6278 +               break;
6279 +#endif
6280 +       case RSA_SSLV23_PADDING:
6281 +               r = RSA_padding_check_SSLv23(to, num, p, j, num);
6282 +               break;
6283 +       case RSA_NO_PADDING:
6284 +               r = RSA_padding_check_none(to, num, p, j, num);
6285 +               break;
6286 +       default:
6287 +               RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
6288 +               goto err;
6289 +               }
6290 +       if (r < 0)
6291 +               RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_PADDING_CHECK_FAILED);
6293 +err:
6294 +       BN_clear_free(&f);
6295 +       if (buf != NULL)
6296 +               {
6297 +               OPENSSL_cleanse(buf, num);
6298 +               OPENSSL_free(buf);
6299 +               }
6300 +       return (r);
6301 +       }
6303 +/* Similar to OpenSSL code. Input errors are also checked here */
6304 +static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
6305 +       unsigned char *to, RSA *rsa, int padding)
6306 +       {
6307 +       BIGNUM f;
6308 +       int i, num = 0, r = -1;
6309 +       unsigned char *p;
6310 +       unsigned char *buf = NULL;
6312 +       BN_init(&f);
6313 +       num = BN_num_bytes(rsa->n);
6314 +       buf = (unsigned char *)OPENSSL_malloc(num);
6315 +       if (buf == NULL)
6316 +               {
6317 +               RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_MALLOC_FAILURE);
6318 +               goto err;
6319 +               }
6321 +       /*
6322 +        * This check was for equality but PGP does evil things
6323 +        * and chops off the top '0' bytes
6324 +        */
6325 +       if (flen > num)
6326 +               {
6327 +               RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_DATA_GREATER_THAN_MOD_LEN);
6328 +               goto err;
6329 +               }
6331 +       if (BN_bin2bn(from, flen, &f) == NULL)
6332 +               goto err;
6334 +       if (BN_ucmp(&f, rsa->n) >= 0)
6335 +               {
6336 +               RSAerr(PK11_F_RSA_PUB_DEC,
6337 +                       PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
6338 +               goto err;
6339 +               }
6341 +       /* PK11 functions are called here */
6342 +       r = pk11_RSA_public_decrypt_low(flen, from, buf, rsa);
6344 +       /*
6345 +        * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
6346 +        * Needs to skip these 0's here
6347 +        */
6348 +       for (i = 0; i < r; i++)
6349 +               if (buf[i] != 0)
6350 +                       break;
6352 +       p = buf + i;
6353 +       i = r - i;  /* i is only used with no-padding mode */
6355 +       switch (padding)
6356 +               {
6357 +       case RSA_PKCS1_PADDING:
6358 +               r = RSA_padding_check_PKCS1_type_1(to, num, p, i, num);
6359 +               break;
6360 +       case RSA_NO_PADDING:
6361 +               r = RSA_padding_check_none(to, num, p, i, num);
6362 +               break;
6363 +       default:
6364 +               RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
6365 +               goto err;
6366 +               }
6367 +       if (r < 0)
6368 +               RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_PADDING_CHECK_FAILED);
6370 +err:
6371 +       BN_clear_free(&f);
6372 +       if (buf != NULL)
6373 +               {
6374 +               OPENSSL_cleanse(buf, num);
6375 +               OPENSSL_free(buf);
6376 +               }
6377 +       return (r);
6378 +       }
6381 + * This function implements RSA public encryption using C_EncryptInit and
6382 + * C_Encrypt pk11 interfaces. Note that the CKM_RSA_X_509 is used here.
6383 + * The calling function allocated sufficient memory in "to" to store results.
6384 + */
6385 +static int pk11_RSA_public_encrypt_low(int flen,
6386 +       const unsigned char *from, unsigned char *to, RSA *rsa)
6387 +       {
6388 +       CK_ULONG bytes_encrypted = flen;
6389 +       int retval = -1;
6390 +       CK_RV rv;
6391 +       CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6392 +       CK_MECHANISM *p_mech = &mech_rsa;
6393 +       CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
6394 +       PK11_SESSION *sp;
6396 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6397 +               return (-1);
6399 +       (void) check_new_rsa_key_pub(sp, rsa);
6401 +       h_pub_key = sp->opdata_rsa_pub_key;
6402 +       if (h_pub_key == CK_INVALID_HANDLE)
6403 +               h_pub_key = sp->opdata_rsa_pub_key =
6404 +                       pk11_get_public_rsa_key(rsa, &sp->opdata_rsa_pub,
6405 +                           &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
6406 +                           sp->session);
6408 +       if (h_pub_key != CK_INVALID_HANDLE)
6409 +               {
6410 +               rv = pFuncList->C_EncryptInit(sp->session, p_mech,
6411 +                       h_pub_key);
6413 +               if (rv != CKR_OK)
6414 +                       {
6415 +                       PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
6416 +                           PK11_R_ENCRYPTINIT, rv);
6417 +                       pk11_return_session(sp, OP_RSA);
6418 +                       return (-1);
6419 +                       }
6421 +               rv = pFuncList->C_Encrypt(sp->session,
6422 +                       (unsigned char *)from, flen, to, &bytes_encrypted);
6424 +               if (rv != CKR_OK)
6425 +                       {
6426 +                       PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
6427 +                           PK11_R_ENCRYPT, rv);
6428 +                       pk11_return_session(sp, OP_RSA);
6429 +                       return (-1);
6430 +                       }
6431 +               retval = bytes_encrypted;
6432 +               }
6434 +       pk11_return_session(sp, OP_RSA);
6435 +       return (retval);
6436 +       }
6440 + * This function implements RSA private encryption using C_SignInit and
6441 + * C_Sign pk11 APIs. Note that CKM_RSA_X_509 is used here.
6442 + * The calling function allocated sufficient memory in "to" to store results.
6443 + */
6444 +static int pk11_RSA_private_encrypt_low(int flen,
6445 +       const unsigned char *from, unsigned char *to, RSA *rsa)
6446 +       {
6447 +       CK_ULONG ul_sig_len = flen;
6448 +       int retval = -1;
6449 +       CK_RV rv;
6450 +       CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6451 +       CK_MECHANISM *p_mech = &mech_rsa;
6452 +       CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
6453 +       PK11_SESSION *sp;
6455 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6456 +               return (-1);
6458 +       (void) check_new_rsa_key_priv(sp, rsa);
6460 +       h_priv_key = sp->opdata_rsa_priv_key;
6461 +       if (h_priv_key == CK_INVALID_HANDLE)
6462 +               {
6463 +               h_priv_key = sp->opdata_rsa_priv_key =
6464 +                       pk11_get_private_rsa_key(rsa, &sp->opdata_rsa_priv,
6465 +                           &sp->opdata_rsa_d_num, &sp->opdata_rsa_pn_num,
6466 +                           &sp->opdata_rsa_pe_num, sp->session);
6467 +               }
6469 +       if (h_priv_key != CK_INVALID_HANDLE)
6470 +               {
6471 +               rv = pFuncList->C_SignInit(sp->session, p_mech,
6472 +                       h_priv_key);
6474 +               if (rv != CKR_OK)
6475 +                       {
6476 +                       PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW,
6477 +                           PK11_R_SIGNINIT, rv);
6478 +                       pk11_return_session(sp, OP_RSA);
6479 +                       return (-1);
6480 +                       }
6482 +               rv = pFuncList->C_Sign(sp->session,
6483 +                       (unsigned char *)from, flen, to, &ul_sig_len);
6485 +               if (rv != CKR_OK)
6486 +                       {
6487 +                       PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW, PK11_R_SIGN,
6488 +                           rv);
6489 +                       pk11_return_session(sp, OP_RSA);
6490 +                       return (-1);
6491 +                       }
6493 +               retval = ul_sig_len;
6494 +               }
6496 +       pk11_return_session(sp, OP_RSA);
6497 +       return (retval);
6498 +       }
6502 + * This function implements RSA private decryption using C_DecryptInit and
6503 + * C_Decrypt pk11 APIs. Note that CKM_RSA_X_509 mechanism is used here.
6504 + * The calling function allocated sufficient memory in "to" to store results.
6505 + */
6506 +static int pk11_RSA_private_decrypt_low(int flen,
6507 +       const unsigned char *from, unsigned char *to, RSA *rsa)
6508 +       {
6509 +       CK_ULONG bytes_decrypted = flen;
6510 +       int retval = -1;
6511 +       CK_RV rv;
6512 +       CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6513 +       CK_MECHANISM *p_mech = &mech_rsa;
6514 +       CK_OBJECT_HANDLE h_priv_key;
6515 +       PK11_SESSION *sp;
6517 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6518 +               return (-1);
6520 +       (void) check_new_rsa_key_priv(sp, rsa);
6522 +       h_priv_key = sp->opdata_rsa_priv_key;
6523 +       if (h_priv_key == CK_INVALID_HANDLE)
6524 +               h_priv_key = sp->opdata_rsa_priv_key =
6525 +                       pk11_get_private_rsa_key(rsa, &sp->opdata_rsa_priv,
6526 +                           &sp->opdata_rsa_d_num, &sp->opdata_rsa_pn_num,
6527 +                           &sp->opdata_rsa_pe_num, sp->session);
6529 +       if (h_priv_key != CK_INVALID_HANDLE)
6530 +               {
6531 +               rv = pFuncList->C_DecryptInit(sp->session, p_mech,
6532 +                       h_priv_key);
6534 +               if (rv != CKR_OK)
6535 +                       {
6536 +                       PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
6537 +                               PK11_R_DECRYPTINIT, rv);
6538 +                       pk11_return_session(sp, OP_RSA);
6539 +                       return (-1);
6540 +                       }
6542 +               rv = pFuncList->C_Decrypt(sp->session,
6543 +                       (unsigned char *)from, flen, to, &bytes_decrypted);
6545 +               if (rv != CKR_OK)
6546 +                       {
6547 +                       PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
6548 +                           PK11_R_DECRYPT, rv);
6549 +                       pk11_return_session(sp, OP_RSA);
6550 +                       return (-1);
6551 +                       }
6552 +               retval = bytes_decrypted;
6553 +               }
6555 +       pk11_return_session(sp, OP_RSA);
6556 +       return (retval);
6557 +       }
6561 + * This function implements RSA public decryption using C_VerifyRecoverInit
6562 + * and C_VerifyRecover pk11 APIs. Note that CKM_RSA_X_509 is used here.
6563 + * The calling function allocated sufficient memory in "to" to store results.
6564 + */
6565 +static int pk11_RSA_public_decrypt_low(int flen,
6566 +       const unsigned char *from, unsigned char *to, RSA *rsa)
6567 +       {
6568 +       CK_ULONG bytes_decrypted = flen;
6569 +       int retval = -1;
6570 +       CK_RV rv;
6571 +       CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6572 +       CK_MECHANISM *p_mech = &mech_rsa;
6573 +       CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
6574 +       PK11_SESSION *sp;
6576 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6577 +               return (-1);
6579 +       (void) check_new_rsa_key_pub(sp, rsa);
6581 +       h_pub_key = sp->opdata_rsa_pub_key;
6582 +       if (h_pub_key == CK_INVALID_HANDLE)
6583 +               h_pub_key = sp->opdata_rsa_pub_key =
6584 +                       pk11_get_public_rsa_key(rsa, &sp->opdata_rsa_pub,
6585 +                           &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
6586 +                           sp->session);
6588 +       if (h_pub_key != CK_INVALID_HANDLE)
6589 +               {
6590 +               rv = pFuncList->C_VerifyRecoverInit(sp->session,
6591 +                       p_mech, h_pub_key);
6593 +               if (rv != CKR_OK)
6594 +                       {
6595 +                       PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
6596 +                               PK11_R_VERIFYRECOVERINIT, rv);
6597 +                       pk11_return_session(sp, OP_RSA);
6598 +                       return (-1);
6599 +                       }
6601 +               rv = pFuncList->C_VerifyRecover(sp->session,
6602 +                       (unsigned char *)from, flen, to, &bytes_decrypted);
6604 +               if (rv != CKR_OK)
6605 +                       {
6606 +                       PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
6607 +                           PK11_R_VERIFYRECOVER, rv);
6608 +                       pk11_return_session(sp, OP_RSA);
6609 +                       return (-1);
6610 +                       }
6611 +               retval = bytes_decrypted;
6612 +               }
6614 +       pk11_return_session(sp, OP_RSA);
6615 +       return (retval);
6616 +       }
6618 +static int pk11_RSA_init(RSA *rsa)
6619 +       {
6620 +       /*
6621 +        * This flag in the RSA_METHOD enables the new rsa_sign,
6622 +        * rsa_verify functions. See rsa.h for details.
6623 +        */
6624 +       rsa->flags |= RSA_FLAG_SIGN_VER;
6626 +       return (1);
6627 +       }
6629 +static int pk11_RSA_finish(RSA *rsa)
6630 +       {
6631 +       /*
6632 +        * Since we are overloading OpenSSL's native RSA_eay_finish() we need
6633 +        * to do the same as in the original function, i.e. to free bignum
6634 +        * structures.
6635 +        */
6636 +       if (rsa->_method_mod_n != NULL)
6637 +               BN_MONT_CTX_free(rsa->_method_mod_n);
6638 +       if (rsa->_method_mod_p != NULL)
6639 +               BN_MONT_CTX_free(rsa->_method_mod_p);
6640 +       if (rsa->_method_mod_q != NULL)
6641 +               BN_MONT_CTX_free(rsa->_method_mod_q);
6643 +       return (1);
6644 +       }
6647 + * Standard engine interface function. Majority codes here are from
6648 + * rsa/rsa_sign.c. We replaced the decrypt function call by C_Sign of PKCS#11.
6649 + * See more details in rsa/rsa_sign.c
6650 + */
6651 +static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
6652 +       unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
6653 +       {
6654 +       X509_SIG sig;
6655 +       ASN1_TYPE parameter;
6656 +       int i, j = 0;
6657 +       unsigned char *p, *s = NULL;
6658 +       X509_ALGOR algor;
6659 +       ASN1_OCTET_STRING digest;
6660 +       CK_RV rv;
6661 +       CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
6662 +       CK_MECHANISM *p_mech = &mech_rsa;
6663 +       CK_OBJECT_HANDLE h_priv_key;
6664 +       PK11_SESSION *sp = NULL;
6665 +       int ret = 0;
6666 +       unsigned long ulsiglen;
6668 +       /* Encode the digest */
6669 +       /* Special case: SSL signature, just check the length */
6670 +       if (type == NID_md5_sha1)
6671 +               {
6672 +               if (m_len != SSL_SIG_LENGTH)
6673 +                       {
6674 +                       PK11err(PK11_F_RSA_SIGN,
6675 +                               PK11_R_INVALID_MESSAGE_LENGTH);
6676 +                       goto err;
6677 +                       }
6678 +               i = SSL_SIG_LENGTH;
6679 +               s = (unsigned char *)m;
6680 +               }
6681 +       else
6682 +               {
6683 +               sig.algor = &algor;
6684 +               sig.algor->algorithm = OBJ_nid2obj(type);
6685 +               if (sig.algor->algorithm == NULL)
6686 +                       {
6687 +                       PK11err(PK11_F_RSA_SIGN,
6688 +                               PK11_R_UNKNOWN_ALGORITHM_TYPE);
6689 +                       goto err;
6690 +                       }
6691 +               if (sig.algor->algorithm->length == 0)
6692 +                       {
6693 +                       PK11err(PK11_F_RSA_SIGN,
6694 +                               PK11_R_UNKNOWN_ASN1_OBJECT_ID);
6695 +                       goto err;
6696 +                       }
6697 +               parameter.type = V_ASN1_NULL;
6698 +               parameter.value.ptr = NULL;
6699 +               sig.algor->parameter = &parameter;
6701 +               sig.digest = &digest;
6702 +               sig.digest->data = (unsigned char *)m;
6703 +               sig.digest->length = m_len;
6705 +               i = i2d_X509_SIG(&sig, NULL);
6706 +               }
6708 +       j = RSA_size(rsa);
6709 +       if ((i - RSA_PKCS1_PADDING) > j)
6710 +               {
6711 +               PK11err(PK11_F_RSA_SIGN, PK11_R_DIGEST_TOO_BIG);
6712 +               goto err;
6713 +               }
6715 +       if (type != NID_md5_sha1)
6716 +               {
6717 +               s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
6718 +               if (s == NULL)
6719 +                       {
6720 +                       PK11err(PK11_F_RSA_SIGN, PK11_R_MALLOC_FAILURE);
6721 +                       goto err;
6722 +                       }
6723 +               p = s;
6724 +               (void) i2d_X509_SIG(&sig, &p);
6725 +               }
6727 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6728 +               goto err;
6730 +       (void) check_new_rsa_key_priv(sp, rsa);
6732 +       h_priv_key = sp->opdata_rsa_priv_key;
6733 +       if (h_priv_key == CK_INVALID_HANDLE)
6734 +               h_priv_key = sp->opdata_rsa_priv_key =
6735 +                       pk11_get_private_rsa_key((RSA *)rsa,
6736 +                           &sp->opdata_rsa_priv, &sp->opdata_rsa_d_num,
6737 +                           &sp->opdata_rsa_pn_num, &sp->opdata_rsa_pe_num,
6738 +                           sp->session);
6740 +       if (h_priv_key != CK_INVALID_HANDLE)
6741 +               {
6742 +               rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
6744 +               if (rv != CKR_OK)
6745 +                       {
6746 +                       PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGNINIT, rv);
6747 +                       goto err;
6748 +                       }
6750 +               ulsiglen = j;
6751 +               rv = pFuncList->C_Sign(sp->session, s, i, sigret,
6752 +                       (CK_ULONG_PTR) &ulsiglen);
6753 +               *siglen = ulsiglen;
6755 +               if (rv != CKR_OK)
6756 +                       {
6757 +                       PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGN, rv);
6758 +                       goto err;
6759 +                       }
6760 +               ret = 1;
6761 +               }
6763 +err:
6764 +       if ((type != NID_md5_sha1) && (s != NULL))
6765 +               {
6766 +               (void) memset(s, 0, (unsigned int)(j + 1));
6767 +               OPENSSL_free(s);
6768 +               }
6770 +       pk11_return_session(sp, OP_RSA);
6771 +       return (ret);
6772 +       }
6774 +#if OPENSSL_VERSION_NUMBER < 0x10000000L
6775 +static int pk11_RSA_verify(int type, const unsigned char *m,
6776 +       unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
6777 +       const RSA *rsa)
6778 +#else
6779 +static int pk11_RSA_verify(int type, const unsigned char *m,
6780 +       unsigned int m_len, const unsigned char *sigbuf, unsigned int siglen,
6781 +       const RSA *rsa)
6782 +#endif
6783 +       {
6784 +       X509_SIG sig;
6785 +       ASN1_TYPE parameter;
6786 +       int i, j = 0;
6787 +       unsigned char *p, *s = NULL;
6788 +       X509_ALGOR algor;
6789 +       ASN1_OCTET_STRING digest;
6790 +       CK_RV rv;
6791 +       CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
6792 +       CK_MECHANISM *p_mech = &mech_rsa;
6793 +       CK_OBJECT_HANDLE h_pub_key;
6794 +       PK11_SESSION *sp = NULL;
6795 +       int ret = 0;
6797 +       /* Encode the digest    */
6798 +       /* Special case: SSL signature, just check the length */
6799 +       if (type == NID_md5_sha1)
6800 +               {
6801 +               if (m_len != SSL_SIG_LENGTH)
6802 +                       {
6803 +                       PK11err(PK11_F_RSA_VERIFY,
6804 +                               PK11_R_INVALID_MESSAGE_LENGTH);
6805 +                       goto err;
6806 +                       }
6807 +               i = SSL_SIG_LENGTH;
6808 +               s = (unsigned char *)m;
6809 +               }
6810 +       else
6811 +               {
6812 +               sig.algor = &algor;
6813 +               sig.algor->algorithm = OBJ_nid2obj(type);
6814 +               if (sig.algor->algorithm == NULL)
6815 +                       {
6816 +                       PK11err(PK11_F_RSA_VERIFY,
6817 +                               PK11_R_UNKNOWN_ALGORITHM_TYPE);
6818 +                       goto err;
6819 +                       }
6820 +               if (sig.algor->algorithm->length == 0)
6821 +                       {
6822 +                       PK11err(PK11_F_RSA_VERIFY,
6823 +                               PK11_R_UNKNOWN_ASN1_OBJECT_ID);
6824 +                       goto err;
6825 +                       }
6826 +               parameter.type = V_ASN1_NULL;
6827 +               parameter.value.ptr = NULL;
6828 +               sig.algor->parameter = &parameter;
6829 +               sig.digest = &digest;
6830 +               sig.digest->data = (unsigned char *)m;
6831 +               sig.digest->length = m_len;
6832 +               i = i2d_X509_SIG(&sig, NULL);
6833 +               }
6835 +       j = RSA_size(rsa);
6836 +       if ((i - RSA_PKCS1_PADDING) > j)
6837 +               {
6838 +               PK11err(PK11_F_RSA_VERIFY, PK11_R_DIGEST_TOO_BIG);
6839 +               goto err;
6840 +               }
6842 +       if (type != NID_md5_sha1)
6843 +               {
6844 +               s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
6845 +               if (s == NULL)
6846 +                       {
6847 +                       PK11err(PK11_F_RSA_VERIFY, PK11_R_MALLOC_FAILURE);
6848 +                       goto err;
6849 +                       }
6850 +               p = s;
6851 +               (void) i2d_X509_SIG(&sig, &p);
6852 +               }
6854 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6855 +               goto err;
6857 +       (void) check_new_rsa_key_pub(sp, rsa);
6859 +       h_pub_key = sp->opdata_rsa_pub_key;
6860 +       if (h_pub_key == CK_INVALID_HANDLE)
6861 +               h_pub_key = sp->opdata_rsa_pub_key =
6862 +                       pk11_get_public_rsa_key((RSA *)rsa, &sp->opdata_rsa_pub,
6863 +                           &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
6864 +                           sp->session);
6866 +       if (h_pub_key != CK_INVALID_HANDLE)
6867 +               {
6868 +               rv = pFuncList->C_VerifyInit(sp->session, p_mech,
6869 +                       h_pub_key);
6871 +               if (rv != CKR_OK)
6872 +                       {
6873 +                       PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFYINIT,
6874 +                           rv);
6875 +                       goto err;
6876 +                       }
6877 +               rv = pFuncList->C_Verify(sp->session, s, i,
6878 +                       (CK_BYTE_PTR)sigbuf, (CK_ULONG)siglen);
6880 +               if (rv != CKR_OK)
6881 +                       {
6882 +                       PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFY, rv);
6883 +                       goto err;
6884 +                       }
6885 +               ret = 1;
6886 +               }
6888 +err:
6889 +       if ((type != NID_md5_sha1) && (s != NULL))
6890 +               {
6891 +               (void) memset(s, 0, (unsigned int)(j + 1));
6892 +               OPENSSL_free(s);
6893 +               }
6895 +       pk11_return_session(sp, OP_RSA);
6896 +       return (ret);
6897 +       }
6899 +static int hndidx_rsa = -1;
6901 +#define        MAXATTR 1024
6904 + * Load RSA private key from a file or get its PKCS#11 handle if stored in the
6905 + * PKCS#11 token.
6906 + */
6907 +/* ARGSUSED */
6908 +EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *privkey_file,
6909 +       UI_METHOD *ui_method, void *callback_data)
6910 +       {
6911 +       EVP_PKEY *pkey = NULL;
6912 +       FILE *privkey;
6913 +       CK_OBJECT_HANDLE  h_priv_key = CK_INVALID_HANDLE;
6914 +       RSA *rsa = NULL;
6915 +       PK11_SESSION *sp;
6916 +       /* Anything else below is needed for the key by reference extension. */
6917 +       CK_RV rv;
6918 +       CK_BBOOL is_token = TRUE;
6919 +       CK_BBOOL rollback = FALSE;
6920 +       CK_BYTE attr_data[2][MAXATTR];
6921 +       CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
6922 +       CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;    /* key in keystore */
6924 +       /* we look for private keys only */
6925 +       CK_ATTRIBUTE search_templ[] =
6926 +               {
6927 +               {CKA_TOKEN, &is_token, sizeof(is_token)},
6928 +               {CKA_CLASS, &key_class, sizeof(key_class)},
6929 +               {CKA_LABEL, NULL, 0}
6930 +               };
6932 +       /*
6933 +        * These public attributes are needed to initialize the OpenSSL RSA
6934 +        * structure with something we can use to look up the key. Note that we
6935 +        * never ask for private components.
6936 +        */
6937 +       CK_ATTRIBUTE get_templ[] =
6938 +               {
6939 +               {CKA_MODULUS, (void *)attr_data[0], MAXATTR},           /* n */
6940 +               {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},   /* e */
6941 +               };
6943 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6944 +               return (NULL);
6946 +       /*
6947 +        * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
6948 +        */
6949 +       if (strstr(privkey_file, "pkcs11:") == privkey_file)
6950 +               {
6951 +               search_templ[2].pValue = strstr(privkey_file, ":") + 1;
6952 +               search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
6954 +               if (pk11_token_login(sp->session, &pk11_login_done,
6955 +                   CK_TRUE) == 0)
6956 +                       goto err;
6958 +               /* see find_lock array definition
6959 +                  for more info on object locking */
6960 +               LOCK_OBJSTORE(OP_RSA);
6962 +               /*
6963 +                * Now let's try to find the key in the token. It is a failure
6964 +                * if we can't find it.
6965 +                */
6966 +               if (find_one_object(OP_RSA, sp->session, search_templ, 3,
6967 +                   &ks_key) == 0)
6968 +                       {
6969 +                       UNLOCK_OBJSTORE(OP_RSA);
6970 +                       goto err;
6971 +                       }
6973 +               if (hndidx_rsa == -1)
6974 +                       hndidx_rsa = RSA_get_ex_new_index(0,
6975 +                                       "pkcs11 RSA HSM key handle",
6976 +                                       NULL, NULL, NULL);
6978 +               /*
6979 +                * We might have a cache hit which we could confirm
6980 +                * according to the 'n'/'e' params, RSA public pointer
6981 +                * as NULL, and non-NULL RSA private pointer. However,
6982 +                * it is easier just to recreate everything. We expect
6983 +                * the keys to be loaded once and used many times. We
6984 +                * do not check the return value because even in case
6985 +                * of failure the sp structure will have both key
6986 +                * pointer and object handle cleaned and
6987 +                * pk11_destroy_object() reports the failure to the
6988 +                * OpenSSL error message buffer.
6989 +                */
6990 +               (void) pk11_destroy_rsa_object_priv(sp, FALSE);
6992 +               sp->opdata_rsa_priv_key = ks_key;
6993 +               /* This object shall not be deleted on a cache miss. */
6994 +               sp->priv_persistent = CK_TRUE;
6996 +               /*
6997 +                * Cache the RSA private structure pointer. We do not
6998 +                * use it now for key-by-ref keys but let's do it for
6999 +                * consistency reasons.
7000 +                */
7001 +               if ((rsa = sp->opdata_rsa_priv = RSA_new_method(e)) == NULL)
7002 +                       {
7003 +                       UNLOCK_OBJSTORE(OP_RSA);
7004 +                       goto err;
7005 +                       }
7007 +               /*
7008 +                * Now we have to initialize an OpenSSL RSA structure,
7009 +                * everything else is 0 or NULL.
7010 +                */
7011 +               rsa->flags = RSA_FLAG_SIGN_VER | RSA_FLAG_EXT_PKEY;
7012 +               RSA_set_ex_data(rsa, hndidx_rsa, (void *) ks_key);
7014 +               if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
7015 +                   get_templ, 2)) != CKR_OK)
7016 +                       {
7017 +                       UNLOCK_OBJSTORE(OP_RSA);
7018 +                       PK11err_add_data(PK11_F_LOAD_PRIVKEY,
7019 +                                        PK11_R_GETATTRIBUTVALUE, rv);
7020 +                       goto err;
7021 +                       }
7023 +               /*
7024 +                * We do not use pk11_get_private_rsa_key() here so we
7025 +                * must take care of handle management ourselves.
7026 +                */
7027 +               KEY_HANDLE_REFHOLD(ks_key, OP_RSA, TRUE, rollback, err);
7029 +               /*
7030 +                * Those are the sensitive components we do not want to export
7031 +                * from the token at all: rsa->(d|p|q|dmp1|dmq1|iqmp).
7032 +                */
7033 +               attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
7034 +               attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
7035 +               /*
7036 +                * Must have 'n'/'e' components in the session structure as
7037 +                * well. They serve as a public look-up key for the private key
7038 +                * in the keystore.
7039 +                */
7040 +               attr_to_BN(&get_templ[0], attr_data[0],
7041 +                       &sp->opdata_rsa_pn_num);
7042 +               attr_to_BN(&get_templ[1], attr_data[1],
7043 +                       &sp->opdata_rsa_pe_num);
7045 +               UNLOCK_OBJSTORE(OP_RSA);
7047 +               if ((pkey = EVP_PKEY_new()) == NULL)
7048 +                       goto err;
7050 +               if (EVP_PKEY_assign_RSA(pkey, rsa) == 0)
7051 +                       goto err;
7052 +               }
7053 +       else if ((privkey = fopen(privkey_file, read_mode_flags)) != NULL)
7054 +               {
7055 +               pkey = PEM_read_PrivateKey(privkey, NULL, NULL, NULL);
7056 +               (void) fclose(privkey);
7057 +               if (pkey != NULL)
7058 +                       {
7059 +                       rsa = EVP_PKEY_get1_RSA(pkey);
7060 +                       if (rsa != NULL)
7061 +                               {
7062 +                               /*
7063 +                                * This will always destroy the RSA
7064 +                                * object since we have a new RSA
7065 +                                * structure here.
7066 +                                */
7067 +                               (void) check_new_rsa_key_priv(sp, rsa);
7068 +                               sp->priv_persistent = CK_FALSE;
7070 +                               h_priv_key = sp->opdata_rsa_priv_key =
7071 +                                   pk11_get_private_rsa_key(rsa,
7072 +                                   &sp->opdata_rsa_priv,
7073 +                                   &sp->opdata_rsa_d_num,
7074 +                                   &sp->opdata_rsa_pn_num,
7075 +                                   &sp->opdata_rsa_pe_num, sp->session);
7076 +                               if (h_priv_key == CK_INVALID_HANDLE)
7077 +                                       goto err;
7078 +                               }
7079 +                       else
7080 +                               goto err;
7081 +                       }
7082 +               }
7084 +       pk11_return_session(sp, OP_RSA);
7085 +       return (pkey);
7086 +err:
7087 +       pk11_return_session(sp, OP_RSA);
7088 +       if (rsa != NULL)
7089 +               RSA_free(rsa);
7090 +       if (pkey != NULL)
7091 +               {
7092 +               EVP_PKEY_free(pkey);
7093 +               pkey = NULL;
7094 +               }
7095 +       rollback = rollback;
7096 +       return (pkey);
7097 +       }
7100 + * Load RSA public key from a file or get its PKCS#11 handle if stored in the
7101 + * PKCS#11 token.
7102 + */
7103 +/* ARGSUSED */
7104 +EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
7105 +       UI_METHOD *ui_method, void *callback_data)
7106 +       {
7107 +       EVP_PKEY *pkey = NULL;
7108 +       FILE *pubkey;
7109 +       CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
7110 +       RSA *rsa = NULL;
7111 +       PK11_SESSION *sp;
7112 +       /* Anything else below is needed for the key by reference extension. */
7113 +       CK_RV rv;
7114 +       CK_BBOOL is_token = TRUE;
7115 +       CK_BYTE attr_data[2][MAXATTR];
7116 +       CK_OBJECT_CLASS key_class = CKO_PUBLIC_KEY;
7117 +       CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;    /* key in keystore */
7119 +       /* we look for public keys only */
7120 +       CK_ATTRIBUTE search_templ[] =
7121 +               {
7122 +               {CKA_TOKEN, &is_token, sizeof(is_token)},
7123 +               {CKA_CLASS, &key_class, sizeof(key_class)},
7124 +               {CKA_LABEL, NULL, 0}
7125 +               };
7127 +       /*
7128 +        * These public attributes are needed to initialize OpenSSL RSA
7129 +        * structure with something we can use to look up the key.
7130 +        */
7131 +       CK_ATTRIBUTE get_templ[] =
7132 +               {
7133 +               {CKA_MODULUS, (void *)attr_data[0], MAXATTR},           /* n */
7134 +               {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},   /* e */
7135 +               };
7137 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
7138 +               return (NULL);
7140 +       /*
7141 +        * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
7142 +        */
7143 +       if (strstr(pubkey_file, "pkcs11:") == pubkey_file)
7144 +               {
7145 +               search_templ[2].pValue = strstr(pubkey_file, ":") + 1;
7146 +               search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
7148 +               if (pk11_token_login(sp->session, &pk11_login_done,
7149 +                   CK_FALSE) == 0)
7150 +                       goto err;
7152 +               /* see find_lock array definition
7153 +                  for more info on object locking */
7154 +               LOCK_OBJSTORE(OP_RSA);
7156 +               /*
7157 +                * Now let's try to find the key in the token. It is a failure
7158 +                * if we can't find it.
7159 +                */
7160 +               if (find_one_object(OP_RSA, sp->session, search_templ, 3,
7161 +                   &ks_key) == 0)
7162 +                       {
7163 +                       UNLOCK_OBJSTORE(OP_RSA);
7164 +                       goto err;
7165 +                       }
7167 +               /*
7168 +                * We load a new public key so we will create a new RSA
7169 +                * structure. No cache hit is possible.
7170 +                */
7171 +               (void) pk11_destroy_rsa_object_pub(sp, FALSE);
7173 +               sp->opdata_rsa_pub_key = ks_key;
7174 +               /* This object shall not be deleted on a cache miss. */
7175 +               sp->pub_persistent = CK_TRUE;
7177 +               /*
7178 +                * Cache the RSA public structure pointer.
7179 +                */
7180 +               if ((rsa = sp->opdata_rsa_pub = RSA_new_method(e)) == NULL)
7181 +                       {
7182 +                       UNLOCK_OBJSTORE(OP_RSA);
7183 +                       goto err;
7184 +                       }
7186 +               /*
7187 +                * Now we have to initialize an OpenSSL RSA structure,
7188 +                * everything else is 0 or NULL.
7189 +                */
7190 +               rsa->flags = RSA_FLAG_SIGN_VER;
7192 +               if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
7193 +                   get_templ, 2)) != CKR_OK)
7194 +                       {
7195 +                       UNLOCK_OBJSTORE(OP_RSA);
7196 +                       PK11err_add_data(PK11_F_LOAD_PUBKEY,
7197 +                                        PK11_R_GETATTRIBUTVALUE, rv);
7198 +                       goto err;
7199 +                       }
7201 +               attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
7202 +               attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
7204 +               UNLOCK_OBJSTORE(OP_RSA);
7206 +               if ((pkey = EVP_PKEY_new()) == NULL)
7207 +                       goto err;
7209 +               if (EVP_PKEY_assign_RSA(pkey, rsa) == 0)
7210 +                       goto err;
7212 +               /*
7213 +                * Create a session object from it so that when calling
7214 +                * pk11_get_public_rsa_key() the next time, we can find it. The
7215 +                * reason why we do that is that we cannot tell from the RSA
7216 +                * structure (OpenSSL RSA structure does not have any room for
7217 +                * additional data used by the engine, for example) if it bears
7218 +                * a public key stored in the keystore or not so it's better if
7219 +                * we always have a session key. Note that this is different
7220 +                * from what we do for the private keystore objects but in that
7221 +                * case, we can tell from the RSA structure that the keystore
7222 +                * object is in play - the 'd' component is NULL in that case.
7223 +                */
7224 +               h_pub_key = sp->opdata_rsa_pub_key =
7225 +                   pk11_get_public_rsa_key(rsa,
7226 +                   &sp->opdata_rsa_pub, &sp->opdata_rsa_n_num,
7227 +                   &sp->opdata_rsa_e_num, sp->session);
7228 +               if (h_pub_key == CK_INVALID_HANDLE)
7229 +                       goto err;
7230 +               }
7231 +       else if ((pubkey = fopen(pubkey_file, read_mode_flags)) != NULL)
7232 +               {
7233 +               pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL);
7234 +               (void) fclose(pubkey);
7235 +               if (pkey != NULL)
7236 +                       {
7237 +                       rsa = EVP_PKEY_get1_RSA(pkey);
7238 +                       if (rsa != NULL)
7239 +                               {
7240 +                               /*
7241 +                                * This will always destroy the RSA
7242 +                                * object since we have a new RSA
7243 +                                * structure here.
7244 +                                */
7245 +                               (void) check_new_rsa_key_pub(sp, rsa);
7246 +                               sp->pub_persistent = CK_FALSE;
7248 +                               h_pub_key = sp->opdata_rsa_pub_key =
7249 +                                   pk11_get_public_rsa_key(rsa,
7250 +                                   &sp->opdata_rsa_pub, &sp->opdata_rsa_n_num,
7251 +                                   &sp->opdata_rsa_e_num, sp->session);
7252 +                               if (h_pub_key == CK_INVALID_HANDLE)
7253 +                                       goto err;
7254 +                               }
7255 +                       else
7256 +                               goto err;
7257 +                       }
7258 +               }
7260 +       pk11_return_session(sp, OP_RSA);
7261 +       return (pkey);
7262 +err:
7263 +       pk11_return_session(sp, OP_RSA);
7264 +       if (rsa != NULL)
7265 +               RSA_free(rsa);
7266 +       if (pkey != NULL)
7267 +               {
7268 +               EVP_PKEY_free(pkey);
7269 +               pkey = NULL;
7270 +               }
7271 +       return (pkey);
7272 +       }
7275 + * Create a public key object in a session from a given rsa structure.
7276 + * The *rsa_n_num and *rsa_e_num pointers are non-NULL for RSA public keys.
7277 + */
7278 +static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA *rsa,
7279 +    RSA **key_ptr, BIGNUM **rsa_n_num, BIGNUM **rsa_e_num,
7280 +    CK_SESSION_HANDLE session)
7281 +       {
7282 +       CK_RV rv;
7283 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
7284 +       CK_ULONG found;
7285 +       CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
7286 +       CK_KEY_TYPE k_type = CKK_RSA;
7287 +       CK_ULONG ul_key_attr_count = 8;
7288 +       CK_BBOOL rollback = FALSE;
7290 +       CK_ATTRIBUTE  a_key_template[] =
7291 +               {
7292 +               {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
7293 +               {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
7294 +               {CKA_TOKEN, &myfalse, sizeof (myfalse)},
7295 +               {CKA_ENCRYPT, &mytrue, sizeof (mytrue)},
7296 +               {CKA_VERIFY, &mytrue, sizeof (mytrue)},
7297 +               {CKA_VERIFY_RECOVER, &mytrue, sizeof (mytrue)},
7298 +               {CKA_MODULUS, (void *)NULL, 0},
7299 +               {CKA_PUBLIC_EXPONENT, (void *)NULL, 0}
7300 +               };
7302 +       int i;
7304 +       a_key_template[0].pValue = &o_key;
7305 +       a_key_template[1].pValue = &k_type;
7307 +       a_key_template[6].ulValueLen = BN_num_bytes(rsa->n);
7308 +       a_key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
7309 +               (size_t)a_key_template[6].ulValueLen);
7310 +       if (a_key_template[6].pValue == NULL)
7311 +               {
7312 +               PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
7313 +               goto malloc_err;
7314 +               }
7316 +       BN_bn2bin(rsa->n, a_key_template[6].pValue);
7318 +       a_key_template[7].ulValueLen = BN_num_bytes(rsa->e);
7319 +       a_key_template[7].pValue = (CK_VOID_PTR)OPENSSL_malloc(
7320 +               (size_t)a_key_template[7].ulValueLen);
7321 +       if (a_key_template[7].pValue == NULL)
7322 +               {
7323 +               PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
7324 +               goto malloc_err;
7325 +               }
7327 +       BN_bn2bin(rsa->e, a_key_template[7].pValue);
7329 +       /* see find_lock array definition for more info on object locking */
7330 +       LOCK_OBJSTORE(OP_RSA);
7332 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template,
7333 +               ul_key_attr_count);
7335 +       if (rv != CKR_OK)
7336 +               {
7337 +               PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
7338 +                   PK11_R_FINDOBJECTSINIT, rv);
7339 +               goto err;
7340 +               }
7342 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
7344 +       if (rv != CKR_OK)
7345 +               {
7346 +               (void) pFuncList->C_FindObjectsFinal(session);
7347 +               PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
7348 +                   PK11_R_FINDOBJECTS, rv);
7349 +               goto err;
7350 +               }
7352 +       rv = pFuncList->C_FindObjectsFinal(session);
7354 +       if (rv != CKR_OK)
7355 +               {
7356 +               PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
7357 +                   PK11_R_FINDOBJECTSFINAL, rv);
7358 +               goto err;
7359 +               }
7361 +       if (found == 0)
7362 +               {
7363 +               rv = pFuncList->C_CreateObject(session,
7364 +                       a_key_template, ul_key_attr_count, &h_key);
7365 +               if (rv != CKR_OK)
7366 +                       {
7367 +                       PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
7368 +                           PK11_R_CREATEOBJECT, rv);
7369 +                       goto err;
7370 +                       }
7371 +               }
7373 +       if (rsa_n_num != NULL)
7374 +               if ((*rsa_n_num = BN_dup(rsa->n)) == NULL)
7375 +                       {
7376 +                       PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
7377 +                       rollback = TRUE;
7378 +                       goto err;
7379 +                       }
7380 +       if (rsa_e_num != NULL)
7381 +               if ((*rsa_e_num = BN_dup(rsa->e)) == NULL)
7382 +                       {
7383 +                       PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
7384 +                       BN_free(*rsa_n_num);
7385 +                       *rsa_n_num = NULL;
7386 +                       rollback = TRUE;
7387 +                       goto err;
7388 +                       }
7390 +       /* LINTED: E_CONSTANT_CONDITION */
7391 +       KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
7392 +       if (key_ptr != NULL)
7393 +               *key_ptr = rsa;
7395 +err:
7396 +       if (rollback)
7397 +               {
7398 +               /*
7399 +                * We do not care about the return value from C_DestroyObject()
7400 +                * since we are doing rollback.
7401 +                */
7402 +               if (found == 0)
7403 +                       (void) pFuncList->C_DestroyObject(session, h_key);
7404 +               h_key = CK_INVALID_HANDLE;
7405 +               }
7407 +       UNLOCK_OBJSTORE(OP_RSA);
7409 +malloc_err:
7410 +       for (i = 6; i <= 7; i++)
7411 +               {
7412 +               if (a_key_template[i].pValue != NULL)
7413 +                       {
7414 +                       OPENSSL_free(a_key_template[i].pValue);
7415 +                       a_key_template[i].pValue = NULL;
7416 +                       }
7417 +               }
7419 +       return (h_key);
7420 +       }
7423 + * Create a private key object in the session from a given rsa structure.
7424 + * The *rsa_d_num pointer is non-NULL for RSA private keys.
7425 + */
7426 +static CK_OBJECT_HANDLE
7427 +pk11_get_private_rsa_key(RSA *rsa, RSA **key_ptr, BIGNUM **rsa_d_num,
7428 +    BIGNUM **rsa_n_num, BIGNUM **rsa_e_num, CK_SESSION_HANDLE session)
7429 +       {
7430 +       CK_RV rv;
7431 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
7432 +       int i;
7433 +       CK_ULONG found;
7434 +       CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
7435 +       CK_KEY_TYPE k_type = CKK_RSA;
7436 +       CK_ULONG ul_key_attr_count = 14;
7437 +       CK_BBOOL rollback = FALSE;
7439 +       /* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys */
7440 +       CK_ATTRIBUTE  a_key_template[] =
7441 +               {
7442 +               {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
7443 +               {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
7444 +               {CKA_TOKEN, &myfalse, sizeof (myfalse)},
7445 +               {CKA_SENSITIVE, &myfalse, sizeof (myfalse)},
7446 +               {CKA_DECRYPT, &mytrue, sizeof (mytrue)},
7447 +               {CKA_SIGN, &mytrue, sizeof (mytrue)},
7448 +               {CKA_MODULUS, (void *)NULL, 0},
7449 +               {CKA_PUBLIC_EXPONENT, (void *)NULL, 0},
7450 +               {CKA_PRIVATE_EXPONENT, (void *)NULL, 0},
7451 +               {CKA_PRIME_1, (void *)NULL, 0},
7452 +               {CKA_PRIME_2, (void *)NULL, 0},
7453 +               {CKA_EXPONENT_1, (void *)NULL, 0},
7454 +               {CKA_EXPONENT_2, (void *)NULL, 0},
7455 +               {CKA_COEFFICIENT, (void *)NULL, 0},
7456 +               };
7458 +       if ((rsa->flags & RSA_FLAG_EXT_PKEY) != 0) {
7459 +               h_key = (CK_OBJECT_HANDLE)RSA_get_ex_data(rsa, hndidx_rsa);
7460 +               LOCK_OBJSTORE(OP_RSA);
7461 +               goto set;
7462 +       }
7463 +       
7464 +       a_key_template[0].pValue = &o_key;
7465 +       a_key_template[1].pValue = &k_type;
7467 +       /* Put the private key components into the template */
7468 +       if (init_template_value(rsa->n, &a_key_template[6].pValue,
7469 +               &a_key_template[6].ulValueLen) == 0 ||
7470 +           init_template_value(rsa->e, &a_key_template[7].pValue,
7471 +               &a_key_template[7].ulValueLen) == 0 ||
7472 +           init_template_value(rsa->d, &a_key_template[8].pValue,
7473 +               &a_key_template[8].ulValueLen) == 0 ||
7474 +           init_template_value(rsa->p, &a_key_template[9].pValue,
7475 +               &a_key_template[9].ulValueLen) == 0 ||
7476 +           init_template_value(rsa->q, &a_key_template[10].pValue,
7477 +               &a_key_template[10].ulValueLen) == 0 ||
7478 +           init_template_value(rsa->dmp1, &a_key_template[11].pValue,
7479 +               &a_key_template[11].ulValueLen) == 0 ||
7480 +           init_template_value(rsa->dmq1, &a_key_template[12].pValue,
7481 +               &a_key_template[12].ulValueLen) == 0 ||
7482 +           init_template_value(rsa->iqmp, &a_key_template[13].pValue,
7483 +               &a_key_template[13].ulValueLen) == 0)
7484 +               {
7485 +               PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
7486 +               goto malloc_err;
7487 +               }
7489 +       /* see find_lock array definition for more info on object locking */
7490 +       LOCK_OBJSTORE(OP_RSA);
7492 +       /*
7493 +        * We are getting the private key but the private 'd'
7494 +        * component is NULL.  That means this is key by reference RSA
7495 +        * key. In that case, we can use only public components for
7496 +        * searching for the private key handle.
7497 +        */
7498 +       if (rsa->d == NULL)
7499 +               {
7500 +               ul_key_attr_count = 8;
7501 +               /*
7502 +                * We will perform the search in the token, not in the existing
7503 +                * session keys.
7504 +                */
7505 +               a_key_template[2].pValue = &mytrue;
7506 +               }
7508 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template,
7509 +               ul_key_attr_count);
7511 +       if (rv != CKR_OK)
7512 +               {
7513 +               PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7514 +                   PK11_R_FINDOBJECTSINIT, rv);
7515 +               goto err;
7516 +               }
7518 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
7520 +       if (rv != CKR_OK)
7521 +               {
7522 +               (void) pFuncList->C_FindObjectsFinal(session);
7523 +               PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7524 +                   PK11_R_FINDOBJECTS, rv);
7525 +               goto err;
7526 +               }
7528 +       rv = pFuncList->C_FindObjectsFinal(session);
7530 +       if (rv != CKR_OK)
7531 +               {
7532 +               PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7533 +                   PK11_R_FINDOBJECTSFINAL, rv);
7534 +               goto err;
7535 +               }
7537 +       if (found == 0)
7538 +               {
7539 +               /*
7540 +                * We have an RSA structure with 'n'/'e' components
7541 +                * only so we tried to find the private key in the
7542 +                * keystore. If it was really a token key we have a
7543 +                * problem. Note that for other key types we just
7544 +                * create a new session key using the private
7545 +                * components from the RSA structure.
7546 +                */
7547 +               if (rsa->d == NULL)
7548 +                       {
7549 +                       PK11err(PK11_F_GET_PRIV_RSA_KEY,
7550 +                           PK11_R_PRIV_KEY_NOT_FOUND);
7551 +                       goto err;
7552 +                       }
7554 +               rv = pFuncList->C_CreateObject(session,
7555 +                       a_key_template, ul_key_attr_count, &h_key);
7556 +               if (rv != CKR_OK)
7557 +                       {
7558 +                       PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7559 +                               PK11_R_CREATEOBJECT, rv);
7560 +                       goto err;
7561 +                       }
7562 +               }
7564 +set:
7565 +       if (rsa_d_num != NULL)
7566 +               {
7567 +               /*
7568 +                * When RSA keys by reference code is used, we never
7569 +                * extract private components from the keystore. In
7570 +                * that case 'd' was set to NULL and we expect the
7571 +                * application to properly cope with that. It is
7572 +                * documented in openssl(5). In general, if keys by
7573 +                * reference are used we expect it to be used
7574 +                * exclusively using the high level API and then there
7575 +                * is no problem. If the application expects the
7576 +                * private components to be read from the keystore
7577 +                * then that is not a supported way of usage.
7578 +                */
7579 +               if (rsa->d != NULL && (*rsa_d_num = BN_dup(rsa->d)) == NULL)
7580 +                       {
7581 +                       PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
7582 +                       rollback = TRUE;
7583 +                       goto err;
7584 +                       }
7585 +               else
7586 +                       *rsa_d_num = NULL;
7587 +               }
7589 +       /*
7590 +        * For the key by reference code, we need public components as well
7591 +        * since 'd' component is always NULL. For that reason, we always cache
7592 +        * 'n'/'e' components as well.
7593 +        */
7594 +       *rsa_n_num = BN_dup(rsa->n);
7595 +       *rsa_e_num = BN_dup(rsa->e);
7597 +       /* LINTED: E_CONSTANT_CONDITION */
7598 +       KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
7599 +       if (key_ptr != NULL)
7600 +               *key_ptr = rsa;
7602 +err:
7603 +       if (rollback)
7604 +               {
7605 +               /*
7606 +                * We do not care about the return value from C_DestroyObject()
7607 +                * since we are doing rollback.
7608 +                */
7609 +               if (found == 0 &&
7610 +                   (rsa->flags & RSA_FLAG_EXT_PKEY) == 0)
7611 +                       (void) pFuncList->C_DestroyObject(session, h_key);
7612 +               h_key = CK_INVALID_HANDLE;
7613 +               }
7615 +       UNLOCK_OBJSTORE(OP_RSA);
7617 +malloc_err:
7618 +       /*
7619 +        * 6 to 13 entries in the key template are key components.
7620 +        * They need to be freed upon exit or error.
7621 +        */
7622 +       for (i = 6; i <= 13; i++)
7623 +               {
7624 +               if (a_key_template[i].pValue != NULL)
7625 +                       {
7626 +                       (void) memset(a_key_template[i].pValue, 0,
7627 +                               a_key_template[i].ulValueLen);
7628 +                       OPENSSL_free(a_key_template[i].pValue);
7629 +                       a_key_template[i].pValue = NULL;
7630 +                       }
7631 +               }
7633 +       return (h_key);
7634 +       }
7637 + * Check for cache miss and clean the object pointer and handle
7638 + * in such case. Return 1 for cache hit, 0 for cache miss.
7639 + */
7640 +static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa)
7641 +       {
7642 +       /*
7643 +        * Provide protection against RSA structure reuse by making the
7644 +        * check for cache hit stronger. Only public components of RSA
7645 +        * key matter here so it is sufficient to compare them with values
7646 +        * cached in PK11_SESSION structure.
7647 +        *
7648 +        * We must check the handle as well since with key by reference, public
7649 +        * components 'n'/'e' are cached in private keys as well. That means we
7650 +        * could have a cache hit in a private key when looking for a public
7651 +        * key. That would not work, you cannot have one PKCS#11 object for
7652 +        * both data signing and verifying.
7653 +        */
7654 +       if ((sp->opdata_rsa_pub != rsa) ||
7655 +           (BN_cmp(sp->opdata_rsa_n_num, rsa->n) != 0) ||
7656 +           (BN_cmp(sp->opdata_rsa_e_num, rsa->e) != 0) ||
7657 +           (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE))
7658 +               {
7659 +               /*
7660 +                * We do not check the return value because even in case of
7661 +                * failure the sp structure will have both key pointer
7662 +                * and object handle cleaned and pk11_destroy_object()
7663 +                * reports the failure to the OpenSSL error message buffer.
7664 +                */
7665 +               (void) pk11_destroy_rsa_object_pub(sp, TRUE);
7666 +               return (0);
7667 +               }
7668 +       return (1);
7669 +       }
7672 + * Check for cache miss and clean the object pointer and handle
7673 + * in such case. Return 1 for cache hit, 0 for cache miss.
7674 + */
7675 +static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa)
7676 +       {
7677 +       /*
7678 +        * Provide protection against RSA structure reuse by making
7679 +        * the check for cache hit stronger. Comparing public exponent
7680 +        * of RSA key with value cached in PK11_SESSION structure
7681 +        * should be sufficient. Note that we want to compare the
7682 +        * public component since with the keys by reference
7683 +        * mechanism, private components are not in the RSA
7684 +        * structure. Also, see check_new_rsa_key_pub() about why we
7685 +        * compare the handle as well.
7686 +        */
7687 +       if ((sp->opdata_rsa_priv != rsa) ||
7688 +           (BN_cmp(sp->opdata_rsa_pn_num, rsa->n) != 0) ||
7689 +           (BN_cmp(sp->opdata_rsa_pe_num, rsa->e) != 0) ||
7690 +           (sp->opdata_rsa_pn_num == NULL) ||
7691 +           (sp->opdata_rsa_pe_num == NULL) ||
7692 +           (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE))
7693 +               {
7694 +               /*
7695 +                * We do not check the return value because even in case of
7696 +                * failure the sp structure will have both key pointer
7697 +                * and object handle cleaned and pk11_destroy_object()
7698 +                * reports the failure to the OpenSSL error message buffer.
7699 +                */
7700 +               (void) pk11_destroy_rsa_object_priv(sp, TRUE);
7701 +               return (0);
7702 +               }
7703 +       return (1);
7704 +       }
7705 +#endif
7707 +#ifndef OPENSSL_NO_DSA
7708 +/* The DSA function implementation */
7709 +/* ARGSUSED */
7710 +static int pk11_DSA_init(DSA *dsa)
7711 +       {
7712 +       return (1);
7713 +       }
7715 +/* ARGSUSED */
7716 +static int pk11_DSA_finish(DSA *dsa)
7717 +       {
7718 +       return (1);
7719 +       }
7722 +static DSA_SIG *
7723 +pk11_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
7724 +       {
7725 +       BIGNUM *r = NULL, *s = NULL;
7726 +       int i;
7727 +       DSA_SIG *dsa_sig = NULL;
7729 +       CK_RV rv;
7730 +       CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
7731 +       CK_MECHANISM *p_mech = &Mechanism_dsa;
7732 +       CK_OBJECT_HANDLE h_priv_key;
7734 +       /*
7735 +        * The signature is the concatenation of r and s,
7736 +        * each is 20 bytes long
7737 +        */
7738 +       unsigned char sigret[DSA_SIGNATURE_LEN];
7739 +       unsigned long siglen = DSA_SIGNATURE_LEN;
7740 +       unsigned int siglen2 = DSA_SIGNATURE_LEN / 2;
7742 +       PK11_SESSION *sp = NULL;
7744 +       if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
7745 +               {
7746 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MISSING_KEY_COMPONENT);
7747 +               goto ret;
7748 +               }
7750 +       i = BN_num_bytes(dsa->q); /* should be 20 */
7751 +       if (dlen > i)
7752 +               {
7753 +               PK11err(PK11_F_DSA_SIGN, PK11_R_INVALID_SIGNATURE_LENGTH);
7754 +               goto ret;
7755 +               }
7757 +       if ((sp = pk11_get_session(OP_DSA)) == NULL)
7758 +               goto ret;
7760 +       (void) check_new_dsa_key_priv(sp, dsa);
7762 +       h_priv_key = sp->opdata_dsa_priv_key;
7763 +       if (h_priv_key == CK_INVALID_HANDLE)
7764 +               h_priv_key = sp->opdata_dsa_priv_key =
7765 +                       pk11_get_private_dsa_key((DSA *)dsa,
7766 +                           &sp->opdata_dsa_priv,
7767 +                           &sp->opdata_dsa_priv_num, sp->session);
7769 +       if (h_priv_key != CK_INVALID_HANDLE)
7770 +               {
7771 +               rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
7773 +               if (rv != CKR_OK)
7774 +                       {
7775 +                       PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGNINIT, rv);
7776 +                       goto ret;
7777 +                       }
7779 +               (void) memset(sigret, 0, siglen);
7780 +               rv = pFuncList->C_Sign(sp->session,
7781 +                       (unsigned char*) dgst, dlen, sigret,
7782 +                       (CK_ULONG_PTR) &siglen);
7784 +               if (rv != CKR_OK)
7785 +                       {
7786 +                       PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGN, rv);
7787 +                       goto ret;
7788 +                       }
7789 +               }
7792 +       if ((s = BN_new()) == NULL)
7793 +               {
7794 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7795 +               goto ret;
7796 +               }
7798 +       if ((r = BN_new()) == NULL)
7799 +               {
7800 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7801 +               goto ret;
7802 +               }
7804 +       if ((dsa_sig = DSA_SIG_new()) == NULL)
7805 +               {
7806 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7807 +               goto ret;
7808 +               }
7810 +       if (BN_bin2bn(sigret, siglen2, r) == NULL ||
7811 +           BN_bin2bn(&sigret[siglen2], siglen2, s) == NULL)
7812 +               {
7813 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7814 +               goto ret;
7815 +               }
7817 +       dsa_sig->r = r;
7818 +       dsa_sig->s = s;
7820 +ret:
7821 +       if (dsa_sig == NULL)
7822 +               {
7823 +               if (r != NULL)
7824 +                       BN_free(r);
7825 +               if (s != NULL)
7826 +                       BN_free(s);
7827 +               }
7829 +       pk11_return_session(sp, OP_DSA);
7830 +       return (dsa_sig);
7831 +       }
7833 +static int
7834 +pk11_dsa_do_verify(const unsigned char *dgst, int dlen, DSA_SIG *sig,
7835 +       DSA *dsa)
7836 +       {
7837 +       int i;
7838 +       CK_RV rv;
7839 +       int retval = 0;
7840 +       CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
7841 +       CK_MECHANISM *p_mech = &Mechanism_dsa;
7842 +       CK_OBJECT_HANDLE h_pub_key;
7844 +       unsigned char sigbuf[DSA_SIGNATURE_LEN];
7845 +       unsigned long siglen = DSA_SIGNATURE_LEN;
7846 +       unsigned long siglen2 = DSA_SIGNATURE_LEN/2;
7848 +       PK11_SESSION *sp = NULL;
7850 +       if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0)
7851 +               {
7852 +               PK11err(PK11_F_DSA_VERIFY,
7853 +                       PK11_R_INVALID_DSA_SIGNATURE_R);
7854 +               goto ret;
7855 +               }
7857 +       if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0)
7858 +               {
7859 +               PK11err(PK11_F_DSA_VERIFY,
7860 +                       PK11_R_INVALID_DSA_SIGNATURE_S);
7861 +               goto ret;
7862 +               }
7864 +       i = BN_num_bytes(dsa->q); /* should be 20 */
7866 +       if (dlen > i)
7867 +               {
7868 +               PK11err(PK11_F_DSA_VERIFY,
7869 +                       PK11_R_INVALID_SIGNATURE_LENGTH);
7870 +               goto ret;
7871 +               }
7873 +       if ((sp = pk11_get_session(OP_DSA)) == NULL)
7874 +               goto ret;
7876 +       (void) check_new_dsa_key_pub(sp, dsa);
7878 +       h_pub_key = sp->opdata_dsa_pub_key;
7879 +       if (h_pub_key == CK_INVALID_HANDLE)
7880 +               h_pub_key = sp->opdata_dsa_pub_key =
7881 +                       pk11_get_public_dsa_key((DSA *)dsa, &sp->opdata_dsa_pub,
7882 +                           &sp->opdata_dsa_pub_num, sp->session);
7884 +       if (h_pub_key != CK_INVALID_HANDLE)
7885 +               {
7886 +               rv = pFuncList->C_VerifyInit(sp->session, p_mech,
7887 +                       h_pub_key);
7889 +               if (rv != CKR_OK)
7890 +                       {
7891 +                       PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFYINIT,
7892 +                           rv);
7893 +                       goto ret;
7894 +                       }
7896 +               /*
7897 +                * The representation of each of the two big numbers could
7898 +                * be shorter than DSA_SIGNATURE_LEN/2 bytes so we need
7899 +                * to act accordingly and shift if necessary.
7900 +                */
7901 +               (void) memset(sigbuf, 0, siglen);
7902 +               BN_bn2bin(sig->r, sigbuf + siglen2 - BN_num_bytes(sig->r));
7903 +               BN_bn2bin(sig->s, &sigbuf[siglen2] + siglen2 -
7904 +                   BN_num_bytes(sig->s));
7906 +               rv = pFuncList->C_Verify(sp->session,
7907 +                       (unsigned char *) dgst, dlen, sigbuf, (CK_ULONG)siglen);
7909 +               if (rv != CKR_OK)
7910 +                       {
7911 +                       PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFY, rv);
7912 +                       goto ret;
7913 +                       }
7914 +               }
7916 +       retval = 1;
7917 +ret:
7919 +       pk11_return_session(sp, OP_DSA);
7920 +       return (retval);
7921 +       }
7925 + * Create a public key object in a session from a given dsa structure.
7926 + * The *dsa_pub_num pointer is non-NULL for DSA public keys.
7927 + */
7928 +static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa,
7929 +    DSA **key_ptr, BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session)
7930 +       {
7931 +       CK_RV rv;
7932 +       CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
7933 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
7934 +       CK_ULONG found;
7935 +       CK_KEY_TYPE k_type = CKK_DSA;
7936 +       CK_ULONG ul_key_attr_count = 8;
7937 +       CK_BBOOL rollback = FALSE;
7938 +       int i;
7940 +       CK_ATTRIBUTE  a_key_template[] =
7941 +               {
7942 +               {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
7943 +               {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
7944 +               {CKA_TOKEN, &myfalse, sizeof (myfalse)},
7945 +               {CKA_VERIFY, &mytrue, sizeof (mytrue)},
7946 +               {CKA_PRIME, (void *)NULL, 0},           /* p */
7947 +               {CKA_SUBPRIME, (void *)NULL, 0},        /* q */
7948 +               {CKA_BASE, (void *)NULL, 0},            /* g */
7949 +               {CKA_VALUE, (void *)NULL, 0}            /* pub_key - y */
7950 +               };
7952 +       a_key_template[0].pValue = &o_key;
7953 +       a_key_template[1].pValue = &k_type;
7955 +       if (init_template_value(dsa->p, &a_key_template[4].pValue,
7956 +               &a_key_template[4].ulValueLen) == 0 ||
7957 +           init_template_value(dsa->q, &a_key_template[5].pValue,
7958 +               &a_key_template[5].ulValueLen) == 0 ||
7959 +           init_template_value(dsa->g, &a_key_template[6].pValue,
7960 +               &a_key_template[6].ulValueLen) == 0 ||
7961 +           init_template_value(dsa->pub_key, &a_key_template[7].pValue,
7962 +               &a_key_template[7].ulValueLen) == 0)
7963 +               {
7964 +               PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
7965 +               goto malloc_err;
7966 +               }
7968 +       /* see find_lock array definition for more info on object locking */
7969 +       LOCK_OBJSTORE(OP_DSA);
7970 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template,
7971 +               ul_key_attr_count);
7973 +       if (rv != CKR_OK)
7974 +               {
7975 +               PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
7976 +                   PK11_R_FINDOBJECTSINIT, rv);
7977 +               goto err;
7978 +               }
7980 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
7982 +       if (rv != CKR_OK)
7983 +               {
7984 +               (void) pFuncList->C_FindObjectsFinal(session);
7985 +               PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
7986 +                   PK11_R_FINDOBJECTS, rv);
7987 +               goto err;
7988 +               }
7990 +       rv = pFuncList->C_FindObjectsFinal(session);
7992 +       if (rv != CKR_OK)
7993 +               {
7994 +               PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
7995 +                   PK11_R_FINDOBJECTSFINAL, rv);
7996 +               goto err;
7997 +               }
7999 +       if (found == 0)
8000 +               {
8001 +               rv = pFuncList->C_CreateObject(session,
8002 +                       a_key_template, ul_key_attr_count, &h_key);
8003 +               if (rv != CKR_OK)
8004 +                       {
8005 +                       PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
8006 +                           PK11_R_CREATEOBJECT, rv);
8007 +                       goto err;
8008 +                       }
8009 +               }
8011 +       if (dsa_pub_num != NULL)
8012 +               if ((*dsa_pub_num = BN_dup(dsa->pub_key)) == NULL)
8013 +                       {
8014 +                       PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
8015 +                       rollback = TRUE;
8016 +                       goto err;
8017 +                       }
8019 +       /* LINTED: E_CONSTANT_CONDITION */
8020 +       KEY_HANDLE_REFHOLD(h_key, OP_DSA, FALSE, rollback, err);
8021 +       if (key_ptr != NULL)
8022 +               *key_ptr = dsa;
8024 +err:
8025 +       if (rollback)
8026 +               {
8027 +               /*
8028 +                * We do not care about the return value from C_DestroyObject()
8029 +                * since we are doing rollback.
8030 +                */
8031 +               if (found == 0)
8032 +                       (void) pFuncList->C_DestroyObject(session, h_key);
8033 +               h_key = CK_INVALID_HANDLE;
8034 +               }
8036 +       UNLOCK_OBJSTORE(OP_DSA);
8038 +malloc_err:
8039 +       for (i = 4; i <= 7; i++)
8040 +               {
8041 +               if (a_key_template[i].pValue != NULL)
8042 +                       {
8043 +                       OPENSSL_free(a_key_template[i].pValue);
8044 +                       a_key_template[i].pValue = NULL;
8045 +                       }
8046 +               }
8048 +       return (h_key);
8049 +       }
8052 + * Create a private key object in the session from a given dsa structure
8053 + * The *dsa_priv_num pointer is non-NULL for DSA private keys.
8054 + */
8055 +static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa,
8056 +    DSA **key_ptr, BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session)
8057 +       {
8058 +       CK_RV rv;
8059 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
8060 +       CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
8061 +       int i;
8062 +       CK_ULONG found;
8063 +       CK_KEY_TYPE k_type = CKK_DSA;
8064 +       CK_ULONG ul_key_attr_count = 9;
8065 +       CK_BBOOL rollback = FALSE;
8067 +       /* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys */
8068 +       CK_ATTRIBUTE  a_key_template[] =
8069 +               {
8070 +               {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
8071 +               {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
8072 +               {CKA_TOKEN, &myfalse, sizeof (myfalse)},
8073 +               {CKA_SENSITIVE, &myfalse, sizeof (myfalse)},
8074 +               {CKA_SIGN, &mytrue, sizeof (mytrue)},
8075 +               {CKA_PRIME, (void *)NULL, 0},           /* p */
8076 +               {CKA_SUBPRIME, (void *)NULL, 0},        /* q */
8077 +               {CKA_BASE, (void *)NULL, 0},            /* g */
8078 +               {CKA_VALUE, (void *)NULL, 0}            /* priv_key - x */
8079 +               };
8081 +       a_key_template[0].pValue = &o_key;
8082 +       a_key_template[1].pValue = &k_type;
8084 +       /* Put the private key components into the template */
8085 +       if (init_template_value(dsa->p, &a_key_template[5].pValue,
8086 +               &a_key_template[5].ulValueLen) == 0 ||
8087 +           init_template_value(dsa->q, &a_key_template[6].pValue,
8088 +               &a_key_template[6].ulValueLen) == 0 ||
8089 +           init_template_value(dsa->g, &a_key_template[7].pValue,
8090 +               &a_key_template[7].ulValueLen) == 0 ||
8091 +           init_template_value(dsa->priv_key, &a_key_template[8].pValue,
8092 +               &a_key_template[8].ulValueLen) == 0)
8093 +               {
8094 +               PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
8095 +               goto malloc_err;
8096 +               }
8098 +       /* see find_lock array definition for more info on object locking */
8099 +       LOCK_OBJSTORE(OP_DSA);
8100 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template,
8101 +               ul_key_attr_count);
8103 +       if (rv != CKR_OK)
8104 +               {
8105 +               PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
8106 +                   PK11_R_FINDOBJECTSINIT, rv);
8107 +               goto err;
8108 +               }
8110 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
8112 +       if (rv != CKR_OK)
8113 +               {
8114 +               (void) pFuncList->C_FindObjectsFinal(session);
8115 +               PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
8116 +                   PK11_R_FINDOBJECTS, rv);
8117 +               goto err;
8118 +               }
8120 +       rv = pFuncList->C_FindObjectsFinal(session);
8122 +       if (rv != CKR_OK)
8123 +               {
8124 +               PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
8125 +                   PK11_R_FINDOBJECTSFINAL, rv);
8126 +               goto err;
8127 +               }
8129 +       if (found == 0)
8130 +               {
8131 +               rv = pFuncList->C_CreateObject(session,
8132 +                       a_key_template, ul_key_attr_count, &h_key);
8133 +               if (rv != CKR_OK)
8134 +                       {
8135 +                       PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
8136 +                           PK11_R_CREATEOBJECT, rv);
8137 +                       goto err;
8138 +                       }
8139 +               }
8141 +       if (dsa_priv_num != NULL)
8142 +               if ((*dsa_priv_num = BN_dup(dsa->priv_key)) == NULL)
8143 +                       {
8144 +                       PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
8145 +                       rollback = TRUE;
8146 +                       goto err;
8147 +                       }
8149 +       /* LINTED: E_CONSTANT_CONDITION */
8150 +       KEY_HANDLE_REFHOLD(h_key, OP_DSA, FALSE, rollback, err);
8151 +       if (key_ptr != NULL)
8152 +               *key_ptr = dsa;
8154 +err:
8155 +       if (rollback)
8156 +               {
8157 +               /*
8158 +                * We do not care about the return value from C_DestroyObject()
8159 +                * since we are doing rollback.
8160 +                */
8161 +               if (found == 0)
8162 +                       (void) pFuncList->C_DestroyObject(session, h_key);
8163 +               h_key = CK_INVALID_HANDLE;
8164 +               }
8166 +       UNLOCK_OBJSTORE(OP_DSA);
8168 +malloc_err:
8169 +       /*
8170 +        * 5 to 8 entries in the key template are key components.
8171 +        * They need to be freed apon exit or error.
8172 +        */
8173 +       for (i = 5; i <= 8; i++)
8174 +               {
8175 +               if (a_key_template[i].pValue != NULL)
8176 +                       {
8177 +                       (void) memset(a_key_template[i].pValue, 0,
8178 +                               a_key_template[i].ulValueLen);
8179 +                       OPENSSL_free(a_key_template[i].pValue);
8180 +                       a_key_template[i].pValue = NULL;
8181 +                       }
8182 +               }
8184 +       return (h_key);
8185 +       }
8188 + * Check for cache miss and clean the object pointer and handle
8189 + * in such case. Return 1 for cache hit, 0 for cache miss.
8190 + */
8191 +static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa)
8192 +       {
8193 +       /*
8194 +        * Provide protection against DSA structure reuse by making the
8195 +        * check for cache hit stronger. Only public key component of DSA
8196 +        * key matters here so it is sufficient to compare it with value
8197 +        * cached in PK11_SESSION structure.
8198 +        */
8199 +       if ((sp->opdata_dsa_pub != dsa) ||
8200 +           (BN_cmp(sp->opdata_dsa_pub_num, dsa->pub_key) != 0))
8201 +               {
8202 +               /*
8203 +                * We do not check the return value because even in case of
8204 +                * failure the sp structure will have both key pointer
8205 +                * and object handle cleaned and pk11_destroy_object()
8206 +                * reports the failure to the OpenSSL error message buffer.
8207 +                */
8208 +               (void) pk11_destroy_dsa_object_pub(sp, TRUE);
8209 +               return (0);
8210 +               }
8211 +       return (1);
8212 +       }
8215 + * Check for cache miss and clean the object pointer and handle
8216 + * in such case. Return 1 for cache hit, 0 for cache miss.
8217 + */
8218 +static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa)
8219 +       {
8220 +       /*
8221 +        * Provide protection against DSA structure reuse by making the
8222 +        * check for cache hit stronger. Only private key component of DSA
8223 +        * key matters here so it is sufficient to compare it with value
8224 +        * cached in PK11_SESSION structure.
8225 +        */
8226 +       if ((sp->opdata_dsa_priv != dsa) ||
8227 +           (BN_cmp(sp->opdata_dsa_priv_num, dsa->priv_key) != 0))
8228 +               {
8229 +               /*
8230 +                * We do not check the return value because even in case of
8231 +                * failure the sp structure will have both key pointer
8232 +                * and object handle cleaned and pk11_destroy_object()
8233 +                * reports the failure to the OpenSSL error message buffer.
8234 +                */
8235 +               (void) pk11_destroy_dsa_object_priv(sp, TRUE);
8236 +               return (0);
8237 +               }
8238 +       return (1);
8239 +       }
8240 +#endif
8243 +#ifndef OPENSSL_NO_DH
8244 +/* The DH function implementation */
8245 +/* ARGSUSED */
8246 +static int pk11_DH_init(DH *dh)
8247 +       {
8248 +       return (1);
8249 +       }
8251 +/* ARGSUSED */
8252 +static int pk11_DH_finish(DH *dh)
8253 +       {
8254 +       return (1);
8255 +       }
8258 + * Generate DH key-pair.
8259 + *
8260 + * Warning: Unlike OpenSSL's DH_generate_key(3) we ignore dh->priv_key
8261 + * and override it even if it is set. OpenSSL does not touch dh->priv_key
8262 + * if set and just computes dh->pub_key. It looks like PKCS#11 standard
8263 + * is not capable of providing this functionality. This could be a problem
8264 + * for applications relying on OpenSSL's semantics.
8265 + */
8266 +static int pk11_DH_generate_key(DH *dh)
8267 +       {
8268 +       CK_ULONG i;
8269 +       CK_RV rv, rv1;
8270 +       int reuse_mem_len = 0, ret = 0;
8271 +       PK11_SESSION *sp = NULL;
8272 +       CK_BYTE_PTR reuse_mem;
8274 +       CK_MECHANISM mechanism = {CKM_DH_PKCS_KEY_PAIR_GEN, NULL_PTR, 0};
8275 +       CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
8276 +       CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
8278 +       CK_ULONG ul_pub_key_attr_count = 3;
8279 +       CK_ATTRIBUTE pub_key_template[] =
8280 +               {
8281 +               {CKA_PRIVATE, &myfalse, sizeof (myfalse)},
8282 +               {CKA_PRIME, (void *)NULL, 0},
8283 +               {CKA_BASE, (void *)NULL, 0}
8284 +               };
8286 +       CK_ULONG ul_priv_key_attr_count = 3;
8287 +       CK_ATTRIBUTE priv_key_template[] =
8288 +               {
8289 +               {CKA_PRIVATE, &myfalse, sizeof (myfalse)},
8290 +               {CKA_SENSITIVE, &myfalse, sizeof (myfalse)},
8291 +               {CKA_DERIVE, &mytrue, sizeof (mytrue)}
8292 +               };
8294 +       CK_ULONG pub_key_attr_result_count = 1;
8295 +       CK_ATTRIBUTE pub_key_result[] =
8296 +               {
8297 +               {CKA_VALUE, (void *)NULL, 0}
8298 +               };
8300 +       CK_ULONG priv_key_attr_result_count = 1;
8301 +       CK_ATTRIBUTE priv_key_result[] =
8302 +               {
8303 +               {CKA_VALUE, (void *)NULL, 0}
8304 +               };
8306 +       pub_key_template[1].ulValueLen = BN_num_bytes(dh->p);
8307 +       if (pub_key_template[1].ulValueLen > 0)
8308 +               {
8309 +               /*
8310 +                * We must not increase ulValueLen by DH_BUF_RESERVE since that
8311 +                * could cause the same rounding problem. See definition of
8312 +                * DH_BUF_RESERVE above.
8313 +                */
8314 +               pub_key_template[1].pValue =
8315 +                       OPENSSL_malloc(pub_key_template[1].ulValueLen +
8316 +                       DH_BUF_RESERVE);
8317 +               if (pub_key_template[1].pValue == NULL)
8318 +                       {
8319 +                       PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
8320 +                       goto err;
8321 +                       }
8323 +               i = BN_bn2bin(dh->p, pub_key_template[1].pValue);
8324 +               }
8325 +       else
8326 +               goto err;
8328 +       pub_key_template[2].ulValueLen = BN_num_bytes(dh->g);
8329 +       if (pub_key_template[2].ulValueLen > 0)
8330 +               {
8331 +               pub_key_template[2].pValue =
8332 +                       OPENSSL_malloc(pub_key_template[2].ulValueLen +
8333 +                       DH_BUF_RESERVE);
8334 +               if (pub_key_template[2].pValue == NULL)
8335 +                       {
8336 +                       PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
8337 +                       goto err;
8338 +                       }
8340 +               i = BN_bn2bin(dh->g, pub_key_template[2].pValue);
8341 +               }
8342 +       else
8343 +               goto err;
8345 +       /*
8346 +        * Note: we are only using PK11_SESSION structure for getting
8347 +        *       a session handle. The objects created in this function are
8348 +        *       destroyed before return and thus not cached.
8349 +        */
8350 +       if ((sp = pk11_get_session(OP_DH)) == NULL)
8351 +               goto err;
8353 +       rv = pFuncList->C_GenerateKeyPair(sp->session,
8354 +           &mechanism,
8355 +           pub_key_template,
8356 +           ul_pub_key_attr_count,
8357 +           priv_key_template,
8358 +           ul_priv_key_attr_count,
8359 +           &h_pub_key,
8360 +           &h_priv_key);
8361 +       if (rv != CKR_OK)
8362 +               {
8363 +               PK11err_add_data(PK11_F_DH_GEN_KEY, PK11_R_GEN_KEY, rv);
8364 +               goto err;
8365 +               }
8367 +       /*
8368 +        * Reuse the larger memory allocated. We know the larger memory
8369 +        * should be sufficient for reuse.
8370 +        */
8371 +       if (pub_key_template[1].ulValueLen > pub_key_template[2].ulValueLen)
8372 +               {
8373 +               reuse_mem = pub_key_template[1].pValue;
8374 +               reuse_mem_len = pub_key_template[1].ulValueLen + DH_BUF_RESERVE;
8375 +               }
8376 +       else
8377 +               {
8378 +               reuse_mem = pub_key_template[2].pValue;
8379 +               reuse_mem_len = pub_key_template[2].ulValueLen + DH_BUF_RESERVE;
8380 +               }
8382 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
8383 +               pub_key_result, pub_key_attr_result_count);
8384 +       rv1 = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
8385 +               priv_key_result, priv_key_attr_result_count);
8387 +       if (rv != CKR_OK || rv1 != CKR_OK)
8388 +               {
8389 +               rv = (rv != CKR_OK) ? rv : rv1;
8390 +               PK11err_add_data(PK11_F_DH_GEN_KEY,
8391 +                   PK11_R_GETATTRIBUTVALUE, rv);
8392 +               goto err;
8393 +               }
8395 +       if (((CK_LONG) pub_key_result[0].ulValueLen) <= 0 ||
8396 +               ((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
8397 +               {
8398 +               PK11err(PK11_F_DH_GEN_KEY, PK11_R_GETATTRIBUTVALUE);
8399 +               goto err;
8400 +               }
8402 +       /* Reuse the memory allocated */
8403 +       pub_key_result[0].pValue = reuse_mem;
8404 +       pub_key_result[0].ulValueLen = reuse_mem_len;
8406 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
8407 +               pub_key_result, pub_key_attr_result_count);
8409 +       if (rv != CKR_OK)
8410 +               {
8411 +               PK11err_add_data(PK11_F_DH_GEN_KEY,
8412 +                   PK11_R_GETATTRIBUTVALUE, rv);
8413 +               goto err;
8414 +               }
8416 +       if (pub_key_result[0].type == CKA_VALUE)
8417 +               {
8418 +               if (dh->pub_key == NULL)
8419 +                       if ((dh->pub_key = BN_new()) == NULL)
8420 +                               {
8421 +                               PK11err(PK11_F_DH_GEN_KEY,
8422 +                                       PK11_R_MALLOC_FAILURE);
8423 +                               goto err;
8424 +                               }
8425 +               dh->pub_key = BN_bin2bn(pub_key_result[0].pValue,
8426 +                       pub_key_result[0].ulValueLen, dh->pub_key);
8427 +               if (dh->pub_key == NULL)
8428 +                       {
8429 +                       PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
8430 +                       goto err;
8431 +                       }
8432 +               }
8434 +       /* Reuse the memory allocated */
8435 +       priv_key_result[0].pValue = reuse_mem;
8436 +       priv_key_result[0].ulValueLen = reuse_mem_len;
8438 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
8439 +               priv_key_result, priv_key_attr_result_count);
8441 +       if (rv != CKR_OK)
8442 +               {
8443 +               PK11err_add_data(PK11_F_DH_GEN_KEY,
8444 +                   PK11_R_GETATTRIBUTVALUE, rv);
8445 +               goto err;
8446 +               }
8448 +       if (priv_key_result[0].type == CKA_VALUE)
8449 +               {
8450 +               if (dh->priv_key == NULL)
8451 +                       if ((dh->priv_key = BN_new()) == NULL)
8452 +                               {
8453 +                               PK11err(PK11_F_DH_GEN_KEY,
8454 +                                       PK11_R_MALLOC_FAILURE);
8455 +                               goto err;
8456 +                               }
8457 +               dh->priv_key = BN_bin2bn(priv_key_result[0].pValue,
8458 +                       priv_key_result[0].ulValueLen, dh->priv_key);
8459 +               if (dh->priv_key == NULL)
8460 +                       {
8461 +                       PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
8462 +                       goto err;
8463 +                       }
8464 +               }
8466 +       ret = 1;
8468 +err:
8470 +       if (h_pub_key != CK_INVALID_HANDLE)
8471 +               {
8472 +               rv = pFuncList->C_DestroyObject(sp->session, h_pub_key);
8473 +               if (rv != CKR_OK)
8474 +                       {
8475 +                       PK11err_add_data(PK11_F_DH_GEN_KEY,
8476 +                           PK11_R_DESTROYOBJECT, rv);
8477 +                       }
8478 +               }
8480 +       if (h_priv_key != CK_INVALID_HANDLE)
8481 +               {
8482 +               rv = pFuncList->C_DestroyObject(sp->session, h_priv_key);
8483 +               if (rv != CKR_OK)
8484 +                       {
8485 +                       PK11err_add_data(PK11_F_DH_GEN_KEY,
8486 +                           PK11_R_DESTROYOBJECT, rv);
8487 +                       }
8488 +               }
8490 +       for (i = 1; i <= 2; i++)
8491 +               {
8492 +               if (pub_key_template[i].pValue != NULL)
8493 +                       {
8494 +                       OPENSSL_free(pub_key_template[i].pValue);
8495 +                       pub_key_template[i].pValue = NULL;
8496 +                       }
8497 +               }
8499 +       pk11_return_session(sp, OP_DH);
8500 +       return (ret);
8501 +       }
8503 +static int pk11_DH_compute_key(unsigned char *key, const BIGNUM *pub_key,
8504 +       DH *dh)
8505 +       {
8506 +       unsigned int i;
8507 +       CK_MECHANISM mechanism = {CKM_DH_PKCS_DERIVE, NULL_PTR, 0};
8508 +       CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
8509 +       CK_KEY_TYPE key_type = CKK_GENERIC_SECRET;
8510 +       CK_OBJECT_HANDLE h_derived_key = CK_INVALID_HANDLE;
8511 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
8513 +       CK_ULONG seclen;
8514 +       CK_ULONG ul_priv_key_attr_count = 3;
8515 +       CK_ATTRIBUTE priv_key_template[] =
8516 +               {
8517 +               {CKA_CLASS, (void*) NULL, sizeof (key_class)},
8518 +               {CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
8519 +               {CKA_VALUE_LEN, &seclen, sizeof (seclen)},
8520 +               };
8522 +       CK_ULONG priv_key_attr_result_count = 1;
8523 +       CK_ATTRIBUTE priv_key_result[] =
8524 +               {
8525 +               {CKA_VALUE, (void *)NULL, 0}
8526 +               };
8528 +       CK_RV rv;
8529 +       int ret = -1;
8530 +       PK11_SESSION *sp = NULL;
8532 +       if (dh->priv_key == NULL)
8533 +               goto err;
8535 +       priv_key_template[0].pValue = &key_class;
8536 +       priv_key_template[1].pValue = &key_type;
8537 +       seclen = BN_num_bytes(dh->p);
8539 +       if ((sp = pk11_get_session(OP_DH)) == NULL)
8540 +               goto err;
8542 +       mechanism.ulParameterLen = BN_num_bytes(pub_key);
8543 +       mechanism.pParameter = OPENSSL_malloc(mechanism.ulParameterLen);
8544 +       if (mechanism.pParameter == NULL)
8545 +               {
8546 +               PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
8547 +               goto err;
8548 +               }
8549 +       BN_bn2bin(pub_key, mechanism.pParameter);
8551 +       (void) check_new_dh_key(sp, dh);
8553 +       h_key = sp->opdata_dh_key;
8554 +       if (h_key == CK_INVALID_HANDLE)
8555 +               h_key = sp->opdata_dh_key =
8556 +                       pk11_get_dh_key((DH*) dh, &sp->opdata_dh,
8557 +                           &sp->opdata_dh_priv_num, sp->session);
8559 +       if (h_key == CK_INVALID_HANDLE)
8560 +               {
8561 +               PK11err(PK11_F_DH_COMP_KEY, PK11_R_CREATEOBJECT);
8562 +               goto err;
8563 +               }
8565 +       rv = pFuncList->C_DeriveKey(sp->session,
8566 +           &mechanism,
8567 +           h_key,
8568 +           priv_key_template,
8569 +           ul_priv_key_attr_count,
8570 +           &h_derived_key);
8571 +       if (rv != CKR_OK)
8572 +               {
8573 +               PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_DERIVEKEY, rv);
8574 +               goto err;
8575 +               }
8577 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
8578 +           priv_key_result, priv_key_attr_result_count);
8580 +       if (rv != CKR_OK)
8581 +               {
8582 +               PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
8583 +                   rv);
8584 +               goto err;
8585 +               }
8587 +       if (((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
8588 +               {
8589 +               PK11err(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE);
8590 +               goto err;
8591 +               }
8592 +       priv_key_result[0].pValue =
8593 +               OPENSSL_malloc(priv_key_result[0].ulValueLen);
8594 +       if (!priv_key_result[0].pValue)
8595 +               {
8596 +               PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
8597 +               goto err;
8598 +               }
8600 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
8601 +               priv_key_result, priv_key_attr_result_count);
8603 +       if (rv != CKR_OK)
8604 +               {
8605 +               PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
8606 +                   rv);
8607 +               goto err;
8608 +               }
8610 +       /*
8611 +        * OpenSSL allocates the output buffer 'key' which is the same
8612 +        * length of the public key. It is long enough for the derived key
8613 +        */
8614 +       if (priv_key_result[0].type == CKA_VALUE)
8615 +               {
8616 +               /*
8617 +                * CKM_DH_PKCS_DERIVE mechanism is not supposed to strip
8618 +                * leading zeros from a computed shared secret. However,
8619 +                * OpenSSL always did it so we must do the same here. The
8620 +                * vagueness of the spec regarding leading zero bytes was
8621 +                * finally cleared with TLS 1.1 (RFC 4346) saying that leading
8622 +                * zeros are stripped before the computed data is used as the
8623 +                * pre-master secret.
8624 +                */
8625 +               for (i = 0; i < priv_key_result[0].ulValueLen; ++i)
8626 +                       {
8627 +                       if (((char *)priv_key_result[0].pValue)[i] != 0)
8628 +                               break;
8629 +                       }
8631 +               (void) memcpy(key, ((char *)priv_key_result[0].pValue) + i,
8632 +                       priv_key_result[0].ulValueLen - i);
8633 +               ret = priv_key_result[0].ulValueLen - i;
8634 +               }
8636 +err:
8638 +       if (h_derived_key != CK_INVALID_HANDLE)
8639 +               {
8640 +               rv = pFuncList->C_DestroyObject(sp->session, h_derived_key);
8641 +               if (rv != CKR_OK)
8642 +                       {
8643 +                       PK11err_add_data(PK11_F_DH_COMP_KEY,
8644 +                           PK11_R_DESTROYOBJECT, rv);
8645 +                       }
8646 +               }
8647 +       if (priv_key_result[0].pValue)
8648 +               {
8649 +               OPENSSL_free(priv_key_result[0].pValue);
8650 +               priv_key_result[0].pValue = NULL;
8651 +               }
8653 +       if (mechanism.pParameter)
8654 +               {
8655 +               OPENSSL_free(mechanism.pParameter);
8656 +               mechanism.pParameter = NULL;
8657 +               }
8659 +       pk11_return_session(sp, OP_DH);
8660 +       return (ret);
8661 +       }
8664 +static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh,
8665 +       DH **key_ptr, BIGNUM **dh_priv_num, CK_SESSION_HANDLE session)
8666 +       {
8667 +       CK_RV rv;
8668 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
8669 +       CK_OBJECT_CLASS class = CKO_PRIVATE_KEY;
8670 +       CK_KEY_TYPE key_type = CKK_DH;
8671 +       CK_ULONG found;
8672 +       CK_BBOOL rollback = FALSE;
8673 +       int i;
8675 +       CK_ULONG ul_key_attr_count = 7;
8676 +       CK_ATTRIBUTE key_template[] =
8677 +               {
8678 +               {CKA_CLASS, (void*) NULL, sizeof (class)},
8679 +               {CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
8680 +               {CKA_DERIVE, &mytrue, sizeof (mytrue)},
8681 +               {CKA_PRIVATE, &myfalse, sizeof (myfalse)},
8682 +               {CKA_PRIME, (void *) NULL, 0},
8683 +               {CKA_BASE, (void *) NULL, 0},
8684 +               {CKA_VALUE, (void *) NULL, 0},
8685 +               };
8687 +       key_template[0].pValue = &class;
8688 +       key_template[1].pValue = &key_type;
8690 +       key_template[4].ulValueLen = BN_num_bytes(dh->p);
8691 +       key_template[4].pValue = (CK_VOID_PTR)OPENSSL_malloc(
8692 +               (size_t)key_template[4].ulValueLen);
8693 +       if (key_template[4].pValue == NULL)
8694 +               {
8695 +               PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8696 +               goto malloc_err;
8697 +               }
8699 +       BN_bn2bin(dh->p, key_template[4].pValue);
8701 +       key_template[5].ulValueLen = BN_num_bytes(dh->g);
8702 +       key_template[5].pValue = (CK_VOID_PTR)OPENSSL_malloc(
8703 +               (size_t)key_template[5].ulValueLen);
8704 +       if (key_template[5].pValue == NULL)
8705 +               {
8706 +               PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8707 +               goto malloc_err;
8708 +               }
8710 +       BN_bn2bin(dh->g, key_template[5].pValue);
8712 +       key_template[6].ulValueLen = BN_num_bytes(dh->priv_key);
8713 +       key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
8714 +               (size_t)key_template[6].ulValueLen);
8715 +       if (key_template[6].pValue == NULL)
8716 +               {
8717 +               PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8718 +               goto malloc_err;
8719 +               }
8721 +       BN_bn2bin(dh->priv_key, key_template[6].pValue);
8723 +       /* see find_lock array definition for more info on object locking */
8724 +       LOCK_OBJSTORE(OP_DH);
8725 +       rv = pFuncList->C_FindObjectsInit(session, key_template,
8726 +               ul_key_attr_count);
8728 +       if (rv != CKR_OK)
8729 +               {
8730 +               PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSINIT, rv);
8731 +               goto err;
8732 +               }
8734 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
8736 +       if (rv != CKR_OK)
8737 +               {
8738 +               (void) pFuncList->C_FindObjectsFinal(session);
8739 +               PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTS, rv);
8740 +               goto err;
8741 +               }
8743 +       rv = pFuncList->C_FindObjectsFinal(session);
8745 +       if (rv != CKR_OK)
8746 +               {
8747 +               PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSFINAL,
8748 +                   rv);
8749 +               goto err;
8750 +               }
8752 +       if (found == 0)
8753 +               {
8754 +               rv = pFuncList->C_CreateObject(session,
8755 +                       key_template, ul_key_attr_count, &h_key);
8756 +               if (rv != CKR_OK)
8757 +                       {
8758 +                       PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_CREATEOBJECT,
8759 +                           rv);
8760 +                       goto err;
8761 +                       }
8762 +               }
8764 +       if (dh_priv_num != NULL)
8765 +               if ((*dh_priv_num = BN_dup(dh->priv_key)) == NULL)
8766 +                       {
8767 +                       PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8768 +                       rollback = TRUE;
8769 +                       goto err;
8770 +                       }
8772 +       /* LINTED: E_CONSTANT_CONDITION */
8773 +       KEY_HANDLE_REFHOLD(h_key, OP_DH, FALSE, rollback, err);
8774 +       if (key_ptr != NULL)
8775 +               *key_ptr = dh;
8777 +err:
8778 +       if (rollback)
8779 +               {
8780 +               /*
8781 +                * We do not care about the return value from C_DestroyObject()
8782 +                * since we are doing rollback.
8783 +                */
8784 +               if (found == 0)
8785 +                       (void) pFuncList->C_DestroyObject(session, h_key);
8786 +               h_key = CK_INVALID_HANDLE;
8787 +               }
8789 +       UNLOCK_OBJSTORE(OP_DH);
8791 +malloc_err:
8792 +       for (i = 4; i <= 6; i++)
8793 +               {
8794 +               if (key_template[i].pValue != NULL)
8795 +                       {
8796 +                       OPENSSL_free(key_template[i].pValue);
8797 +                       key_template[i].pValue = NULL;
8798 +                       }
8799 +               }
8801 +       return (h_key);
8802 +       }
8805 + * Check for cache miss and clean the object pointer and handle
8806 + * in such case. Return 1 for cache hit, 0 for cache miss.
8807 + *
8808 + * Note: we rely on pk11_destroy_dh_key_objects() to set sp->opdata_dh
8809 + *       to CK_INVALID_HANDLE even when it fails to destroy the object.
8810 + */
8811 +static int check_new_dh_key(PK11_SESSION *sp, DH *dh)
8812 +       {
8813 +       /*
8814 +        * Provide protection against DH structure reuse by making the
8815 +        * check for cache hit stronger. Private key component of DH key
8816 +        * is unique so it is sufficient to compare it with value cached
8817 +        * in PK11_SESSION structure.
8818 +        */
8819 +       if ((sp->opdata_dh != dh) ||
8820 +           (BN_cmp(sp->opdata_dh_priv_num, dh->priv_key) != 0))
8821 +               {
8822 +               /*
8823 +                * We do not check the return value because even in case of
8824 +                * failure the sp structure will have both key pointer
8825 +                * and object handle cleaned and pk11_destroy_object()
8826 +                * reports the failure to the OpenSSL error message buffer.
8827 +                */
8828 +               (void) pk11_destroy_dh_object(sp, TRUE);
8829 +               return (0);
8830 +               }
8831 +       return (1);
8832 +       }
8833 +#endif
8836 + * Local function to simplify key template population
8837 + * Return 0 -- error, 1 -- no error
8838 + */
8839 +static int
8840 +init_template_value(BIGNUM *bn, CK_VOID_PTR *p_value,
8841 +       CK_ULONG *ul_value_len)
8842 +       {
8843 +       CK_ULONG len = 0;
8845 +       /*
8846 +        * This function can be used on non-initialized BIGNUMs. It is
8847 +        * easier to check that here than individually in the callers.
8848 +        */
8849 +       if (bn != NULL)
8850 +               len = BN_num_bytes(bn);
8852 +       if (bn == NULL || len == 0)
8853 +               return (1);
8855 +       *ul_value_len = len;
8856 +       *p_value = (CK_VOID_PTR)OPENSSL_malloc((size_t)*ul_value_len);
8857 +       if (*p_value == NULL)
8858 +               return (0);
8860 +       BN_bn2bin(bn, *p_value);
8862 +       return (1);
8863 +       }
8865 +static void
8866 +attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn)
8867 +       {
8868 +       if (attr->ulValueLen > 0)
8869 +               *bn = BN_bin2bn(attr_data, attr->ulValueLen, NULL);
8870 +       }
8873 + * Find one object in the token. It is an error if we can not find the
8874 + * object or if we find more objects based on the template we got.
8875 + * Assume object store locked.
8876 + *
8877 + * Returns:
8878 + *     1 OK
8879 + *     0 no object or more than 1 object found
8880 + */
8881 +static int
8882 +find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
8883 +    CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey)
8884 +       {
8885 +       CK_RV rv;
8886 +       CK_ULONG objcnt;
8888 +       if ((rv = pFuncList->C_FindObjectsInit(s, ptempl, nattr)) != CKR_OK)
8889 +               {
8890 +               PK11err_add_data(PK11_F_FIND_ONE_OBJECT,
8891 +                   PK11_R_FINDOBJECTSINIT, rv);
8892 +               return (0);
8893 +               }
8895 +       rv = pFuncList->C_FindObjects(s, pkey, 1, &objcnt);
8896 +       if (rv != CKR_OK)
8897 +               {
8898 +               (void) pFuncList->C_FindObjectsFinal(s);
8899 +               PK11err_add_data(PK11_F_FIND_ONE_OBJECT, PK11_R_FINDOBJECTS,
8900 +                   rv);
8901 +               return (0);
8902 +               }
8904 +       (void) pFuncList->C_FindObjectsFinal(s);
8906 +       if (objcnt > 1)
8907 +               {
8908 +               PK11err(PK11_F_FIND_ONE_OBJECT,
8909 +                   PK11_R_MORE_THAN_ONE_OBJECT_FOUND);
8910 +               return (0);
8911 +               }
8912 +       else if (objcnt == 0)
8913 +               {
8914 +               PK11err(PK11_F_FIND_ONE_OBJECT, PK11_R_NO_OBJECT_FOUND);
8915 +               return (0);
8916 +               }
8917 +       return (1);
8918 +       }
8920 +/* from uri stuff */
8922 +extern char *pk11_pin;
8924 +static int pk11_get_pin(void);
8926 +static int
8927 +pk11_get_pin(void)
8929 +       char *pin;
8931 +       /* The getpassphrase() function is not MT safe. */
8932 +#ifndef NOPTHREADS
8933 +       OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
8934 +#else
8935 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
8936 +#endif
8937 +       pin = getpassphrase("Enter PIN: ");
8938 +       if (pin == NULL)
8939 +               {
8940 +               PK11err(PK11_F_GET_PIN, PK11_R_COULD_NOT_READ_PIN);
8941 +#ifndef NOPTHREADS
8942 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
8943 +#else
8944 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
8945 +#endif
8946 +               return (0);
8947 +               }
8948 +       pk11_pin = BUF_strdup(pin);
8949 +       if (pk11_pin == NULL)
8950 +               {
8951 +               PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_MALLOC_FAILURE);
8952 +#ifndef NOPTHREADS
8953 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
8954 +#else
8955 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
8956 +#endif
8957 +               return (0);
8958 +               }
8959 +       memset(pin, 0, strlen(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 (1);
8966 +       }
8969 + * Log in to the keystore if we are supposed to do that at all. Take care of
8970 + * reading and caching the PIN etc. Log in only once even when called from
8971 + * multiple threads.
8972 + *
8973 + * Returns:
8974 + *     1 on success
8975 + *     0 on failure
8976 + */
8977 +static int
8978 +pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
8979 +    CK_BBOOL is_private)
8980 +       {
8981 +       CK_RV rv;
8983 +#if 0
8984 +       /* doesn't work on the AEP Keyper??? */
8985 +       if ((pubkey_token_flags & CKF_TOKEN_INITIALIZED) == 0)
8986 +               {
8987 +               PK11err(PK11_F_TOKEN_LOGIN,
8988 +                   PK11_R_TOKEN_NOT_INITIALIZED);
8989 +               return (0);
8990 +               }
8991 +#endif
8993 +       /*
8994 +        * If login is required or needed but the PIN has not been
8995 +        * even initialized we can bail out right now. Note that we
8996 +        * are supposed to always log in if we are going to access
8997 +        * private keys. However, we may need to log in even for
8998 +        * accessing public keys in case that the CKF_LOGIN_REQUIRED
8999 +        * flag is set.
9000 +        */
9001 +       if (((pubkey_token_flags & CKF_LOGIN_REQUIRED) ||
9002 +            (is_private == CK_TRUE)) &&
9003 +           (~pubkey_token_flags & CKF_USER_PIN_INITIALIZED))
9004 +               {
9005 +               PK11err(PK11_F_TOKEN_LOGIN, PK11_R_TOKEN_PIN_NOT_SET);
9006 +               return (0);
9007 +               }
9009 +       /*
9010 +        * Note on locking: it is possible that more than one thread
9011 +        * gets into pk11_get_pin() so we must deal with that. We
9012 +        * cannot avoid it since we cannot guard fork() in there with
9013 +        * a lock because we could end up in a dead lock in the
9014 +        * child. Why? Remember we are in a multithreaded environment
9015 +        * so we must lock all mutexes in the prefork function to
9016 +        * avoid a situation in which a thread that did not call
9017 +        * fork() held a lock, making future unlocking impossible. We
9018 +        * lock right before C_Login().
9019 +        */
9020 +       if ((pubkey_token_flags & CKF_LOGIN_REQUIRED) ||
9021 +           (is_private == CK_TRUE))
9022 +               {
9023 +               if (*login_done == CK_FALSE)
9024 +                       {
9025 +                       if ((pk11_pin == NULL) && (pk11_get_pin() == 0))
9026 +                               {
9027 +                               PK11err(PK11_F_TOKEN_LOGIN,
9028 +                                   PK11_R_TOKEN_PIN_NOT_PROVIDED);
9029 +                               return (0);
9030 +                               }
9031 +                       }
9033 +               /*
9034 +                * Note that what we are logging into is the keystore from
9035 +                * pubkey_SLOTID because we work with OP_RSA session type here.
9036 +                * That also means that we can work with only one keystore in
9037 +                * the engine.
9038 +                *
9039 +                * We must make sure we do not try to login more than once.
9040 +                * Also, see the comment above on locking strategy.
9041 +                */
9043 +#ifndef NOPTHREADS
9044 +               OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
9045 +#else
9046 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
9047 +#endif
9048 +               if (*login_done == CK_FALSE)
9049 +                       {
9050 +                       if ((rv = pFuncList->C_Login(session,
9051 +                           CKU_USER, (CK_UTF8CHAR*)pk11_pin,
9052 +                           strlen(pk11_pin))) != CKR_OK)
9053 +                               {
9054 +                               PK11err_add_data(PK11_F_TOKEN_LOGIN,
9055 +                                   PK11_R_TOKEN_LOGIN_FAILED, rv);
9056 +                               goto err_locked;
9057 +                               }
9059 +                       *login_done = CK_TRUE;
9061 +                       }
9062 +#ifndef NOPTHREADS
9063 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
9064 +#else
9065 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
9066 +#endif
9067 +               }
9068 +       else
9069 +               {
9070 +                       /*
9071 +                        * If token does not require login we take it as the
9072 +                        * login was done.
9073 +                        */
9074 +                       *login_done = CK_TRUE;
9075 +               }
9077 +       return (1);
9079 +err_locked:
9080 +       if (pk11_pin) {
9081 +               memset(pk11_pin, 0, strlen(pk11_pin));
9082 +               OPENSSL_free((void*)pk11_pin);
9083 +       }
9084 +       pk11_pin = NULL;
9085 +#ifndef NOPTHREADS
9086 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
9087 +#else
9088 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
9089 +#endif
9090 +       return (0);
9091 +       }
9094 + * Log in to the keystore in the child if we were logged in in the
9095 + * parent. There are similarities in the code with pk11_token_login()
9096 + * but still it is quite different so we need a separate function for
9097 + * this.
9098 + *
9099 + * Note that this function is called under the locked session mutex when fork is
9100 + * detected. That means that C_Login() will be called from the child just once.
9101 + *
9102 + * Returns:
9103 + *     1 on success
9104 + *     0 on failure
9105 + */
9106 +int
9107 +pk11_token_relogin(CK_SESSION_HANDLE session)
9108 +       {
9109 +       CK_RV rv;
9111 +       if ((pk11_pin == NULL) && (pk11_get_pin() == 0))
9112 +               return (0);
9114 +#ifndef NOPTHREADS
9115 +       OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
9116 +#else
9117 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
9118 +#endif
9119 +       if ((rv = pFuncList->C_Login(session, CKU_USER,
9120 +           (CK_UTF8CHAR_PTR)pk11_pin, strlen(pk11_pin))) != CKR_OK)
9121 +               {
9122 +               PK11err_add_data(PK11_F_TOKEN_RELOGIN,
9123 +                   PK11_R_TOKEN_LOGIN_FAILED, rv);
9124 +#ifndef NOPTHREADS
9125 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
9126 +#else
9127 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
9128 +#endif
9129 +               return (0);
9130 +               }
9131 +#ifndef NOPTHREADS
9132 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
9133 +#else
9134 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
9135 +#endif
9137 +       return (1);
9138 +       }
9140 +#ifdef OPENSSL_SYS_WIN32
9141 +char *getpassphrase(const char *prompt)
9142 +       {
9143 +       static char buf[128];
9144 +       HANDLE h;
9145 +       DWORD cc, mode;
9146 +       int cnt;
9148 +       h = GetStdHandle(STD_INPUT_HANDLE);
9149 +       fputs(prompt, stderr);
9150 +       fflush(stderr);
9151 +       fflush(stdout);
9152 +       FlushConsoleInputBuffer(h);
9153 +       GetConsoleMode(h, &mode);
9154 +       SetConsoleMode(h, ENABLE_PROCESSED_INPUT);
9156 +       for (cnt = 0; cnt < sizeof(buf) - 1; cnt++)
9157 +               {
9158 +               ReadFile(h, buf + cnt, 1, &cc, NULL);
9159 +               if (buf[cnt] == '\r')
9160 +                       break;
9161 +               fputc('*', stdout);
9162 +               fflush(stderr);
9163 +               fflush(stdout);
9164 +               }
9166 +       SetConsoleMode(h, mode);
9167 +       buf[cnt] = '\0';
9168 +       fputs("\n", stderr);
9169 +       return buf;
9170 +       }
9171 +#endif /* OPENSSL_SYS_WIN32 */
9172 +#endif /* OPENSSL_NO_HW_PK11CA */
9173 +#endif /* OPENSSL_NO_HW_PK11 */
9174 +#endif /* OPENSSL_NO_HW */
9175 Index: openssl/crypto/engine/hw_pk11ca.h
9176 diff -u /dev/null openssl/crypto/engine/hw_pk11ca.h:1.4
9177 --- /dev/null   Fri Jan  2 14:26:17 2015
9178 +++ openssl/crypto/engine/hw_pk11ca.h   Wed Jun 15 21:12:20 2011
9179 @@ -0,0 +1,32 @@
9180 +/* Redefine all pk11/PK11 external symbols to pk11ca/PK11CA */
9182 +#define token_lock                     pk11ca_token_lock
9183 +#define find_lock                      pk11ca_find_lock
9184 +#define active_list                    pk11ca_active_list
9185 +#define pubkey_token_flags             pk11ca_pubkey_token_flags
9186 +#define pubkey_SLOTID                  pk11ca_pubkey_SLOTID
9187 +#define ERR_pk11_error                 ERR_pk11ca_error
9188 +#define PK11err_add_data               PK11CAerr_add_data
9189 +#define pk11_get_session               pk11ca_get_session
9190 +#define pk11_return_session            pk11ca_return_session
9191 +#define pk11_active_add                        pk11ca_active_add
9192 +#define pk11_active_delete             pk11ca_active_delete
9193 +#define pk11_active_remove             pk11ca_active_remove
9194 +#define pk11_free_active_list          pk11ca_free_active_list
9195 +#define pk11_destroy_rsa_key_objects   pk11ca_destroy_rsa_key_objects
9196 +#define pk11_destroy_rsa_object_pub    pk11ca_destroy_rsa_object_pub
9197 +#define pk11_destroy_rsa_object_priv   pk11ca_destroy_rsa_object_priv
9198 +#define pk11_load_privkey              pk11ca_load_privkey
9199 +#define pk11_load_pubkey               pk11ca_load_pubkey
9200 +#define PK11_RSA                       PK11CA_RSA
9201 +#define pk11_destroy_dsa_key_objects   pk11ca_destroy_dsa_key_objects
9202 +#define pk11_destroy_dsa_object_pub    pk11ca_destroy_dsa_object_pub
9203 +#define pk11_destroy_dsa_object_priv   pk11ca_destroy_dsa_object_priv
9204 +#define PK11_DSA                       PK11CA_DSA
9205 +#define pk11_destroy_dh_key_objects    pk11ca_destroy_dh_key_objects
9206 +#define pk11_destroy_dh_object         pk11ca_destroy_dh_object
9207 +#define PK11_DH                                PK11CA_DH
9208 +#define pk11_token_relogin             pk11ca_token_relogin
9209 +#define pFuncList                      pk11ca_pFuncList
9210 +#define pk11_pin                       pk11ca_pin
9211 +#define ENGINE_load_pk11               ENGINE_load_pk11ca
9212 Index: openssl/crypto/engine/hw_pk11so.c
9213 diff -u /dev/null openssl/crypto/engine/hw_pk11so.c:1.7.4.1
9214 --- /dev/null   Fri Jan  2 14:26:17 2015
9215 +++ openssl/crypto/engine/hw_pk11so.c   Fri Oct  4 14:33:56 2013
9216 @@ -0,0 +1,1775 @@
9218 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
9219 + * Use is subject to license terms.
9220 + */
9222 +/* crypto/engine/hw_pk11.c */
9224 + * This product includes software developed by the OpenSSL Project for
9225 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
9226 + *
9227 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
9228 + * Afchine Madjlessi.
9229 + */
9231 + * ====================================================================
9232 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
9233 + *
9234 + * Redistribution and use in source and binary forms, with or without
9235 + * modification, are permitted provided that the following conditions
9236 + * are met:
9237 + *
9238 + * 1. Redistributions of source code must retain the above copyright
9239 + *    notice, this list of conditions and the following disclaimer.
9240 + *
9241 + * 2. Redistributions in binary form must reproduce the above copyright
9242 + *    notice, this list of conditions and the following disclaimer in
9243 + *    the documentation and/or other materials provided with the
9244 + *    distribution.
9245 + *
9246 + * 3. All advertising materials mentioning features or use of this
9247 + *    software must display the following acknowledgment:
9248 + *    "This product includes software developed by the OpenSSL Project
9249 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
9250 + *
9251 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
9252 + *    endorse or promote products derived from this software without
9253 + *    prior written permission. For written permission, please contact
9254 + *    licensing@OpenSSL.org.
9255 + *
9256 + * 5. Products derived from this software may not be called "OpenSSL"
9257 + *    nor may "OpenSSL" appear in their names without prior written
9258 + *    permission of the OpenSSL Project.
9259 + *
9260 + * 6. Redistributions of any form whatsoever must retain the following
9261 + *    acknowledgment:
9262 + *    "This product includes software developed by the OpenSSL Project
9263 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
9264 + *
9265 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
9266 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9267 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
9268 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
9269 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9270 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
9271 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
9272 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
9273 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
9274 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
9275 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
9276 + * OF THE POSSIBILITY OF SUCH DAMAGE.
9277 + * ====================================================================
9278 + *
9279 + * This product includes cryptographic software written by Eric Young
9280 + * (eay@cryptsoft.com).  This product includes software written by Tim
9281 + * Hudson (tjh@cryptsoft.com).
9282 + *
9283 + */
9285 +/* Modified to keep only RNG and RSA Sign */
9287 +#ifdef OPENSSL_NO_RSA
9288 +#error RSA is disabled
9289 +#endif
9291 +#include <stdio.h>
9292 +#include <stdlib.h>
9293 +#include <string.h>
9294 +#include <sys/types.h>
9296 +#include <openssl/e_os2.h>
9297 +#include <openssl/crypto.h>
9298 +#include <cryptlib.h>
9299 +#include <openssl/engine.h>
9300 +#include <openssl/dso.h>
9301 +#include <openssl/err.h>
9302 +#include <openssl/bn.h>
9303 +#include <openssl/md5.h>
9304 +#include <openssl/pem.h>
9305 +#include <openssl/rsa.h>
9306 +#include <openssl/rand.h>
9307 +#include <openssl/objects.h>
9308 +#include <openssl/x509.h>
9310 +#ifdef OPENSSL_SYS_WIN32
9311 +typedef int pid_t;
9312 +#define getpid() GetCurrentProcessId()
9313 +#define NOPTHREADS
9314 +#ifndef NULL_PTR
9315 +#define NULL_PTR NULL
9316 +#endif
9317 +#define CK_DEFINE_FUNCTION(returnType, name) \
9318 +       returnType __declspec(dllexport) name
9319 +#define CK_DECLARE_FUNCTION(returnType, name) \
9320 +       returnType __declspec(dllimport) name
9321 +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
9322 +       returnType __declspec(dllimport) (* name)
9323 +#else
9324 +#include <signal.h>
9325 +#include <unistd.h>
9326 +#include <dlfcn.h>
9327 +#endif
9329 +/* Debug mutexes */
9330 +/*#undef DEBUG_MUTEX */
9331 +#define DEBUG_MUTEX
9333 +#ifndef NOPTHREADS
9334 +/* for pthread error check on Linuxes */
9335 +#ifdef DEBUG_MUTEX
9336 +#define __USE_UNIX98
9337 +#endif
9338 +#include <pthread.h>
9339 +#endif
9341 +#ifndef OPENSSL_NO_HW
9342 +#ifndef OPENSSL_NO_HW_PK11
9343 +#ifndef OPENSSL_NO_HW_PK11SO
9345 +/* label for debug messages printed on stderr */
9346 +#define        PK11_DBG        "PKCS#11 ENGINE DEBUG"
9347 +/* prints a lot of debug messages on stderr about slot selection process */
9348 +/*#undef       DEBUG_SLOT_SELECTION */
9350 +#ifndef OPENSSL_NO_DSA
9351 +#define OPENSSL_NO_DSA
9352 +#endif
9353 +#ifndef OPENSSL_NO_DH
9354 +#define OPENSSL_NO_DH
9355 +#endif
9357 +#ifdef OPENSSL_SYS_WIN32
9358 +#pragma pack(push, cryptoki, 1)
9359 +#include "cryptoki.h"
9360 +#include "pkcs11.h"
9361 +#pragma pack(pop, cryptoki)
9362 +#else
9363 +#include "cryptoki.h"
9364 +#include "pkcs11.h"
9365 +#endif
9366 +#include "hw_pk11so.h"
9367 +#include "hw_pk11_err.c"
9370 + * We use this lock to prevent multiple C_Login()s, guard getpassphrase(),
9371 + * uri_struct manipulation, and static token info. All of that is used by the
9372 + * RSA keys by reference feature.
9373 + */
9374 +#ifndef NOPTHREADS
9375 +pthread_mutex_t *token_lock;
9376 +#endif
9378 +/* PKCS#11 session caches and their locks for all operation types */
9379 +static PK11_CACHE session_cache[OP_MAX];
9382 + * We cache the flags so that we do not have to run C_GetTokenInfo() again when
9383 + * logging into the token.
9384 + */
9385 +CK_FLAGS pubkey_token_flags;
9388 + * As stated in v2.20, 11.7 Object Management Function, in section for
9389 + * C_FindObjectsInit(), at most one search operation may be active at a given
9390 + * time in a given session. Therefore, C_Find{,Init,Final}Objects() should be
9391 + * grouped together to form one atomic search operation. This is already
9392 + * ensured by the property of unique PKCS#11 session handle used for each
9393 + * PK11_SESSION object.
9394 + *
9395 + * This is however not the biggest concern - maintaining consistency of the
9396 + * underlying object store is more important. The same section of the spec also
9397 + * says that one thread can be in the middle of a search operation while another
9398 + * thread destroys the object matching the search template which would result in
9399 + * invalid handle returned from the search operation.
9400 + *
9401 + * Hence, the following locks are used for both protection of the object stores.
9402 + * They are also used for active list protection.
9403 + */
9404 +#ifndef NOPTHREADS
9405 +pthread_mutex_t *find_lock[OP_MAX] = { NULL };
9406 +#endif
9409 + * lists of asymmetric key handles which are active (referenced by at least one
9410 + * PK11_SESSION structure, either held by a thread or present in free_session
9411 + * list) for given algorithm type
9412 + */
9413 +PK11_active *active_list[OP_MAX] = { NULL };
9416 + * Create all secret key objects in a global session so that they are available
9417 + * to use for other sessions. These other sessions may be opened or closed
9418 + * without losing the secret key objects.
9419 + */
9420 +static CK_SESSION_HANDLE       global_session = CK_INVALID_HANDLE;
9422 +/* ENGINE level stuff */
9423 +static int pk11_init(ENGINE *e);
9424 +static int pk11_library_init(ENGINE *e);
9425 +static int pk11_finish(ENGINE *e);
9426 +static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
9427 +static int pk11_destroy(ENGINE *e);
9429 +/* RAND stuff */
9430 +static void pk11_rand_seed(const void *buf, int num);
9431 +static void pk11_rand_add(const void *buf, int num, double add_entropy);
9432 +static void pk11_rand_cleanup(void);
9433 +static int pk11_rand_bytes(unsigned char *buf, int num);
9434 +static int pk11_rand_status(void);
9436 +/* These functions are also used in other files */
9437 +PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
9438 +void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
9440 +/* active list manipulation functions used in this file */
9441 +extern int pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type);
9442 +extern void pk11_free_active_list(PK11_OPTYPE type);
9444 +int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
9445 +int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
9446 +int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
9448 +/* Local helper functions */
9449 +static int pk11_free_all_sessions(void);
9450 +static int pk11_free_session_list(PK11_OPTYPE optype);
9451 +static int pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype);
9452 +static int pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
9453 +       CK_BBOOL persistent);
9454 +static const char *get_PK11_LIBNAME(void);
9455 +static void free_PK11_LIBNAME(void);
9456 +static long set_PK11_LIBNAME(const char *name);
9458 +static int pk11_choose_slots(int *any_slot_found);
9460 +static int pk11_init_all_locks(void);
9461 +static void pk11_free_all_locks(void);
9463 +#define        TRY_OBJ_DESTROY(sp, obj_hdl, retval, uselock, alg_type, priv)   \
9464 +       {                                                               \
9465 +       if (uselock)                                                    \
9466 +               LOCK_OBJSTORE(alg_type);                                \
9467 +       if (pk11_active_delete(obj_hdl, alg_type) == 1)                 \
9468 +               {                                                       \
9469 +                 retval = pk11_destroy_object(sp->session, obj_hdl,    \
9470 +                 priv ? sp->priv_persistent : sp->pub_persistent);     \
9471 +               }                                                       \
9472 +       if (uselock)                                                    \
9473 +               UNLOCK_OBJSTORE(alg_type);                              \
9474 +       }
9476 +static CK_BBOOL pk11_have_rsa  = CK_FALSE;
9477 +static CK_BBOOL pk11_have_random = CK_FALSE;
9480 + * Initialization function. Sets up various PKCS#11 library components.
9481 + * The definitions for control commands specific to this engine
9482 + */
9483 +#define PK11_CMD_SO_PATH               ENGINE_CMD_BASE
9484 +#define PK11_CMD_PIN                   (ENGINE_CMD_BASE+1)
9485 +#define PK11_CMD_SLOT                  (ENGINE_CMD_BASE+2)
9486 +static const ENGINE_CMD_DEFN pk11_cmd_defns[] =
9487 +       {
9488 +               {
9489 +               PK11_CMD_SO_PATH,
9490 +               "SO_PATH",
9491 +               "Specifies the path to the 'pkcs#11' shared library",
9492 +               ENGINE_CMD_FLAG_STRING
9493 +               },
9494 +               {
9495 +               PK11_CMD_PIN,
9496 +               "PIN",
9497 +               "Specifies the pin code",
9498 +               ENGINE_CMD_FLAG_STRING
9499 +               },
9500 +               {
9501 +               PK11_CMD_SLOT,
9502 +               "SLOT",
9503 +               "Specifies the slot (default is auto select)",
9504 +               ENGINE_CMD_FLAG_NUMERIC,
9505 +               },
9506 +               {0, NULL, NULL, 0}
9507 +       };
9510 +static RAND_METHOD pk11_random =
9511 +       {
9512 +       pk11_rand_seed,
9513 +       pk11_rand_bytes,
9514 +       pk11_rand_cleanup,
9515 +       pk11_rand_add,
9516 +       pk11_rand_bytes,
9517 +       pk11_rand_status
9518 +       };
9521 +/* Constants used when creating the ENGINE */
9522 +#ifdef OPENSSL_NO_HW_PK11CA
9523 +#error "can't load both crypto-accelerator and sign-only PKCS#11 engines"
9524 +#endif
9525 +static const char *engine_pk11_id = "pkcs11";
9526 +static const char *engine_pk11_name = "PKCS #11 engine support (sign only)";
9528 +CK_FUNCTION_LIST_PTR pFuncList = NULL;
9529 +static const char PK11_GET_FUNCTION_LIST[] = "C_GetFunctionList";
9532 + * This is a static string constant for the DSO file name and the function
9533 + * symbol names to bind to. We set it in the Configure script based on whether
9534 + * this is 32 or 64 bit build.
9535 + */
9536 +static const char def_PK11_LIBNAME[] = PK11_LIB_LOCATION;
9538 +/* Needed in hw_pk11_pub.c as well so that's why it is not static. */
9539 +CK_SLOT_ID pubkey_SLOTID = 0;
9540 +static CK_SLOT_ID rand_SLOTID = 0;
9541 +static CK_SLOT_ID SLOTID = 0;
9542 +char *pk11_pin = NULL;
9543 +static CK_BBOOL pk11_library_initialized = FALSE;
9544 +static CK_BBOOL pk11_atfork_initialized = FALSE;
9545 +static int pk11_pid = 0;
9547 +static DSO *pk11_dso = NULL;
9549 +/* allocate and initialize all locks used by the engine itself */
9550 +static int pk11_init_all_locks(void)
9551 +       {
9552 +#ifndef NOPTHREADS
9553 +       int type;
9554 +       pthread_mutexattr_t attr;
9556 +       if (pthread_mutexattr_init(&attr) != 0)
9557 +       {
9558 +               PK11err(PK11_F_INIT_ALL_LOCKS, 100);
9559 +               return (0);
9560 +       }
9562 +#ifdef DEBUG_MUTEX
9563 +       if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0)
9564 +       {
9565 +               PK11err(PK11_F_INIT_ALL_LOCKS, 101);
9566 +               return (0);
9567 +       }
9568 +#endif
9570 +       if ((token_lock = OPENSSL_malloc(sizeof (pthread_mutex_t))) == NULL)
9571 +               goto malloc_err;
9572 +       (void) pthread_mutex_init(token_lock, &attr);
9574 +       find_lock[OP_RSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
9575 +       if (find_lock[OP_RSA] == NULL)
9576 +               goto malloc_err;
9577 +       (void) pthread_mutex_init(find_lock[OP_RSA], &attr);
9579 +       for (type = 0; type < OP_MAX; type++)
9580 +               {
9581 +               session_cache[type].lock =
9582 +                   OPENSSL_malloc(sizeof (pthread_mutex_t));
9583 +               if (session_cache[type].lock == NULL)
9584 +                       goto malloc_err;
9585 +               (void) pthread_mutex_init(session_cache[type].lock, &attr);
9586 +               }
9588 +       return (1);
9590 +malloc_err:
9591 +       pk11_free_all_locks();
9592 +       PK11err(PK11_F_INIT_ALL_LOCKS, PK11_R_MALLOC_FAILURE);
9593 +       return (0);
9594 +#else
9595 +       return (1);
9596 +#endif
9597 +       }
9599 +static void pk11_free_all_locks(void)
9600 +       {
9601 +#ifndef NOPTHREADS
9602 +       int type;
9604 +       if (token_lock != NULL)
9605 +               {
9606 +               (void) pthread_mutex_destroy(token_lock);
9607 +               OPENSSL_free(token_lock);
9608 +               token_lock = NULL;
9609 +               }
9611 +       if (find_lock[OP_RSA] != NULL)
9612 +               {
9613 +               (void) pthread_mutex_destroy(find_lock[OP_RSA]);
9614 +               OPENSSL_free(find_lock[OP_RSA]);
9615 +               find_lock[OP_RSA] = NULL;
9616 +               }
9618 +       for (type = 0; type < OP_MAX; type++)
9619 +               {
9620 +               if (session_cache[type].lock != NULL)
9621 +                       {
9622 +                       (void) pthread_mutex_destroy(session_cache[type].lock);
9623 +                       OPENSSL_free(session_cache[type].lock);
9624 +                       session_cache[type].lock = NULL;
9625 +                       }
9626 +               }
9627 +#endif
9628 +       }
9631 + * This internal function is used by ENGINE_pk11() and "dynamic" ENGINE support.
9632 + */
9633 +static int bind_pk11(ENGINE *e)
9634 +       {
9635 +       if (!pk11_library_initialized)
9636 +               if (!pk11_library_init(e))
9637 +                       return (0);
9639 +       if (!ENGINE_set_id(e, engine_pk11_id) ||
9640 +           !ENGINE_set_name(e, engine_pk11_name))
9641 +               return (0);
9643 +       if (pk11_have_rsa == CK_TRUE)
9644 +               {
9645 +               if (!ENGINE_set_RSA(e, PK11_RSA()) ||
9646 +                   !ENGINE_set_load_privkey_function(e, pk11_load_privkey) ||
9647 +                   !ENGINE_set_load_pubkey_function(e, pk11_load_pubkey))
9648 +                       return (0);
9649 +#ifdef DEBUG_SLOT_SELECTION
9650 +               fprintf(stderr, "%s: registered RSA\n", PK11_DBG);
9651 +#endif /* DEBUG_SLOT_SELECTION */
9652 +               }
9654 +       if (pk11_have_random)
9655 +               {
9656 +               if (!ENGINE_set_RAND(e, &pk11_random))
9657 +                       return (0);
9658 +#ifdef DEBUG_SLOT_SELECTION
9659 +               fprintf(stderr, "%s: registered random\n", PK11_DBG);
9660 +#endif /* DEBUG_SLOT_SELECTION */
9661 +               }
9662 +       if (!ENGINE_set_init_function(e, pk11_init) ||
9663 +           !ENGINE_set_destroy_function(e, pk11_destroy) ||
9664 +           !ENGINE_set_finish_function(e, pk11_finish) ||
9665 +           !ENGINE_set_ctrl_function(e, pk11_ctrl) ||
9666 +           !ENGINE_set_cmd_defns(e, pk11_cmd_defns))
9667 +               return (0);
9669 +       /* Ensure the pk11 error handling is set up */
9670 +       ERR_load_pk11_strings();
9672 +       return (1);
9673 +       }
9675 +/* Dynamic engine support is disabled at a higher level for Solaris */
9676 +#ifdef ENGINE_DYNAMIC_SUPPORT
9677 +#error "dynamic engine not supported"
9678 +static int bind_helper(ENGINE *e, const char *id)
9679 +       {
9680 +       if (id && (strcmp(id, engine_pk11_id) != 0))
9681 +               return (0);
9683 +       if (!bind_pk11(e))
9684 +               return (0);
9686 +       return (1);
9687 +       }
9689 +IMPLEMENT_DYNAMIC_CHECK_FN()
9690 +IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
9692 +#else
9693 +static ENGINE *engine_pk11(void)
9694 +       {
9695 +       ENGINE *ret = ENGINE_new();
9697 +       if (!ret)
9698 +               return (NULL);
9700 +       if (!bind_pk11(ret))
9701 +               {
9702 +               ENGINE_free(ret);
9703 +               return (NULL);
9704 +               }
9706 +       return (ret);
9707 +       }
9709 +void
9710 +ENGINE_load_pk11(void)
9711 +       {
9712 +       ENGINE *e_pk11 = NULL;
9714 +       /*
9715 +        * Do not use dynamic PKCS#11 library on Solaris due to
9716 +        * security reasons. We will link it in statically.
9717 +        */
9718 +       /* Attempt to load PKCS#11 library */
9719 +       if (!pk11_dso)
9720 +               pk11_dso = DSO_load(NULL, get_PK11_LIBNAME(), NULL, 0);
9722 +       if (pk11_dso == NULL)
9723 +               {
9724 +               PK11err(PK11_F_LOAD, PK11_R_DSO_FAILURE);
9725 +               return;
9726 +               }
9728 +       e_pk11 = engine_pk11();
9729 +       if (!e_pk11)
9730 +               {
9731 +               DSO_free(pk11_dso);
9732 +               pk11_dso = NULL;
9733 +               return;
9734 +               }
9736 +       /*
9737 +        * At this point, the pk11 shared library is either dynamically
9738 +        * loaded or statically linked in. So, initialize the pk11
9739 +        * library before calling ENGINE_set_default since the latter
9740 +        * needs cipher and digest algorithm information
9741 +        */
9742 +       if (!pk11_library_init(e_pk11))
9743 +               {
9744 +               DSO_free(pk11_dso);
9745 +               pk11_dso = NULL;
9746 +               ENGINE_free(e_pk11);
9747 +               return;
9748 +               }
9750 +       ENGINE_add(e_pk11);
9752 +       ENGINE_free(e_pk11);
9753 +       ERR_clear_error();
9754 +       }
9755 +#endif /* ENGINE_DYNAMIC_SUPPORT */
9758 + * These are the static string constants for the DSO file name and
9759 + * the function symbol names to bind to.
9760 + */
9761 +static const char *PK11_LIBNAME = NULL;
9763 +static const char *get_PK11_LIBNAME(void)
9764 +       {
9765 +       if (PK11_LIBNAME)
9766 +               return (PK11_LIBNAME);
9768 +       return (def_PK11_LIBNAME);
9769 +       }
9771 +static void free_PK11_LIBNAME(void)
9772 +       {
9773 +       if (PK11_LIBNAME)
9774 +               OPENSSL_free((void*)PK11_LIBNAME);
9776 +       PK11_LIBNAME = NULL;
9777 +       }
9779 +static long set_PK11_LIBNAME(const char *name)
9780 +       {
9781 +       free_PK11_LIBNAME();
9783 +       return ((PK11_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
9784 +       }
9786 +/* acquire all engine specific mutexes before fork */
9787 +static void pk11_fork_prepare(void)
9788 +       {
9789 +#ifndef NOPTHREADS
9790 +       int i;
9792 +       if (!pk11_library_initialized)
9793 +               return;
9795 +       LOCK_OBJSTORE(OP_RSA);
9796 +       OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
9797 +       for (i = 0; i < OP_MAX; i++)
9798 +               {
9799 +               OPENSSL_assert(pthread_mutex_lock(session_cache[i].lock) == 0);
9800 +               }
9801 +#endif
9802 +       }
9804 +/* release all engine specific mutexes */
9805 +static void pk11_fork_parent(void)
9806 +       {
9807 +#ifndef NOPTHREADS
9808 +       int i;
9810 +       if (!pk11_library_initialized)
9811 +               return;
9813 +       for (i = OP_MAX - 1; i >= 0; i--)
9814 +               {
9815 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[i].lock) == 0);
9816 +               }
9817 +       UNLOCK_OBJSTORE(OP_RSA);
9818 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
9819 +#endif
9820 +       }
9823 + * same situation as in parent - we need to unlock all locks to make them
9824 + * accessible to all threads.
9825 + */
9826 +static void pk11_fork_child(void)
9827 +       {
9828 +#ifndef NOPTHREADS
9829 +       int i;
9831 +       if (!pk11_library_initialized)
9832 +               return;
9834 +       for (i = OP_MAX - 1; i >= 0; i--)
9835 +               {
9836 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[i].lock) == 0);
9837 +               }
9838 +       UNLOCK_OBJSTORE(OP_RSA);
9839 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
9840 +#endif
9841 +       }
9843 +/* Initialization function for the pk11 engine */
9844 +static int pk11_init(ENGINE *e)
9846 +       return (pk11_library_init(e));
9849 +static CK_C_INITIALIZE_ARGS pk11_init_args =
9850 +       {
9851 +       NULL_PTR,               /* CreateMutex */
9852 +       NULL_PTR,               /* DestroyMutex */
9853 +       NULL_PTR,               /* LockMutex */
9854 +       NULL_PTR,               /* UnlockMutex */
9855 +       CKF_OS_LOCKING_OK,      /* flags */
9856 +       NULL_PTR,               /* pReserved */
9857 +       };
9860 + * Initialization function. Sets up various PKCS#11 library components.
9861 + * It selects a slot based on predefined critiera. In the process, it also
9862 + * count how many ciphers and digests to support. Since the cipher and
9863 + * digest information is needed when setting default engine, this function
9864 + * needs to be called before calling ENGINE_set_default.
9865 + */
9866 +/* ARGSUSED */
9867 +static int pk11_library_init(ENGINE *e)
9868 +       {
9869 +       CK_C_GetFunctionList p;
9870 +       CK_RV rv = CKR_OK;
9871 +       CK_INFO info;
9872 +       int any_slot_found;
9873 +       int i;
9874 +#ifndef OPENSSL_SYS_WIN32
9875 +       struct sigaction sigint_act, sigterm_act, sighup_act;
9876 +#endif
9878 +       /*
9879 +        * pk11_library_initialized is set to 0 in pk11_finish() which
9880 +        * is called from ENGINE_finish(). However, if there is still
9881 +        * at least one existing functional reference to the engine
9882 +        * (see engine(3) for more information), pk11_finish() is
9883 +        * skipped. For example, this can happen if an application
9884 +        * forgets to clear one cipher context. In case of a fork()
9885 +        * when the application is finishing the engine so that it can
9886 +        * be reinitialized in the child, forgotten functional
9887 +        * reference causes pk11_library_initialized to stay 1. In
9888 +        * that case we need the PID check so that we properly
9889 +        * initialize the engine again.
9890 +        */
9891 +       if (pk11_library_initialized)
9892 +               {
9893 +               if (pk11_pid == getpid())
9894 +                       {
9895 +                       return (1);
9896 +                       }
9897 +               else
9898 +                       {
9899 +                       global_session = CK_INVALID_HANDLE;
9900 +                       /*
9901 +                        * free the locks first to prevent memory leak in case
9902 +                        * the application calls fork() without finishing the
9903 +                        * engine first.
9904 +                        */
9905 +                       pk11_free_all_locks();
9906 +                       }
9907 +               }
9909 +       if (pk11_dso == NULL)
9910 +               {
9911 +               PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
9912 +               goto err;
9913 +               }
9915 +       /* get the C_GetFunctionList function from the loaded library */
9916 +       p = (CK_C_GetFunctionList)DSO_bind_func(pk11_dso,
9917 +               PK11_GET_FUNCTION_LIST);
9918 +       if (!p)
9919 +               {
9920 +               PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
9921 +               goto err;
9922 +               }
9924 +       /* get the full function list from the loaded library */
9925 +       rv = p(&pFuncList);
9926 +       if (rv != CKR_OK)
9927 +               {
9928 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE, rv);
9929 +               goto err;
9930 +               }
9932 +#ifndef OPENSSL_SYS_WIN32
9933 +       /* Not all PKCS#11 library are signal safe! */
9935 +       (void) memset(&sigint_act, 0, sizeof(sigint_act));
9936 +       (void) memset(&sigterm_act, 0, sizeof(sigterm_act));
9937 +       (void) memset(&sighup_act, 0, sizeof(sighup_act));
9938 +       (void) sigaction(SIGINT, NULL, &sigint_act);
9939 +       (void) sigaction(SIGTERM, NULL, &sigterm_act);
9940 +       (void) sigaction(SIGHUP, NULL, &sighup_act);
9941 +#endif
9942 +       rv = pFuncList->C_Initialize((CK_VOID_PTR)&pk11_init_args);
9943 +#ifndef OPENSSL_SYS_WIN32
9944 +       (void) sigaction(SIGINT, &sigint_act, NULL);
9945 +       (void) sigaction(SIGTERM, &sigterm_act, NULL);
9946 +       (void) sigaction(SIGHUP, &sighup_act, NULL);
9947 +#endif
9948 +       if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
9949 +               {
9950 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_INITIALIZE, rv);
9951 +               goto err;
9952 +               }
9954 +       rv = pFuncList->C_GetInfo(&info);
9955 +       if (rv != CKR_OK)
9956 +               {
9957 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_GETINFO, rv);
9958 +               goto err;
9959 +               }
9961 +       if (pk11_choose_slots(&any_slot_found) == 0)
9962 +               goto err;
9964 +       /*
9965 +        * The library we use, set in def_PK11_LIBNAME, may not offer any
9966 +        * slot(s). In that case, we must not proceed but we must not return an
9967 +        * error. The reason is that applications that try to set up the PKCS#11
9968 +        * engine don't exit on error during the engine initialization just
9969 +        * because no slot was present.
9970 +        */
9971 +       if (any_slot_found == 0)
9972 +               return (1);
9974 +       if (global_session == CK_INVALID_HANDLE)
9975 +               {
9976 +               /* Open the global_session for the new process */
9977 +               rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
9978 +                       NULL_PTR, NULL_PTR, &global_session);
9979 +               if (rv != CKR_OK)
9980 +                       {
9981 +                       PK11err_add_data(PK11_F_LIBRARY_INIT,
9982 +                           PK11_R_OPENSESSION, rv);
9983 +                       goto err;
9984 +                       }
9985 +               }
9987 +       pk11_library_initialized = TRUE;
9988 +       pk11_pid = getpid();
9989 +       /*
9990 +        * if initialization of the locks fails pk11_init_all_locks()
9991 +        * will do the cleanup.
9992 +        */
9993 +       if (!pk11_init_all_locks())
9994 +               goto err;
9995 +       for (i = 0; i < OP_MAX; i++)
9996 +               session_cache[i].head = NULL;
9997 +       /*
9998 +        * initialize active lists. We only use active lists
9999 +        * for asymmetric ciphers.
10000 +        */
10001 +       for (i = 0; i < OP_MAX; i++)
10002 +               active_list[i] = NULL;
10004 +#ifndef NOPTHREADS
10005 +       if (!pk11_atfork_initialized)
10006 +               {
10007 +               if (pthread_atfork(pk11_fork_prepare, pk11_fork_parent,
10008 +                   pk11_fork_child) != 0)
10009 +                       {
10010 +                       PK11err(PK11_F_LIBRARY_INIT, PK11_R_ATFORK_FAILED);
10011 +                       goto err;
10012 +                       }
10013 +               pk11_atfork_initialized = TRUE;
10014 +               }
10015 +#endif
10017 +       return (1);
10019 +err:
10020 +       return (0);
10021 +       }
10023 +/* Destructor (complements the "ENGINE_pk11()" constructor) */
10024 +/* ARGSUSED */
10025 +static int pk11_destroy(ENGINE *e)
10026 +       {
10027 +       free_PK11_LIBNAME();
10028 +       ERR_unload_pk11_strings();
10029 +       if (pk11_pin) {
10030 +               memset(pk11_pin, 0, strlen(pk11_pin));
10031 +               OPENSSL_free((void*)pk11_pin);
10032 +       }
10033 +       pk11_pin = NULL;
10034 +       return (1);
10035 +       }
10038 + * Termination function to clean up the session, the token, and the pk11
10039 + * library.
10040 + */
10041 +/* ARGSUSED */
10042 +static int pk11_finish(ENGINE *e)
10043 +       {
10044 +       int i;
10046 +       if (pk11_pin) {
10047 +               memset(pk11_pin, 0, strlen(pk11_pin));
10048 +               OPENSSL_free((void*)pk11_pin);
10049 +       }
10050 +       pk11_pin = NULL;
10052 +       if (pk11_dso == NULL)
10053 +               {
10054 +               PK11err(PK11_F_FINISH, PK11_R_NOT_LOADED);
10055 +               goto err;
10056 +               }
10058 +       OPENSSL_assert(pFuncList != NULL);
10060 +       if (pk11_free_all_sessions() == 0)
10061 +               goto err;
10063 +       /* free all active lists */
10064 +       for (i = 0; i < OP_MAX; i++)
10065 +               pk11_free_active_list(i);
10067 +       pFuncList->C_CloseSession(global_session);
10068 +       global_session = CK_INVALID_HANDLE;
10070 +       /*
10071 +        * Since we are part of a library (libcrypto.so), calling this function
10072 +        * may have side-effects.
10073 +        */
10074 +#if 0
10075 +       pFuncList->C_Finalize(NULL);
10076 +#endif
10078 +       if (!DSO_free(pk11_dso))
10079 +               {
10080 +               PK11err(PK11_F_FINISH, PK11_R_DSO_FAILURE);
10081 +               goto err;
10082 +               }
10083 +       pk11_dso = NULL;
10084 +       pFuncList = NULL;
10085 +       pk11_library_initialized = FALSE;
10086 +       pk11_pid = 0;
10087 +       /*
10088 +        * There is no way how to unregister atfork handlers (other than
10089 +        * unloading the library) so we just free the locks. For this reason
10090 +        * the atfork handlers check if the engine is initialized and bail out
10091 +        * immediately if not. This is necessary in case a process finishes
10092 +        * the engine before calling fork().
10093 +        */
10094 +       pk11_free_all_locks();
10096 +       return (1);
10098 +err:
10099 +       return (0);
10100 +       }
10102 +/* Standard engine interface function to set the dynamic library path */
10103 +/* ARGSUSED */
10104 +static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
10105 +       {
10106 +       int initialized = ((pk11_dso == NULL) ? 0 : 1);
10108 +       switch (cmd)
10109 +               {
10110 +       case PK11_CMD_SO_PATH:
10111 +               if (p == NULL)
10112 +                       {
10113 +                       PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
10114 +                       return (0);
10115 +                       }
10117 +               if (initialized)
10118 +                       {
10119 +                       PK11err(PK11_F_CTRL, PK11_R_ALREADY_LOADED);
10120 +                       return (0);
10121 +                       }
10123 +               return (set_PK11_LIBNAME((const char *)p));
10124 +       case PK11_CMD_PIN:
10125 +               if (pk11_pin) {
10126 +                       memset(pk11_pin, 0, strlen(pk11_pin));
10127 +                       OPENSSL_free((void*)pk11_pin);
10128 +               }
10129 +               pk11_pin = NULL;
10131 +               if (p == NULL)
10132 +                       {
10133 +                       PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
10134 +                       return (0);
10135 +                       }
10137 +               pk11_pin = BUF_strdup(p);
10138 +               if (pk11_pin == NULL)
10139 +                       {
10140 +                       PK11err(PK11_F_GET_SESSION, PK11_R_MALLOC_FAILURE);
10141 +                       return (0);
10142 +                       }
10143 +               return (1);
10144 +       case PK11_CMD_SLOT:
10145 +               SLOTID = (CK_SLOT_ID)i;
10146 +#ifdef DEBUG_SLOT_SELECTION
10147 +               fprintf(stderr, "%s: slot set\n", PK11_DBG);
10148 +#endif
10149 +               return (1);
10150 +       default:
10151 +               break;
10152 +               }
10154 +       PK11err(PK11_F_CTRL, PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED);
10156 +       return (0);
10157 +       }
10160 +/* Required function by the engine random interface. It does nothing here */
10161 +static void pk11_rand_cleanup(void)
10162 +       {
10163 +       return;
10164 +       }
10166 +/* ARGSUSED */
10167 +static void pk11_rand_add(const void *buf, int num, double add)
10168 +       {
10169 +       PK11_SESSION *sp;
10171 +       if ((sp = pk11_get_session(OP_RAND)) == NULL)
10172 +               return;
10174 +       /*
10175 +        * Ignore any errors (e.g. CKR_RANDOM_SEED_NOT_SUPPORTED) since
10176 +        * the calling functions do not care anyway
10177 +        */
10178 +       pFuncList->C_SeedRandom(sp->session, (unsigned char *) buf, num);
10179 +       pk11_return_session(sp, OP_RAND);
10181 +       return;
10182 +       }
10184 +static void pk11_rand_seed(const void *buf, int num)
10185 +       {
10186 +       pk11_rand_add(buf, num, 0);
10187 +       }
10189 +static int pk11_rand_bytes(unsigned char *buf, int num)
10190 +       {
10191 +       CK_RV rv;
10192 +       PK11_SESSION *sp;
10194 +       if ((sp = pk11_get_session(OP_RAND)) == NULL)
10195 +               return (0);
10197 +       rv = pFuncList->C_GenerateRandom(sp->session, buf, num);
10198 +       if (rv != CKR_OK)
10199 +               {
10200 +               PK11err_add_data(PK11_F_RAND_BYTES, PK11_R_GENERATERANDOM, rv);
10201 +               pk11_return_session(sp, OP_RAND);
10202 +               return (0);
10203 +               }
10205 +       pk11_return_session(sp, OP_RAND);
10206 +       return (1);
10207 +       }
10209 +/* Required function by the engine random interface. It does nothing here */
10210 +static int pk11_rand_status(void)
10211 +       {
10212 +       return (1);
10213 +       }
10215 +/* Free all BIGNUM structures from PK11_SESSION. */
10216 +static void pk11_free_nums(PK11_SESSION *sp, PK11_OPTYPE optype)
10217 +       {
10218 +       switch (optype)
10219 +               {
10220 +               case OP_RSA:
10221 +                       if (sp->opdata_rsa_n_num != NULL)
10222 +                               {
10223 +                               BN_free(sp->opdata_rsa_n_num);
10224 +                               sp->opdata_rsa_n_num = NULL;
10225 +                               }
10226 +                       if (sp->opdata_rsa_e_num != NULL)
10227 +                               {
10228 +                               BN_free(sp->opdata_rsa_e_num);
10229 +                               sp->opdata_rsa_e_num = NULL;
10230 +                               }
10231 +                       if (sp->opdata_rsa_pn_num != NULL)
10232 +                               {
10233 +                               BN_free(sp->opdata_rsa_pn_num);
10234 +                               sp->opdata_rsa_pn_num = NULL;
10235 +                               }
10236 +                       if (sp->opdata_rsa_pe_num != NULL)
10237 +                               {
10238 +                               BN_free(sp->opdata_rsa_pe_num);
10239 +                               sp->opdata_rsa_pe_num = NULL;
10240 +                               }
10241 +                       if (sp->opdata_rsa_d_num != NULL)
10242 +                               {
10243 +                               BN_free(sp->opdata_rsa_d_num);
10244 +                               sp->opdata_rsa_d_num = NULL;
10245 +                               }
10246 +                       break;
10247 +               default:
10248 +                       break;
10249 +               }
10250 +       }
10253 + * Get new PK11_SESSION structure ready for use. Every process must have
10254 + * its own freelist of PK11_SESSION structures so handle fork() here
10255 + * by destroying the old and creating new freelist.
10256 + * The returned PK11_SESSION structure is disconnected from the freelist.
10257 + */
10258 +PK11_SESSION *
10259 +pk11_get_session(PK11_OPTYPE optype)
10260 +       {
10261 +       PK11_SESSION *sp = NULL, *sp1, *freelist;
10262 +#ifndef NOPTHREADS
10263 +       pthread_mutex_t *freelist_lock = NULL;
10264 +#endif
10265 +       static pid_t pid = 0;
10266 +       pid_t new_pid;
10267 +       CK_RV rv;
10269 +       switch (optype)
10270 +               {
10271 +               case OP_RSA:
10272 +               case OP_DSA:
10273 +               case OP_DH:
10274 +               case OP_RAND:
10275 +               case OP_DIGEST:
10276 +               case OP_CIPHER:
10277 +#ifndef NOPTHREADS
10278 +                       freelist_lock = session_cache[optype].lock;
10279 +#endif
10280 +                       break;
10281 +               default:
10282 +                       PK11err(PK11_F_GET_SESSION,
10283 +                               PK11_R_INVALID_OPERATION_TYPE);
10284 +                       return (NULL);
10285 +               }
10286 +#ifndef NOPTHREADS
10287 +       OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
10288 +#else
10289 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
10290 +#endif
10292 +       /*
10293 +        * Will use it to find out if we forked. We cannot use the PID field in
10294 +        * the session structure because we could get a newly allocated session
10295 +        * here, with no PID information.
10296 +        */
10297 +       if (pid == 0)
10298 +               pid = getpid();
10300 +       freelist = session_cache[optype].head;
10301 +       sp = freelist;
10303 +       /*
10304 +        * If the free list is empty, allocate new unitialized (filled
10305 +        * with zeroes) PK11_SESSION structure otherwise return first
10306 +        * structure from the freelist.
10307 +        */
10308 +       if (sp == NULL)
10309 +               {
10310 +               if ((sp = OPENSSL_malloc(sizeof (PK11_SESSION))) == NULL)
10311 +                       {
10312 +                       PK11err(PK11_F_GET_SESSION,
10313 +                               PK11_R_MALLOC_FAILURE);
10314 +                       goto err;
10315 +                       }
10316 +               (void) memset(sp, 0, sizeof (PK11_SESSION));
10318 +               /*
10319 +                * It is a new session so it will look like a cache miss to the
10320 +                * code below. So, we must not try to to destroy its members so
10321 +                * mark them as unused.
10322 +                */
10323 +               sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
10324 +               sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
10325 +               }
10326 +       else
10327 +               {
10328 +               freelist = sp->next;
10329 +               }
10331 +       /*
10332 +        * Check whether we have forked. In that case, we must get rid of all
10333 +        * inherited sessions and start allocating new ones.
10334 +        */
10335 +       if (pid != (new_pid = getpid()))
10336 +               {
10337 +               pid = new_pid;
10339 +               /*
10340 +                * We are a new process and thus need to free any inherited
10341 +                * PK11_SESSION objects aside from the first session (sp) which
10342 +                * is the only PK11_SESSION structure we will reuse (for the
10343 +                * head of the list).
10344 +                */
10345 +               while ((sp1 = freelist) != NULL)
10346 +                       {
10347 +                       freelist = sp1->next;
10348 +                       /*
10349 +                        * NOTE: we do not want to call pk11_free_all_sessions()
10350 +                        * here because it would close underlying PKCS#11
10351 +                        * sessions and destroy all objects.
10352 +                        */
10353 +                       pk11_free_nums(sp1, optype);
10354 +                       OPENSSL_free(sp1);
10355 +                       }
10357 +               /* we have to free the active list as well. */
10358 +               pk11_free_active_list(optype);
10360 +               /* Initialize the process */
10361 +               rv = pFuncList->C_Initialize((CK_VOID_PTR)&pk11_init_args);
10362 +               if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
10363 +                       {
10364 +                       PK11err_add_data(PK11_F_GET_SESSION, PK11_R_INITIALIZE,
10365 +                           rv);
10366 +                       OPENSSL_free(sp);
10367 +                       sp = NULL;
10368 +                       goto err;
10369 +                       }
10371 +               /*
10372 +                * Choose slot here since the slot table is different on this
10373 +                * process. If we are here then we must have found at least one
10374 +                * usable slot before so we don't need to check any_slot_found.
10375 +                * See pk11_library_init()'s usage of this function for more
10376 +                * information.
10377 +                */
10378 +               if (pk11_choose_slots(NULL) == 0)
10379 +                       goto err;
10381 +               /* Open the global_session for the new process */
10382 +               rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
10383 +                       NULL_PTR, NULL_PTR, &global_session);
10384 +               if (rv != CKR_OK)
10385 +                       {
10386 +                       PK11err_add_data(PK11_F_GET_SESSION, PK11_R_OPENSESSION,
10387 +                           rv);
10388 +                       OPENSSL_free(sp);
10389 +                       sp = NULL;
10390 +                       goto err;
10391 +                       }
10393 +               /*
10394 +                * It is an inherited session from our parent so it needs
10395 +                * re-initialization.
10396 +                */
10397 +               if (pk11_setup_session(sp, optype) == 0)
10398 +                       {
10399 +                       OPENSSL_free(sp);
10400 +                       sp = NULL;
10401 +                       goto err;
10402 +                       }
10403 +               if (pk11_token_relogin(sp->session) == 0) 
10404 +                       {
10405 +                       /*
10406 +                        * We will keep the session in the cache list and let
10407 +                        * the caller cope with the situation.
10408 +                        */
10409 +                       freelist = sp;
10410 +                       sp = NULL;
10411 +                       goto err;
10412 +                       }
10413 +               }
10415 +       if (sp->pid == 0)
10416 +               {
10417 +               /* It is a new session and needs initialization. */
10418 +               if (pk11_setup_session(sp, optype) == 0)
10419 +                       {
10420 +                       OPENSSL_free(sp);
10421 +                       sp = NULL;
10422 +                       }
10423 +               }
10425 +       /* set new head for the list of PK11_SESSION objects */
10426 +       session_cache[optype].head = freelist;
10428 +err:
10429 +       if (sp != NULL)
10430 +               sp->next = NULL;
10432 +#ifndef NOPTHREADS
10433 +       OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
10434 +#else
10435 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
10436 +#endif
10438 +       return (sp);
10439 +       }
10442 +void
10443 +pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype)
10444 +       {
10445 +#ifndef NOPTHREADS
10446 +       pthread_mutex_t *freelist_lock;
10447 +#endif
10448 +       PK11_SESSION *freelist;
10450 +       /*
10451 +        * If this is a session from the parent it will be taken care of and
10452 +        * freed in pk11_get_session() as part of the post-fork clean up the
10453 +        * next time we will ask for a new session.
10454 +        */
10455 +       if (sp == NULL || sp->pid != getpid())
10456 +               return;
10458 +       switch (optype)
10459 +               {
10460 +               case OP_RSA:
10461 +               case OP_DSA:
10462 +               case OP_DH:
10463 +               case OP_RAND:
10464 +               case OP_DIGEST:
10465 +               case OP_CIPHER:
10466 +#ifndef NOPTHREADS
10467 +                       freelist_lock = session_cache[optype].lock;
10468 +#endif
10469 +                       break;
10470 +               default:
10471 +                       PK11err(PK11_F_RETURN_SESSION,
10472 +                               PK11_R_INVALID_OPERATION_TYPE);
10473 +                       return;
10474 +               }
10476 +#ifndef NOPTHREADS
10477 +       OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
10478 +#else
10479 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
10480 +#endif
10481 +       freelist = session_cache[optype].head;
10482 +       sp->next = freelist;
10483 +       session_cache[optype].head = sp;
10484 +#ifndef NOPTHREADS
10485 +       OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
10486 +#else
10487 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
10488 +#endif
10489 +       }
10492 +/* Destroy all objects. This function is called when the engine is finished */
10493 +static int pk11_free_all_sessions()
10494 +       {
10495 +       int ret = 1;
10496 +       int type;
10498 +       (void) pk11_destroy_rsa_key_objects(NULL);
10500 +       /*
10501 +        * We try to release as much as we can but any error means that we will
10502 +        * return 0 on exit.
10503 +        */
10504 +       for (type = 0; type < OP_MAX; type++)
10505 +               {
10506 +               if (pk11_free_session_list(type) == 0)
10507 +                       ret = 0;
10508 +               }
10510 +       return (ret);
10511 +       }
10514 + * Destroy session structures from the linked list specified. Free as many
10515 + * sessions as possible but any failure in C_CloseSession() means that we
10516 + * return an error on return.
10517 + */
10518 +static int pk11_free_session_list(PK11_OPTYPE optype)
10519 +       {
10520 +       CK_RV rv;
10521 +       PK11_SESSION *sp = NULL;
10522 +       PK11_SESSION *freelist = NULL;
10523 +       pid_t mypid = getpid();
10524 +#ifndef NOPTHREADS
10525 +       pthread_mutex_t *freelist_lock;
10526 +#endif
10527 +       int ret = 1;
10529 +       switch (optype)
10530 +               {
10531 +               case OP_RSA:
10532 +               case OP_DSA:
10533 +               case OP_DH:
10534 +               case OP_RAND:
10535 +               case OP_DIGEST:
10536 +               case OP_CIPHER:
10537 +#ifndef NOPTHREADS
10538 +                       freelist_lock = session_cache[optype].lock;
10539 +#endif
10540 +                       break;
10541 +               default:
10542 +                       PK11err(PK11_F_FREE_ALL_SESSIONS,
10543 +                               PK11_R_INVALID_OPERATION_TYPE);
10544 +                       return (0);
10545 +               }
10547 +#ifndef NOPTHREADS
10548 +       OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
10549 +#else
10550 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
10551 +#endif
10552 +       freelist = session_cache[optype].head;
10553 +       while ((sp = freelist) != NULL)
10554 +               {
10555 +               if (sp->session != CK_INVALID_HANDLE && sp->pid == mypid)
10556 +                       {
10557 +                       rv = pFuncList->C_CloseSession(sp->session);
10558 +                       if (rv != CKR_OK)
10559 +                               {
10560 +                               PK11err_add_data(PK11_F_FREE_ALL_SESSIONS,
10561 +                                       PK11_R_CLOSESESSION, rv);
10562 +                               ret = 0;
10563 +                               }
10564 +                       }
10565 +               freelist = sp->next;
10566 +               pk11_free_nums(sp, optype);
10567 +               OPENSSL_free(sp);
10568 +               }
10570 +#ifndef NOPTHREADS
10571 +       OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
10572 +#else
10573 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
10574 +#endif
10575 +       return (ret);
10576 +       }
10579 +static int
10580 +pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype)
10581 +       {
10582 +       CK_RV rv;
10583 +       CK_SLOT_ID myslot;
10585 +       switch (optype)
10586 +               {
10587 +               case OP_RSA:
10588 +                       myslot = pubkey_SLOTID;
10589 +                       break;
10590 +               case OP_RAND:
10591 +                       myslot = rand_SLOTID;
10592 +                       break;
10593 +               default:
10594 +                       PK11err(PK11_F_SETUP_SESSION,
10595 +                           PK11_R_INVALID_OPERATION_TYPE);
10596 +                       return (0);
10597 +               }
10599 +       sp->session = CK_INVALID_HANDLE;
10600 +#ifdef DEBUG_SLOT_SELECTION
10601 +       fprintf(stderr, "%s: myslot=%d optype=%d\n", PK11_DBG, myslot, optype);
10602 +#endif /* DEBUG_SLOT_SELECTION */
10603 +       rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
10604 +               NULL_PTR, NULL_PTR, &sp->session);
10605 +       if (rv == CKR_CRYPTOKI_NOT_INITIALIZED)
10606 +               {
10607 +               /*
10608 +                * We are probably a child process so force the
10609 +                * reinitialize of the session
10610 +                */
10611 +               pk11_library_initialized = FALSE;
10612 +               if (!pk11_library_init(NULL))
10613 +                       return (0);
10614 +               rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
10615 +                       NULL_PTR, NULL_PTR, &sp->session);
10616 +               }
10617 +       if (rv != CKR_OK)
10618 +               {
10619 +               PK11err_add_data(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION, rv);
10620 +               return (0);
10621 +               }
10623 +       sp->pid = getpid();
10625 +       if (optype == OP_RSA)
10626 +               {
10627 +               sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
10628 +               sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
10629 +               sp->opdata_rsa_pub = NULL;
10630 +               sp->opdata_rsa_n_num = NULL;
10631 +               sp->opdata_rsa_e_num = NULL;
10632 +               sp->opdata_rsa_priv = NULL;
10633 +               sp->opdata_rsa_pn_num = NULL;
10634 +               sp->opdata_rsa_pe_num = NULL;
10635 +               sp->opdata_rsa_d_num = NULL;
10636 +               }
10638 +       /*
10639 +        * We always initialize the session as containing a non-persistent
10640 +        * object. The key load functions set it to persistent if that is so.
10641 +        */
10642 +       sp->pub_persistent = CK_FALSE;
10643 +       sp->priv_persistent = CK_FALSE;
10644 +       return (1);
10645 +       }
10647 +/* Destroy RSA public key from single session. */
10648 +int
10649 +pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
10650 +       {
10651 +       int ret = 0;
10653 +       if (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE)
10654 +               {
10655 +               TRY_OBJ_DESTROY(sp, sp->opdata_rsa_pub_key,
10656 +                   ret, uselock, OP_RSA, CK_FALSE);
10657 +               sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
10658 +               sp->opdata_rsa_pub = NULL;
10659 +               if (sp->opdata_rsa_n_num != NULL)
10660 +                       {
10661 +                       BN_free(sp->opdata_rsa_n_num);
10662 +                       sp->opdata_rsa_n_num = NULL;
10663 +                       }
10664 +               if (sp->opdata_rsa_e_num != NULL)
10665 +                       {
10666 +                       BN_free(sp->opdata_rsa_e_num);
10667 +                       sp->opdata_rsa_e_num = NULL;
10668 +                       }
10669 +               }
10671 +       return (ret);
10672 +       }
10674 +/* Destroy RSA private key from single session. */
10675 +int
10676 +pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
10677 +       {
10678 +       int ret = 0;
10680 +       if (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE)
10681 +               {
10682 +               TRY_OBJ_DESTROY(sp, sp->opdata_rsa_priv_key,
10683 +                   ret, uselock, OP_RSA, CK_TRUE);
10684 +               sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
10685 +               sp->opdata_rsa_priv = NULL;
10686 +               if (sp->opdata_rsa_d_num != NULL)
10687 +                       {
10688 +                       BN_free(sp->opdata_rsa_d_num);
10689 +                       sp->opdata_rsa_d_num = NULL;
10690 +                       }
10692 +               /*
10693 +                * For the RSA key by reference code, public components 'n'/'e'
10694 +                * are the key components we use to check for the cache hit. We
10695 +                * must free those as well.
10696 +                */
10697 +               if (sp->opdata_rsa_pn_num != NULL)
10698 +                       {
10699 +                       BN_free(sp->opdata_rsa_pn_num);
10700 +                       sp->opdata_rsa_pn_num = NULL;
10701 +                       }
10702 +               if (sp->opdata_rsa_pe_num != NULL)
10703 +                       {
10704 +                       BN_free(sp->opdata_rsa_pe_num);
10705 +                       sp->opdata_rsa_pe_num = NULL;
10706 +                       }
10707 +               }
10709 +       return (ret);
10710 +       }
10713 + * Destroy RSA key object wrapper. If session is NULL, try to destroy all
10714 + * objects in the free list.
10715 + */
10716 +int
10717 +pk11_destroy_rsa_key_objects(PK11_SESSION *session)
10718 +       {
10719 +       int ret = 1;
10720 +       PK11_SESSION *sp = NULL;
10721 +       PK11_SESSION *local_free_session;
10722 +       CK_BBOOL uselock = TRUE;
10724 +       if (session != NULL)
10725 +               local_free_session = session;
10726 +       else
10727 +               {
10728 +#ifndef NOPTHREADS
10729 +               OPENSSL_assert(pthread_mutex_lock(session_cache[OP_RSA].lock) == 0);
10730 +#else
10731 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
10732 +#endif
10733 +               local_free_session = session_cache[OP_RSA].head;
10734 +               uselock = FALSE;
10735 +               }
10737 +       /*
10738 +        * go through the list of sessions and delete key objects
10739 +        */
10740 +       while ((sp = local_free_session) != NULL)
10741 +               {
10742 +               local_free_session = sp->next;
10744 +               /*
10745 +                * Do not terminate list traversal if one of the
10746 +                * destroy operations fails.
10747 +                */
10748 +               if (pk11_destroy_rsa_object_pub(sp, uselock) == 0)
10749 +                       {
10750 +                       ret = 0;
10751 +                       continue;
10752 +                       }
10753 +               if (pk11_destroy_rsa_object_priv(sp, uselock) == 0)
10754 +                       {
10755 +                       ret = 0;
10756 +                       continue;
10757 +                       }
10758 +               }
10760 +#ifndef NOPTHREADS
10761 +       if (session == NULL)
10762 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[OP_RSA].lock) == 0);
10763 +#else
10764 +       if (session == NULL)
10765 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
10766 +#endif
10768 +       return (ret);
10769 +       }
10771 +static int
10772 +pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
10773 +       CK_BBOOL persistent)
10774 +       {
10775 +       CK_RV rv;
10777 +       /*
10778 +        * We never try to destroy persistent objects which are the objects
10779 +        * stored in the keystore. Also, we always use read-only sessions so
10780 +        * C_DestroyObject() would be returning CKR_SESSION_READ_ONLY here.
10781 +        */
10782 +       if (persistent == CK_TRUE)
10783 +               return (1);
10785 +       rv = pFuncList->C_DestroyObject(session, oh);
10786 +       if (rv != CKR_OK)
10787 +               {
10788 +               PK11err_add_data(PK11_F_DESTROY_OBJECT, PK11_R_DESTROYOBJECT,
10789 +                   rv);
10790 +               return (0);
10791 +               }
10793 +       return (1);
10794 +       }
10798 + * Public key mechanisms optionally supported
10799 + *
10800 + * CKM_RSA_PKCS
10801 + *
10802 + * The first slot that supports at least one of those mechanisms is chosen as a
10803 + * public key slot.
10804 + *
10805 + * The output of this function is a set of global variables indicating which
10806 + * mechanisms from RSA, DSA, DH and RAND are present, and also two arrays of
10807 + * mechanisms, one for symmetric ciphers and one for digests. Also, 3 global
10808 + * variables carry information about which slot was chosen for (a) public key
10809 + * mechanisms, (b) random operations, and (c) symmetric ciphers and digests.
10810 + */
10811 +static int
10812 +pk11_choose_slots(int *any_slot_found)
10813 +       {
10814 +       CK_SLOT_ID_PTR pSlotList = NULL_PTR;
10815 +       CK_ULONG ulSlotCount = 0;
10816 +       CK_MECHANISM_INFO mech_info;
10817 +       CK_TOKEN_INFO token_info;
10818 +       unsigned int i;
10819 +       CK_RV rv;
10820 +       CK_SLOT_ID best_slot_sofar = 0;
10821 +       CK_BBOOL found_candidate_slot = CK_FALSE;
10822 +       CK_SLOT_ID current_slot = 0;
10824 +       /* let's initialize the output parameter */
10825 +       if (any_slot_found != NULL)
10826 +               *any_slot_found = 0;
10828 +       /* Get slot list for memory allocation */
10829 +       rv = pFuncList->C_GetSlotList(CK_FALSE, NULL_PTR, &ulSlotCount);
10831 +       if (rv != CKR_OK)
10832 +               {
10833 +               PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
10834 +               return (0);
10835 +               }
10837 +       /* it's not an error if we didn't find any providers */
10838 +       if (ulSlotCount == 0)
10839 +               {
10840 +#ifdef DEBUG_SLOT_SELECTION
10841 +               fprintf(stderr, "%s: no crypto providers found\n", PK11_DBG);
10842 +#endif /* DEBUG_SLOT_SELECTION */
10843 +               return (1);
10844 +               }
10846 +       pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
10848 +       if (pSlotList == NULL)
10849 +               {
10850 +               PK11err(PK11_F_CHOOSE_SLOT, PK11_R_MALLOC_FAILURE);
10851 +               return (0);
10852 +               }
10854 +       /* Get the slot list for processing */
10855 +       rv = pFuncList->C_GetSlotList(CK_FALSE, pSlotList, &ulSlotCount);
10856 +       if (rv != CKR_OK)
10857 +               {
10858 +               PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
10859 +               OPENSSL_free(pSlotList);
10860 +               return (0);
10861 +               }
10863 +#ifdef DEBUG_SLOT_SELECTION
10864 +       fprintf(stderr, "%s: provider: %s\n", PK11_DBG, def_PK11_LIBNAME);
10865 +       fprintf(stderr, "%s: number of slots: %d\n", PK11_DBG, ulSlotCount);
10867 +       fprintf(stderr, "%s: == checking rand slots ==\n", PK11_DBG);
10868 +#endif /* DEBUG_SLOT_SELECTION */
10869 +       for (i = 0; i < ulSlotCount; i++)
10870 +               {
10871 +               current_slot = pSlotList[i];
10873 +#ifdef DEBUG_SLOT_SELECTION
10874 +       fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
10875 +#endif /* DEBUG_SLOT_SELECTION */
10876 +               /* Check if slot has random support. */
10877 +               rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
10878 +               if (rv != CKR_OK)
10879 +                       continue;
10881 +#ifdef DEBUG_SLOT_SELECTION
10882 +       fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
10883 +#endif /* DEBUG_SLOT_SELECTION */
10885 +               if (token_info.flags & CKF_RNG)
10886 +                       {
10887 +#ifdef DEBUG_SLOT_SELECTION
10888 +       fprintf(stderr, "%s: this token has CKF_RNG flag\n", PK11_DBG);
10889 +#endif /* DEBUG_SLOT_SELECTION */
10890 +                       pk11_have_random = CK_TRUE;
10891 +                       rand_SLOTID = current_slot;
10892 +                       break;
10893 +                       }
10894 +               }
10896 +#ifdef DEBUG_SLOT_SELECTION
10897 +       fprintf(stderr, "%s: == checking pubkey slots ==\n", PK11_DBG);
10898 +#endif /* DEBUG_SLOT_SELECTION */
10900 +       pubkey_SLOTID = pSlotList[0];
10901 +       for (i = 0; i < ulSlotCount; i++)
10902 +               {
10903 +               CK_BBOOL slot_has_rsa = CK_FALSE;
10904 +               current_slot = pSlotList[i];
10906 +#ifdef DEBUG_SLOT_SELECTION
10907 +       fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
10908 +#endif /* DEBUG_SLOT_SELECTION */
10909 +               rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
10910 +               if (rv != CKR_OK)
10911 +                       continue;
10913 +#ifdef DEBUG_SLOT_SELECTION
10914 +       fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
10915 +#endif /* DEBUG_SLOT_SELECTION */
10917 +               /*
10918 +                * Check if this slot is capable of signing with CKM_RSA_PKCS.
10919 +                */
10920 +               rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS,
10921 +                       &mech_info);
10923 +               if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN)))
10924 +                       {
10925 +                       slot_has_rsa = CK_TRUE;
10926 +                       }
10928 +               if (!found_candidate_slot && slot_has_rsa)
10929 +                       {
10930 +#ifdef DEBUG_SLOT_SELECTION
10931 +                       fprintf(stderr,
10932 +                           "%s: potential slot: %d\n", PK11_DBG, current_slot);
10933 +#endif /* DEBUG_SLOT_SELECTION */
10934 +                       best_slot_sofar = current_slot;
10935 +                       pk11_have_rsa = slot_has_rsa;
10936 +                       found_candidate_slot = CK_TRUE;
10937 +                       /*
10938 +                        * Cache the flags for later use. We might
10939 +                        * need those if RSA keys by reference feature
10940 +                        * is used.
10941 +                        */
10942 +                       pubkey_token_flags = token_info.flags;
10943 +#ifdef DEBUG_SLOT_SELECTION
10944 +                       fprintf(stderr,
10945 +                           "%s: setting found_candidate_slot to CK_TRUE\n",
10946 +                           PK11_DBG);
10947 +                       fprintf(stderr,
10948 +                           "%s: best so far slot: %d\n", PK11_DBG,
10949 +                           best_slot_sofar);
10950 +                       fprintf(stderr, "%s: pubkey flags changed to "
10951 +                           "%lu.\n", PK11_DBG, pubkey_token_flags);
10952 +                       }
10953 +               else
10954 +                       {
10955 +                       fprintf(stderr,
10956 +                           "%s: no rsa\n", PK11_DBG);
10957 +                       }
10958 +#else
10959 +                       } /* if */
10960 +#endif /* DEBUG_SLOT_SELECTION */
10961 +               } /* for */
10963 +       if (found_candidate_slot == CK_TRUE)
10964 +               {
10965 +               pubkey_SLOTID = best_slot_sofar;
10966 +               }
10968 +       /*SLOTID = pSlotList[0];*/
10970 +#ifdef DEBUG_SLOT_SELECTION
10971 +       fprintf(stderr,
10972 +           "%s: chosen pubkey slot: %d\n", PK11_DBG, pubkey_SLOTID);
10973 +       fprintf(stderr,
10974 +           "%s: chosen rand slot: %d\n", PK11_DBG, rand_SLOTID);
10975 +       fprintf(stderr,
10976 +           "%s: pk11_have_rsa %d\n", PK11_DBG, pk11_have_rsa);
10977 +       fprintf(stderr,
10978 +           "%s: pk11_have_random %d\n", PK11_DBG, pk11_have_random);
10979 +#endif /* DEBUG_SLOT_SELECTION */
10981 +       if (pSlotList != NULL)
10982 +               OPENSSL_free(pSlotList);
10984 +       if (any_slot_found != NULL)
10985 +               *any_slot_found = 1;
10986 +       return (1);
10987 +       }
10989 +#endif /* OPENSSL_NO_HW_PK11SO */
10990 +#endif /* OPENSSL_NO_HW_PK11 */
10991 +#endif /* OPENSSL_NO_HW */
10992 Index: openssl/crypto/engine/hw_pk11so.h
10993 diff -u /dev/null openssl/crypto/engine/hw_pk11so.h:1.4
10994 --- /dev/null   Fri Jan  2 14:26:17 2015
10995 +++ openssl/crypto/engine/hw_pk11so.h   Wed Jun 15 21:12:20 2011
10996 @@ -0,0 +1,32 @@
10997 +/* Redefine all pk11/PK11 external symbols to pk11so/PK11SO */
10999 +#define token_lock                     pk11so_token_lock
11000 +#define find_lock                      pk11so_find_lock
11001 +#define active_list                    pk11so_active_list
11002 +#define pubkey_token_flags             pk11so_pubkey_token_flags
11003 +#define pubkey_SLOTID                  pk11so_pubkey_SLOTID
11004 +#define ERR_pk11_error                 ERR_pk11so_error
11005 +#define PK11err_add_data               PK11SOerr_add_data
11006 +#define pk11_get_session               pk11so_get_session
11007 +#define pk11_return_session            pk11so_return_session
11008 +#define pk11_active_add                        pk11so_active_add
11009 +#define pk11_active_delete             pk11so_active_delete
11010 +#define pk11_active_remove             pk11so_active_remove
11011 +#define pk11_free_active_list          pk11so_free_active_list
11012 +#define pk11_destroy_rsa_key_objects   pk11so_destroy_rsa_key_objects
11013 +#define pk11_destroy_rsa_object_pub    pk11so_destroy_rsa_object_pub
11014 +#define pk11_destroy_rsa_object_priv   pk11so_destroy_rsa_object_priv
11015 +#define pk11_load_privkey              pk11so_load_privkey
11016 +#define pk11_load_pubkey               pk11so_load_pubkey
11017 +#define PK11_RSA                       PK11SO_RSA
11018 +#define pk11_destroy_dsa_key_objects   pk11so_destroy_dsa_key_objects
11019 +#define pk11_destroy_dsa_object_pub    pk11so_destroy_dsa_object_pub
11020 +#define pk11_destroy_dsa_object_priv   pk11so_destroy_dsa_object_priv
11021 +#define PK11_DSA                       PK11SO_DSA
11022 +#define pk11_destroy_dh_key_objects    pk11so_destroy_dh_key_objects
11023 +#define pk11_destroy_dh_object         pk11so_destroy_dh_object
11024 +#define PK11_DH                                PK11SO_DH
11025 +#define pk11_token_relogin             pk11so_token_relogin
11026 +#define pFuncList                      pk11so_pFuncList
11027 +#define pk11_pin                       pk11so_pin
11028 +#define ENGINE_load_pk11               ENGINE_load_pk11so
11029 Index: openssl/crypto/engine/hw_pk11so_pub.c
11030 diff -u /dev/null openssl/crypto/engine/hw_pk11so_pub.c:1.8.2.2
11031 --- /dev/null   Fri Jan  2 14:26:17 2015
11032 +++ openssl/crypto/engine/hw_pk11so_pub.c       Fri Oct  4 14:33:56 2013
11033 @@ -0,0 +1,1642 @@
11035 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
11036 + * Use is subject to license terms.
11037 + */
11039 +/* crypto/engine/hw_pk11_pub.c */
11041 + * This product includes software developed by the OpenSSL Project for
11042 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
11043 + *
11044 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
11045 + * Afchine Madjlessi.
11046 + */
11048 + * ====================================================================
11049 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
11050 + *
11051 + * Redistribution and use in source and binary forms, with or without
11052 + * modification, are permitted provided that the following conditions
11053 + * are met:
11054 + *
11055 + * 1. Redistributions of source code must retain the above copyright
11056 + *    notice, this list of conditions and the following disclaimer.
11057 + *
11058 + * 2. Redistributions in binary form must reproduce the above copyright
11059 + *    notice, this list of conditions and the following disclaimer in
11060 + *    the documentation and/or other materials provided with the
11061 + *    distribution.
11062 + *
11063 + * 3. All advertising materials mentioning features or use of this
11064 + *    software must display the following acknowledgment:
11065 + *    "This product includes software developed by the OpenSSL Project
11066 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
11067 + *
11068 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
11069 + *    endorse or promote products derived from this software without
11070 + *    prior written permission. For written permission, please contact
11071 + *    licensing@OpenSSL.org.
11072 + *
11073 + * 5. Products derived from this software may not be called "OpenSSL"
11074 + *    nor may "OpenSSL" appear in their names without prior written
11075 + *    permission of the OpenSSL Project.
11076 + *
11077 + * 6. Redistributions of any form whatsoever must retain the following
11078 + *    acknowledgment:
11079 + *    "This product includes software developed by the OpenSSL Project
11080 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
11081 + *
11082 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
11083 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
11084 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
11085 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
11086 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
11087 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
11088 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
11089 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
11090 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
11091 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
11092 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
11093 + * OF THE POSSIBILITY OF SUCH DAMAGE.
11094 + * ====================================================================
11095 + *
11096 + * This product includes cryptographic software written by Eric Young
11097 + * (eay@cryptsoft.com).  This product includes software written by Tim
11098 + * Hudson (tjh@cryptsoft.com).
11099 + *
11100 + */
11102 +/* Modified to keep only RNG and RSA Sign */
11104 +#ifdef OPENSSL_NO_RSA
11105 +#error RSA is disabled
11106 +#endif
11108 +#include <stdio.h>
11109 +#include <stdlib.h>
11110 +#include <string.h>
11111 +#include <sys/types.h>
11113 +#include <openssl/e_os2.h>
11114 +#include <openssl/crypto.h>
11115 +#include <cryptlib.h>
11116 +#include <openssl/engine.h>
11117 +#include <openssl/dso.h>
11118 +#include <openssl/err.h>
11119 +#include <openssl/bn.h>
11120 +#include <openssl/pem.h>
11121 +#include <openssl/rsa.h>
11122 +#include <openssl/rand.h>
11123 +#include <openssl/objects.h>
11124 +#include <openssl/x509.h>
11126 +#ifdef OPENSSL_SYS_WIN32
11127 +#define NOPTHREADS
11128 +typedef int pid_t;
11129 +#define HAVE_GETPASSPHRASE
11130 +static char *getpassphrase(const char *prompt);
11131 +#ifndef NULL_PTR
11132 +#define NULL_PTR NULL
11133 +#endif
11134 +#define CK_DEFINE_FUNCTION(returnType, name) \
11135 +       returnType __declspec(dllexport) name
11136 +#define CK_DECLARE_FUNCTION(returnType, name) \
11137 +       returnType __declspec(dllimport) name
11138 +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
11139 +       returnType __declspec(dllimport) (* name)
11140 +#else
11141 +#include <unistd.h>
11142 +#endif
11144 +#ifndef NOPTHREADS
11145 +#include <pthread.h>
11146 +#endif
11148 +#ifndef OPENSSL_NO_HW
11149 +#ifndef OPENSSL_NO_HW_PK11
11150 +#ifndef OPENSSL_NO_HW_PK11SO
11152 +#ifdef OPENSSL_SYS_WIN32
11153 +#pragma pack(push, cryptoki, 1)
11154 +#include "cryptoki.h"
11155 +#include "pkcs11.h"
11156 +#pragma pack(pop, cryptoki)
11157 +#else
11158 +#include "cryptoki.h"
11159 +#include "pkcs11.h"
11160 +#endif
11161 +#include "hw_pk11so.h"
11162 +#include "hw_pk11_err.h"
11164 +static CK_BBOOL pk11_login_done = CK_FALSE;
11165 +extern CK_SLOT_ID pubkey_SLOTID;
11166 +#ifndef NOPTHREADS
11167 +extern pthread_mutex_t *token_lock;
11168 +#endif
11170 +#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun)))
11171 +#define getpassphrase(x)       getpass(x)
11172 +#endif
11174 +/* RSA stuff */
11175 +static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
11176 +       unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
11177 +EVP_PKEY *pk11_load_privkey(ENGINE*, const char *privkey_file,
11178 +       UI_METHOD *ui_method, void *callback_data);
11179 +EVP_PKEY *pk11_load_pubkey(ENGINE*, const char *pubkey_file,
11180 +       UI_METHOD *ui_method, void *callback_data);
11182 +static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA* rsa, RSA** key_ptr,
11183 +       BIGNUM **rsa_n_num, BIGNUM **rsa_e_num, CK_SESSION_HANDLE session);
11184 +static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa, RSA** key_ptr,
11185 +       BIGNUM **rsa_d_num, BIGNUM **rsa_n_num, BIGNUM **rsa_e_num,
11186 +       CK_SESSION_HANDLE session);
11188 +static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa);
11189 +static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa);
11191 +static int find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
11192 +       CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey);
11193 +static int init_template_value(BIGNUM *bn, CK_VOID_PTR *pValue,
11194 +       CK_ULONG *ulValueLen);
11195 +static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn);
11197 +static int pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
11198 +       CK_BBOOL is_private);
11200 +/* Read mode string to be used for fopen() */
11201 +#if SOLARIS_OPENSSL
11202 +static char *read_mode_flags = "rF";
11203 +#else
11204 +static char *read_mode_flags = "r";
11205 +#endif
11208 + * increment/create reference for an asymmetric key handle via active list
11209 + * manipulation. If active list operation fails, unlock (if locked), set error
11210 + * variable and jump to the specified label.
11211 + */
11212 +#define        KEY_HANDLE_REFHOLD(key_handle, alg_type, unlock, var, label)    \
11213 +       {                                                               \
11214 +       if (pk11_active_add(key_handle, alg_type) < 0)                  \
11215 +               {                                                       \
11216 +               var = TRUE;                                             \
11217 +               if (unlock)                                             \
11218 +                       UNLOCK_OBJSTORE(alg_type);                      \
11219 +               goto label;                                             \
11220 +               }                                                       \
11221 +       }
11224 + * Find active list entry according to object handle and return pointer to the
11225 + * entry otherwise return NULL.
11226 + *
11227 + * This function presumes it is called with lock protecting the active list
11228 + * held.
11229 + */
11230 +static PK11_active *pk11_active_find(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
11231 +       {
11232 +       PK11_active *entry;
11234 +       for (entry = active_list[type]; entry != NULL; entry = entry->next)
11235 +               if (entry->h == h)
11236 +                       return (entry);
11238 +       return (NULL);
11239 +       }
11242 + * Search for an entry in the active list using PKCS#11 object handle as a
11243 + * search key and return refcnt of the found/created entry or -1 in case of
11244 + * failure.
11245 + *
11246 + * This function presumes it is called with lock protecting the active list
11247 + * held.
11248 + */
11249 +int
11250 +pk11_active_add(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
11251 +       {
11252 +       PK11_active *entry = NULL;
11254 +       if (h == CK_INVALID_HANDLE)
11255 +               {
11256 +               PK11err(PK11_F_ACTIVE_ADD, PK11_R_INVALID_HANDLE);
11257 +               return (-1);
11258 +               }
11260 +       /* search for entry in the active list */
11261 +       if ((entry = pk11_active_find(h, type)) != NULL)
11262 +               entry->refcnt++;
11263 +       else
11264 +               {
11265 +               /* not found, create new entry and add it to the list */
11266 +               entry = OPENSSL_malloc(sizeof (PK11_active));
11267 +               if (entry == NULL)
11268 +                       {
11269 +                       PK11err(PK11_F_ACTIVE_ADD, PK11_R_MALLOC_FAILURE);
11270 +                       return (-1);
11271 +                       }
11272 +               entry->h = h;
11273 +               entry->refcnt = 1;
11274 +               entry->prev = NULL;
11275 +               entry->next = NULL;
11276 +               /* connect the newly created entry to the list */
11277 +               if (active_list[type] == NULL)
11278 +                       active_list[type] = entry;
11279 +               else /* make the entry first in the list */
11280 +                       {
11281 +                       entry->next = active_list[type];
11282 +                       active_list[type]->prev = entry;
11283 +                       active_list[type] = entry;
11284 +                       }
11285 +               }
11287 +       return (entry->refcnt);
11288 +       }
11291 + * Remove active list entry from the list and free it.
11292 + *
11293 + * This function presumes it is called with lock protecting the active list
11294 + * held.
11295 + */
11296 +void
11297 +pk11_active_remove(PK11_active *entry, PK11_OPTYPE type)
11298 +       {
11299 +       PK11_active *prev_entry;
11301 +       /* remove the entry from the list and free it */
11302 +       if ((prev_entry = entry->prev) != NULL)
11303 +               {
11304 +               prev_entry->next = entry->next;
11305 +               if (entry->next != NULL)
11306 +                       entry->next->prev = prev_entry;
11307 +               }
11308 +       else
11309 +               {
11310 +               active_list[type] = entry->next;
11311 +               /* we were the first but not the only one */
11312 +               if (entry->next != NULL)
11313 +                       entry->next->prev = NULL;
11314 +               }
11316 +       /* sanitization */
11317 +       entry->h = CK_INVALID_HANDLE;
11318 +       entry->prev = NULL;
11319 +       entry->next = NULL;
11320 +       OPENSSL_free(entry);
11321 +       }
11323 +/* Free all entries from the active list. */
11324 +void
11325 +pk11_free_active_list(PK11_OPTYPE type)
11326 +       {
11327 +       PK11_active *entry;
11329 +       /* only for asymmetric types since only they have C_Find* locks. */
11330 +       switch (type)
11331 +               {
11332 +               case OP_RSA:
11333 +                       break;
11334 +               default:
11335 +                       return;
11336 +               }
11338 +       /* see find_lock array definition for more info on object locking */
11339 +       LOCK_OBJSTORE(type);
11340 +       while ((entry = active_list[type]) != NULL)
11341 +               pk11_active_remove(entry, type);
11342 +       UNLOCK_OBJSTORE(type);
11343 +       }
11346 + * Search for active list entry associated with given PKCS#11 object handle,
11347 + * decrement its refcnt and if it drops to 0, disconnect the entry and free it.
11348 + *
11349 + * Return 1 if the PKCS#11 object associated with the entry has no references,
11350 + * return 0 if there is at least one reference, -1 on error.
11351 + *
11352 + * This function presumes it is called with lock protecting the active list
11353 + * held.
11354 + */
11355 +int
11356 +pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
11357 +       {
11358 +       PK11_active *entry = NULL;
11360 +       if ((entry = pk11_active_find(h, type)) == NULL)
11361 +               {
11362 +               PK11err(PK11_F_ACTIVE_DELETE, PK11_R_INVALID_HANDLE);
11363 +               return (-1);
11364 +               }
11366 +       OPENSSL_assert(entry->refcnt > 0);
11367 +       entry->refcnt--;
11368 +       if (entry->refcnt == 0)
11369 +               {
11370 +               pk11_active_remove(entry, type);
11371 +               return (1);
11372 +               }
11374 +       return (0);
11375 +       }
11377 +/* Our internal RSA_METHOD that we provide pointers to */
11378 +static RSA_METHOD pk11_rsa;
11380 +RSA_METHOD *
11381 +PK11_RSA(void)
11382 +       {
11383 +       const RSA_METHOD *rsa;
11385 +       if (pk11_rsa.name == NULL)
11386 +               {
11387 +               rsa = RSA_PKCS1_SSLeay();
11388 +               memcpy(&pk11_rsa, rsa, sizeof(*rsa));
11389 +               pk11_rsa.name = "PKCS#11 RSA method";
11390 +               pk11_rsa.rsa_sign = pk11_RSA_sign;
11391 +               }
11392 +       return (&pk11_rsa);
11393 +       }
11395 +/* Size of an SSL signature: MD5+SHA1 */
11396 +#define        SSL_SIG_LENGTH          36
11398 +static CK_BBOOL mytrue = TRUE;
11399 +static CK_BBOOL myfalse = FALSE;
11402 + * Standard engine interface function. Majority codes here are from
11403 + * rsa/rsa_sign.c. We replaced the decrypt function call by C_Sign of PKCS#11.
11404 + * See more details in rsa/rsa_sign.c
11405 + */
11406 +static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
11407 +       unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
11408 +       {
11409 +       X509_SIG sig;
11410 +       ASN1_TYPE parameter;
11411 +       int i, j = 0;
11412 +       unsigned char *p, *s = NULL;
11413 +       X509_ALGOR algor;
11414 +       ASN1_OCTET_STRING digest;
11415 +       CK_RV rv;
11416 +       CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
11417 +       CK_MECHANISM *p_mech = &mech_rsa;
11418 +       CK_OBJECT_HANDLE h_priv_key;
11419 +       PK11_SESSION *sp = NULL;
11420 +       int ret = 0;
11421 +       unsigned long ulsiglen;
11423 +       /* Encode the digest */
11424 +       /* Special case: SSL signature, just check the length */
11425 +       if (type == NID_md5_sha1)
11426 +               {
11427 +               if (m_len != SSL_SIG_LENGTH)
11428 +                       {
11429 +                       PK11err(PK11_F_RSA_SIGN,
11430 +                               PK11_R_INVALID_MESSAGE_LENGTH);
11431 +                       goto err;
11432 +                       }
11433 +               i = SSL_SIG_LENGTH;
11434 +               s = (unsigned char *)m;
11435 +               }
11436 +       else
11437 +               {
11438 +               sig.algor = &algor;
11439 +               sig.algor->algorithm = OBJ_nid2obj(type);
11440 +               if (sig.algor->algorithm == NULL)
11441 +                       {
11442 +                       PK11err(PK11_F_RSA_SIGN,
11443 +                               PK11_R_UNKNOWN_ALGORITHM_TYPE);
11444 +                       goto err;
11445 +                       }
11446 +               if (sig.algor->algorithm->length == 0)
11447 +                       {
11448 +                       PK11err(PK11_F_RSA_SIGN,
11449 +                               PK11_R_UNKNOWN_ASN1_OBJECT_ID);
11450 +                       goto err;
11451 +                       }
11452 +               parameter.type = V_ASN1_NULL;
11453 +               parameter.value.ptr = NULL;
11454 +               sig.algor->parameter = &parameter;
11456 +               sig.digest = &digest;
11457 +               sig.digest->data = (unsigned char *)m;
11458 +               sig.digest->length = m_len;
11460 +               i = i2d_X509_SIG(&sig, NULL);
11461 +               }
11463 +       j = RSA_size(rsa);
11464 +       if ((i - RSA_PKCS1_PADDING) > j)
11465 +               {
11466 +               PK11err(PK11_F_RSA_SIGN, PK11_R_DIGEST_TOO_BIG);
11467 +               goto err;
11468 +               }
11470 +       if (type != NID_md5_sha1)
11471 +               {
11472 +               s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
11473 +               if (s == NULL)
11474 +                       {
11475 +                       PK11err(PK11_F_RSA_SIGN, PK11_R_MALLOC_FAILURE);
11476 +                       goto err;
11477 +                       }
11478 +               p = s;
11479 +               (void) i2d_X509_SIG(&sig, &p);
11480 +               }
11482 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
11483 +               goto err;
11485 +       (void) check_new_rsa_key_priv(sp, rsa);
11487 +       h_priv_key = sp->opdata_rsa_priv_key;
11488 +       if (h_priv_key == CK_INVALID_HANDLE)
11489 +               h_priv_key = sp->opdata_rsa_priv_key =
11490 +                       pk11_get_private_rsa_key((RSA *)rsa,
11491 +                           &sp->opdata_rsa_priv, &sp->opdata_rsa_d_num,
11492 +                           &sp->opdata_rsa_pn_num, &sp->opdata_rsa_pe_num,
11493 +                           sp->session);
11495 +       if (h_priv_key != CK_INVALID_HANDLE)
11496 +               {
11497 +               rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
11499 +               if (rv != CKR_OK)
11500 +                       {
11501 +                       PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGNINIT, rv);
11502 +                       goto err;
11503 +                       }
11505 +               ulsiglen = j;
11506 +               rv = pFuncList->C_Sign(sp->session, s, i, sigret,
11507 +                       (CK_ULONG_PTR) &ulsiglen);
11508 +               *siglen = ulsiglen;
11510 +               if (rv != CKR_OK)
11511 +                       {
11512 +                       PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGN, rv);
11513 +                       goto err;
11514 +                       }
11515 +               ret = 1;
11516 +               }
11518 +err:
11519 +       if ((type != NID_md5_sha1) && (s != NULL))
11520 +               {
11521 +               (void) memset(s, 0, (unsigned int)(j + 1));
11522 +               OPENSSL_free(s);
11523 +               }
11525 +       pk11_return_session(sp, OP_RSA);
11526 +       return (ret);
11527 +       }
11529 +static int hndidx_rsa = -1;
11531 +#define        MAXATTR 1024
11534 + * Load RSA private key from a file or get its PKCS#11 handle if stored in the
11535 + * PKCS#11 token.
11536 + */
11537 +/* ARGSUSED */
11538 +EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *privkey_file,
11539 +       UI_METHOD *ui_method, void *callback_data)
11540 +       {
11541 +       EVP_PKEY *pkey = NULL;
11542 +       FILE *privkey;
11543 +       CK_OBJECT_HANDLE  h_priv_key = CK_INVALID_HANDLE;
11544 +       RSA *rsa = NULL;
11545 +       PK11_SESSION *sp;
11546 +       /* Anything else below is needed for the key by reference extension. */
11547 +       CK_RV rv;
11548 +       CK_BBOOL is_token = TRUE;
11549 +       CK_BBOOL rollback = FALSE;
11550 +       CK_BYTE attr_data[2][MAXATTR];
11551 +       CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
11552 +       CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;    /* key in keystore */
11554 +       /* we look for private keys only */
11555 +       CK_ATTRIBUTE search_templ[] =
11556 +               {
11557 +               {CKA_TOKEN, &is_token, sizeof(is_token)},
11558 +               {CKA_CLASS, &key_class, sizeof(key_class)},
11559 +               {CKA_LABEL, NULL, 0}
11560 +               };
11562 +       /*
11563 +        * These public attributes are needed to initialize the OpenSSL RSA
11564 +        * structure with something we can use to look up the key. Note that we
11565 +        * never ask for private components.
11566 +        */
11567 +       CK_ATTRIBUTE get_templ[] =
11568 +               {
11569 +               {CKA_MODULUS, (void *)attr_data[0], MAXATTR},           /* n */
11570 +               {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},   /* e */
11571 +               };
11573 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
11574 +               return (NULL);
11576 +       /*
11577 +        * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
11578 +        */
11579 +       if (strstr(privkey_file, "pkcs11:") == privkey_file)
11580 +               {
11581 +               search_templ[2].pValue = strstr(privkey_file, ":") + 1;
11582 +               search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
11584 +               if (pk11_token_login(sp->session, &pk11_login_done,
11585 +                   CK_TRUE) == 0)
11586 +                       goto err;
11588 +               /* see find_lock array definition
11589 +                  for more info on object locking */
11590 +               LOCK_OBJSTORE(OP_RSA);
11592 +               /*
11593 +                * Now let's try to find the key in the token. It is a failure
11594 +                * if we can't find it.
11595 +                */
11596 +               if (find_one_object(OP_RSA, sp->session, search_templ, 3,
11597 +                   &ks_key) == 0)
11598 +                       {
11599 +                       UNLOCK_OBJSTORE(OP_RSA);
11600 +                       goto err;
11601 +                       }
11603 +               if (hndidx_rsa == -1)
11604 +                       hndidx_rsa = RSA_get_ex_new_index(0,
11605 +                                       "pkcs11 RSA HSM key handle",
11606 +                                       NULL, NULL, NULL);
11608 +               /*
11609 +                * We might have a cache hit which we could confirm
11610 +                * according to the 'n'/'e' params, RSA public pointer
11611 +                * as NULL, and non-NULL RSA private pointer. However,
11612 +                * it is easier just to recreate everything. We expect
11613 +                * the keys to be loaded once and used many times. We
11614 +                * do not check the return value because even in case
11615 +                * of failure the sp structure will have both key
11616 +                * pointer and object handle cleaned and
11617 +                * pk11_destroy_object() reports the failure to the
11618 +                * OpenSSL error message buffer.
11619 +                */
11620 +               (void) pk11_destroy_rsa_object_priv(sp, FALSE);
11622 +               sp->opdata_rsa_priv_key = ks_key;
11623 +               /* This object shall not be deleted on a cache miss. */
11624 +               sp->priv_persistent = CK_TRUE;
11626 +               /*
11627 +                * Cache the RSA private structure pointer. We do not
11628 +                * use it now for key-by-ref keys but let's do it for
11629 +                * consistency reasons.
11630 +                */
11631 +               if ((rsa = sp->opdata_rsa_priv = RSA_new_method(e)) == NULL)
11632 +                       {
11633 +                       UNLOCK_OBJSTORE(OP_RSA);
11634 +                       goto err;
11635 +                       }
11637 +               /*
11638 +                * Now we have to initialize an OpenSSL RSA structure,
11639 +                * everything else is 0 or NULL.
11640 +                */
11641 +               rsa->flags = RSA_FLAG_SIGN_VER | RSA_FLAG_EXT_PKEY;
11642 +               RSA_set_ex_data(rsa, hndidx_rsa, (void *) ks_key);
11644 +               if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
11645 +                   get_templ, 2)) != CKR_OK)
11646 +                       {
11647 +                       UNLOCK_OBJSTORE(OP_RSA);
11648 +                       PK11err_add_data(PK11_F_LOAD_PRIVKEY,
11649 +                                        PK11_R_GETATTRIBUTVALUE, rv);
11650 +                       goto err;
11651 +                       }
11653 +               /*
11654 +                * We do not use pk11_get_private_rsa_key() here so we
11655 +                * must take care of handle management ourselves.
11656 +                */
11657 +               KEY_HANDLE_REFHOLD(ks_key, OP_RSA, TRUE, rollback, err);
11659 +               /*
11660 +                * Those are the sensitive components we do not want to export
11661 +                * from the token at all: rsa->(d|p|q|dmp1|dmq1|iqmp).
11662 +                */
11663 +               attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
11664 +               attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
11665 +               /*
11666 +                * Must have 'n'/'e' components in the session structure as
11667 +                * well. They serve as a public look-up key for the private key
11668 +                * in the keystore.
11669 +                */
11670 +               attr_to_BN(&get_templ[0], attr_data[0],
11671 +                       &sp->opdata_rsa_pn_num);
11672 +               attr_to_BN(&get_templ[1], attr_data[1],
11673 +                       &sp->opdata_rsa_pe_num);
11675 +               UNLOCK_OBJSTORE(OP_RSA);
11677 +               if ((pkey = EVP_PKEY_new()) == NULL)
11678 +                       goto err;
11680 +               if (EVP_PKEY_assign_RSA(pkey, rsa) == 0)
11681 +                       goto err;
11682 +               }
11683 +       else if ((privkey = fopen(privkey_file, read_mode_flags)) != NULL)
11684 +               {
11685 +               pkey = PEM_read_PrivateKey(privkey, NULL, NULL, NULL);
11686 +               (void) fclose(privkey);
11687 +               if (pkey != NULL)
11688 +                       {
11689 +                       rsa = EVP_PKEY_get1_RSA(pkey);
11690 +                       if (rsa != NULL)
11691 +                               {
11692 +                               /*
11693 +                                * This will always destroy the RSA
11694 +                                * object since we have a new RSA
11695 +                                * structure here.
11696 +                                */
11697 +                               (void) check_new_rsa_key_priv(sp, rsa);
11698 +                               sp->priv_persistent = CK_FALSE;
11700 +                               h_priv_key = sp->opdata_rsa_priv_key =
11701 +                                   pk11_get_private_rsa_key(rsa,
11702 +                                   &sp->opdata_rsa_priv,
11703 +                                   &sp->opdata_rsa_d_num,
11704 +                                   &sp->opdata_rsa_pn_num,
11705 +                                   &sp->opdata_rsa_pe_num, sp->session);
11706 +                               if (h_priv_key == CK_INVALID_HANDLE)
11707 +                                       goto err;
11708 +                               }
11709 +                       else
11710 +                               goto err;
11711 +                       }
11712 +               }
11714 +       pk11_return_session(sp, OP_RSA);
11715 +       return (pkey);
11716 +err:
11717 +       pk11_return_session(sp, OP_RSA);
11718 +       if (rsa != NULL)
11719 +               RSA_free(rsa);
11720 +       if (pkey != NULL)
11721 +               {
11722 +               EVP_PKEY_free(pkey);
11723 +               pkey = NULL;
11724 +               }
11725 +       rollback = rollback;
11726 +       return (pkey);
11727 +       }
11730 + * Load RSA public key from a file or get its PKCS#11 handle if stored in the
11731 + * PKCS#11 token.
11732 + */
11733 +/* ARGSUSED */
11734 +EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
11735 +       UI_METHOD *ui_method, void *callback_data)
11736 +       {
11737 +       EVP_PKEY *pkey = NULL;
11738 +       FILE *pubkey;
11739 +       CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
11740 +       RSA *rsa = NULL;
11741 +       PK11_SESSION *sp;
11742 +       /* Anything else below is needed for the key by reference extension. */
11743 +       CK_RV rv;
11744 +       CK_BBOOL is_token = TRUE;
11745 +       CK_BYTE attr_data[2][MAXATTR];
11746 +       CK_OBJECT_CLASS key_class = CKO_PUBLIC_KEY;
11747 +       CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;    /* key in keystore */
11749 +       /* we look for public keys only */
11750 +       CK_ATTRIBUTE search_templ[] =
11751 +               {
11752 +               {CKA_TOKEN, &is_token, sizeof(is_token)},
11753 +               {CKA_CLASS, &key_class, sizeof(key_class)},
11754 +               {CKA_LABEL, NULL, 0}
11755 +               };
11757 +       /*
11758 +        * These public attributes are needed to initialize OpenSSL RSA
11759 +        * structure with something we can use to look up the key.
11760 +        */
11761 +       CK_ATTRIBUTE get_templ[] =
11762 +               {
11763 +               {CKA_MODULUS, (void *)attr_data[0], MAXATTR},           /* n */
11764 +               {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},   /* e */
11765 +               };
11767 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
11768 +               return (NULL);
11770 +       /*
11771 +        * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
11772 +        */
11773 +       if (strstr(pubkey_file, "pkcs11:") == pubkey_file)
11774 +               {
11775 +               search_templ[2].pValue = strstr(pubkey_file, ":") + 1;
11776 +               search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
11778 +               if (pk11_token_login(sp->session, &pk11_login_done,
11779 +                   CK_FALSE) == 0)
11780 +                       goto err;
11782 +               /* see find_lock array definition
11783 +                  for more info on object locking */
11784 +               LOCK_OBJSTORE(OP_RSA);
11786 +               /*
11787 +                * Now let's try to find the key in the token. It is a failure
11788 +                * if we can't find it.
11789 +                */
11790 +               if (find_one_object(OP_RSA, sp->session, search_templ, 3,
11791 +                   &ks_key) == 0)
11792 +                       {
11793 +                       UNLOCK_OBJSTORE(OP_RSA);
11794 +                       goto err;
11795 +                       }
11797 +               /*
11798 +                * We load a new public key so we will create a new RSA
11799 +                * structure. No cache hit is possible.
11800 +                */
11801 +               (void) pk11_destroy_rsa_object_pub(sp, FALSE);
11803 +               sp->opdata_rsa_pub_key = ks_key;
11804 +               /* This object shall not be deleted on a cache miss. */
11805 +               sp->pub_persistent = CK_TRUE;
11807 +               /*
11808 +                * Cache the RSA public structure pointer.
11809 +                */
11810 +               if ((rsa = sp->opdata_rsa_pub = RSA_new_method(e)) == NULL)
11811 +                       {
11812 +                       UNLOCK_OBJSTORE(OP_RSA);
11813 +                       goto err;
11814 +                       }
11816 +               /*
11817 +                * Now we have to initialize an OpenSSL RSA structure,
11818 +                * everything else is 0 or NULL.
11819 +                */
11820 +               rsa->flags = RSA_FLAG_SIGN_VER;
11822 +               if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
11823 +                   get_templ, 2)) != CKR_OK)
11824 +                       {
11825 +                       UNLOCK_OBJSTORE(OP_RSA);
11826 +                       PK11err_add_data(PK11_F_LOAD_PUBKEY,
11827 +                                        PK11_R_GETATTRIBUTVALUE, rv);
11828 +                       goto err;
11829 +                       }
11831 +               attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
11832 +               attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
11834 +               UNLOCK_OBJSTORE(OP_RSA);
11836 +               if ((pkey = EVP_PKEY_new()) == NULL)
11837 +                       goto err;
11839 +               if (EVP_PKEY_assign_RSA(pkey, rsa) == 0)
11840 +                       goto err;
11842 +               /*
11843 +                * Create a session object from it so that when calling
11844 +                * pk11_get_public_rsa_key() the next time, we can find it. The
11845 +                * reason why we do that is that we cannot tell from the RSA
11846 +                * structure (OpenSSL RSA structure does not have any room for
11847 +                * additional data used by the engine, for example) if it bears
11848 +                * a public key stored in the keystore or not so it's better if
11849 +                * we always have a session key. Note that this is different
11850 +                * from what we do for the private keystore objects but in that
11851 +                * case, we can tell from the RSA structure that the keystore
11852 +                * object is in play - the 'd' component is NULL in that case.
11853 +                */
11854 +               h_pub_key = sp->opdata_rsa_pub_key =
11855 +                   pk11_get_public_rsa_key(rsa,
11856 +                   &sp->opdata_rsa_pub, &sp->opdata_rsa_n_num,
11857 +                   &sp->opdata_rsa_e_num, sp->session);
11858 +               if (h_pub_key == CK_INVALID_HANDLE)
11859 +                       goto err;
11860 +               }
11861 +       else if ((pubkey = fopen(pubkey_file, read_mode_flags)) != NULL)
11862 +               {
11863 +               pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL);
11864 +               (void) fclose(pubkey);
11865 +               if (pkey != NULL)
11866 +                       {
11867 +                       rsa = EVP_PKEY_get1_RSA(pkey);
11868 +                       if (rsa != NULL)
11869 +                               {
11870 +                               /*
11871 +                                * This will always destroy the RSA
11872 +                                * object since we have a new RSA
11873 +                                * structure here.
11874 +                                */
11875 +                               (void) check_new_rsa_key_pub(sp, rsa);
11876 +                               sp->pub_persistent = CK_FALSE;
11878 +                               h_pub_key = sp->opdata_rsa_pub_key =
11879 +                                   pk11_get_public_rsa_key(rsa,
11880 +                                   &sp->opdata_rsa_pub, &sp->opdata_rsa_n_num,
11881 +                                   &sp->opdata_rsa_e_num, sp->session);
11882 +                               if (h_pub_key == CK_INVALID_HANDLE)
11883 +                                       goto err;
11884 +                               }
11885 +                       else
11886 +                               goto err;
11887 +                       }
11888 +               }
11890 +       pk11_return_session(sp, OP_RSA);
11891 +       return (pkey);
11892 +err:
11893 +       pk11_return_session(sp, OP_RSA);
11894 +       if (rsa != NULL)
11895 +               RSA_free(rsa);
11896 +       if (pkey != NULL)
11897 +               {
11898 +               EVP_PKEY_free(pkey);
11899 +               pkey = NULL;
11900 +               }
11901 +       return (pkey);
11902 +       }
11905 + * Create a public key object in a session from a given rsa structure.
11906 + * The *rsa_n_num and *rsa_e_num pointers are non-NULL for RSA public keys.
11907 + */
11908 +static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA *rsa,
11909 +    RSA **key_ptr, BIGNUM **rsa_n_num, BIGNUM **rsa_e_num,
11910 +    CK_SESSION_HANDLE session)
11911 +       {
11912 +       CK_RV rv;
11913 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
11914 +       CK_ULONG found;
11915 +       CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
11916 +       CK_KEY_TYPE k_type = CKK_RSA;
11917 +       CK_ULONG ul_key_attr_count = 8;
11918 +       CK_BBOOL rollback = FALSE;
11920 +       CK_ATTRIBUTE  a_key_template[] =
11921 +               {
11922 +               {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
11923 +               {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
11924 +               {CKA_TOKEN, &myfalse, sizeof (myfalse)},
11925 +               {CKA_ENCRYPT, &mytrue, sizeof (mytrue)},
11926 +               {CKA_VERIFY, &mytrue, sizeof (mytrue)},
11927 +               {CKA_VERIFY_RECOVER, &mytrue, sizeof (mytrue)},
11928 +               {CKA_MODULUS, (void *)NULL, 0},
11929 +               {CKA_PUBLIC_EXPONENT, (void *)NULL, 0}
11930 +               };
11932 +       int i;
11934 +       a_key_template[0].pValue = &o_key;
11935 +       a_key_template[1].pValue = &k_type;
11937 +       a_key_template[6].ulValueLen = BN_num_bytes(rsa->n);
11938 +       a_key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
11939 +               (size_t)a_key_template[6].ulValueLen);
11940 +       if (a_key_template[6].pValue == NULL)
11941 +               {
11942 +               PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
11943 +               goto malloc_err;
11944 +               }
11946 +       BN_bn2bin(rsa->n, a_key_template[6].pValue);
11948 +       a_key_template[7].ulValueLen = BN_num_bytes(rsa->e);
11949 +       a_key_template[7].pValue = (CK_VOID_PTR)OPENSSL_malloc(
11950 +               (size_t)a_key_template[7].ulValueLen);
11951 +       if (a_key_template[7].pValue == NULL)
11952 +               {
11953 +               PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
11954 +               goto malloc_err;
11955 +               }
11957 +       BN_bn2bin(rsa->e, a_key_template[7].pValue);
11959 +       /* see find_lock array definition for more info on object locking */
11960 +       LOCK_OBJSTORE(OP_RSA);
11962 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template,
11963 +               ul_key_attr_count);
11965 +       if (rv != CKR_OK)
11966 +               {
11967 +               PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
11968 +                   PK11_R_FINDOBJECTSINIT, rv);
11969 +               goto err;
11970 +               }
11972 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
11974 +       if (rv != CKR_OK)
11975 +               {
11976 +               (void) pFuncList->C_FindObjectsFinal(session);
11977 +               PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
11978 +                   PK11_R_FINDOBJECTS, rv);
11979 +               goto err;
11980 +               }
11982 +       rv = pFuncList->C_FindObjectsFinal(session);
11984 +       if (rv != CKR_OK)
11985 +               {
11986 +               PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
11987 +                   PK11_R_FINDOBJECTSFINAL, rv);
11988 +               goto err;
11989 +               }
11991 +       if (found == 0)
11992 +               {
11993 +               rv = pFuncList->C_CreateObject(session,
11994 +                       a_key_template, ul_key_attr_count, &h_key);
11995 +               if (rv != CKR_OK)
11996 +                       {
11997 +                       PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
11998 +                           PK11_R_CREATEOBJECT, rv);
11999 +                       goto err;
12000 +                       }
12001 +               }
12003 +       if (rsa_n_num != NULL)
12004 +               if ((*rsa_n_num = BN_dup(rsa->n)) == NULL)
12005 +                       {
12006 +                       PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
12007 +                       rollback = TRUE;
12008 +                       goto err;
12009 +                       }
12010 +       if (rsa_e_num != NULL)
12011 +               if ((*rsa_e_num = BN_dup(rsa->e)) == NULL)
12012 +                       {
12013 +                       PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
12014 +                       BN_free(*rsa_n_num);
12015 +                       *rsa_n_num = NULL;
12016 +                       rollback = TRUE;
12017 +                       goto err;
12018 +                       }
12020 +       /* LINTED: E_CONSTANT_CONDITION */
12021 +       KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
12022 +       if (key_ptr != NULL)
12023 +               *key_ptr = rsa;
12025 +err:
12026 +       if (rollback)
12027 +               {
12028 +               /*
12029 +                * We do not care about the return value from C_DestroyObject()
12030 +                * since we are doing rollback.
12031 +                */
12032 +               if (found == 0)
12033 +                       (void) pFuncList->C_DestroyObject(session, h_key);
12034 +               h_key = CK_INVALID_HANDLE;
12035 +               }
12037 +       UNLOCK_OBJSTORE(OP_RSA);
12039 +malloc_err:
12040 +       for (i = 6; i <= 7; i++)
12041 +               {
12042 +               if (a_key_template[i].pValue != NULL)
12043 +                       {
12044 +                       OPENSSL_free(a_key_template[i].pValue);
12045 +                       a_key_template[i].pValue = NULL;
12046 +                       }
12047 +               }
12049 +       return (h_key);
12050 +       }
12053 + * Create a private key object in the session from a given rsa structure.
12054 + * The *rsa_d_num pointer is non-NULL for RSA private keys.
12055 + */
12056 +static CK_OBJECT_HANDLE
12057 +pk11_get_private_rsa_key(RSA *rsa, RSA **key_ptr, BIGNUM **rsa_d_num,
12058 +    BIGNUM **rsa_n_num, BIGNUM **rsa_e_num, CK_SESSION_HANDLE session)
12059 +       {
12060 +       CK_RV rv;
12061 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
12062 +       int i;
12063 +       CK_ULONG found;
12064 +       CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
12065 +       CK_KEY_TYPE k_type = CKK_RSA;
12066 +       CK_ULONG ul_key_attr_count = 14;
12067 +       CK_BBOOL rollback = FALSE;
12069 +       /* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys */
12070 +       CK_ATTRIBUTE  a_key_template[] =
12071 +               {
12072 +               {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
12073 +               {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
12074 +               {CKA_TOKEN, &myfalse, sizeof (myfalse)},
12075 +               {CKA_SENSITIVE, &myfalse, sizeof (myfalse)},
12076 +               {CKA_DECRYPT, &mytrue, sizeof (mytrue)},
12077 +               {CKA_SIGN, &mytrue, sizeof (mytrue)},
12078 +               {CKA_MODULUS, (void *)NULL, 0},
12079 +               {CKA_PUBLIC_EXPONENT, (void *)NULL, 0},
12080 +               {CKA_PRIVATE_EXPONENT, (void *)NULL, 0},
12081 +               {CKA_PRIME_1, (void *)NULL, 0},
12082 +               {CKA_PRIME_2, (void *)NULL, 0},
12083 +               {CKA_EXPONENT_1, (void *)NULL, 0},
12084 +               {CKA_EXPONENT_2, (void *)NULL, 0},
12085 +               {CKA_COEFFICIENT, (void *)NULL, 0},
12086 +               };
12088 +       if ((rsa->flags & RSA_FLAG_EXT_PKEY) != 0) {
12089 +               h_key = (CK_OBJECT_HANDLE)RSA_get_ex_data(rsa, hndidx_rsa);
12090 +               LOCK_OBJSTORE(OP_RSA);
12091 +               goto set;
12092 +       }
12093 +       
12094 +       a_key_template[0].pValue = &o_key;
12095 +       a_key_template[1].pValue = &k_type;
12097 +       /* Put the private key components into the template */
12098 +       if (init_template_value(rsa->n, &a_key_template[6].pValue,
12099 +               &a_key_template[6].ulValueLen) == 0 ||
12100 +           init_template_value(rsa->e, &a_key_template[7].pValue,
12101 +               &a_key_template[7].ulValueLen) == 0 ||
12102 +           init_template_value(rsa->d, &a_key_template[8].pValue,
12103 +               &a_key_template[8].ulValueLen) == 0 ||
12104 +           init_template_value(rsa->p, &a_key_template[9].pValue,
12105 +               &a_key_template[9].ulValueLen) == 0 ||
12106 +           init_template_value(rsa->q, &a_key_template[10].pValue,
12107 +               &a_key_template[10].ulValueLen) == 0 ||
12108 +           init_template_value(rsa->dmp1, &a_key_template[11].pValue,
12109 +               &a_key_template[11].ulValueLen) == 0 ||
12110 +           init_template_value(rsa->dmq1, &a_key_template[12].pValue,
12111 +               &a_key_template[12].ulValueLen) == 0 ||
12112 +           init_template_value(rsa->iqmp, &a_key_template[13].pValue,
12113 +               &a_key_template[13].ulValueLen) == 0)
12114 +               {
12115 +               PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
12116 +               goto malloc_err;
12117 +               }
12119 +       /* see find_lock array definition for more info on object locking */
12120 +       LOCK_OBJSTORE(OP_RSA);
12122 +       /*
12123 +        * We are getting the private key but the private 'd'
12124 +        * component is NULL.  That means this is key by reference RSA
12125 +        * key. In that case, we can use only public components for
12126 +        * searching for the private key handle.
12127 +        */
12128 +       if (rsa->d == NULL)
12129 +               {
12130 +               ul_key_attr_count = 8;
12131 +               /*
12132 +                * We will perform the search in the token, not in the existing
12133 +                * session keys.
12134 +                */
12135 +               a_key_template[2].pValue = &mytrue;
12136 +               }
12138 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template,
12139 +               ul_key_attr_count);
12141 +       if (rv != CKR_OK)
12142 +               {
12143 +               PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
12144 +                   PK11_R_FINDOBJECTSINIT, rv);
12145 +               goto err;
12146 +               }
12148 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
12150 +       if (rv != CKR_OK)
12151 +               {
12152 +               (void) pFuncList->C_FindObjectsFinal(session);
12153 +               PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
12154 +                   PK11_R_FINDOBJECTS, rv);
12155 +               goto err;
12156 +               }
12158 +       rv = pFuncList->C_FindObjectsFinal(session);
12160 +       if (rv != CKR_OK)
12161 +               {
12162 +               PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
12163 +                   PK11_R_FINDOBJECTSFINAL, rv);
12164 +               goto err;
12165 +               }
12167 +       if (found == 0)
12168 +               {
12169 +               /*
12170 +                * We have an RSA structure with 'n'/'e' components
12171 +                * only so we tried to find the private key in the
12172 +                * keystore. If it was really a token key we have a
12173 +                * problem. Note that for other key types we just
12174 +                * create a new session key using the private
12175 +                * components from the RSA structure.
12176 +                */
12177 +               if (rsa->d == NULL)
12178 +                       {
12179 +                       PK11err(PK11_F_GET_PRIV_RSA_KEY,
12180 +                           PK11_R_PRIV_KEY_NOT_FOUND);
12181 +                       goto err;
12182 +                       }
12184 +               rv = pFuncList->C_CreateObject(session,
12185 +                       a_key_template, ul_key_attr_count, &h_key);
12186 +               if (rv != CKR_OK)
12187 +                       {
12188 +                       PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
12189 +                               PK11_R_CREATEOBJECT, rv);
12190 +                       goto err;
12191 +                       }
12192 +               }
12194 +set:
12195 +       if (rsa_d_num != NULL)
12196 +               {
12197 +               /*
12198 +                * When RSA keys by reference code is used, we never
12199 +                * extract private components from the keystore. In
12200 +                * that case 'd' was set to NULL and we expect the
12201 +                * application to properly cope with that. It is
12202 +                * documented in openssl(5). In general, if keys by
12203 +                * reference are used we expect it to be used
12204 +                * exclusively using the high level API and then there
12205 +                * is no problem. If the application expects the
12206 +                * private components to be read from the keystore
12207 +                * then that is not a supported way of usage.
12208 +                */
12209 +               if (rsa->d != NULL && (*rsa_d_num = BN_dup(rsa->d)) == NULL)
12210 +                       {
12211 +                       PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
12212 +                       rollback = TRUE;
12213 +                       goto err;
12214 +                       }
12215 +               else
12216 +                       *rsa_d_num = NULL;
12217 +               }
12219 +       /*
12220 +        * For the key by reference code, we need public components as well
12221 +        * since 'd' component is always NULL. For that reason, we always cache
12222 +        * 'n'/'e' components as well.
12223 +        */
12224 +       *rsa_n_num = BN_dup(rsa->n);
12225 +       *rsa_e_num = BN_dup(rsa->e);
12227 +       /* LINTED: E_CONSTANT_CONDITION */
12228 +       KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
12229 +       if (key_ptr != NULL)
12230 +               *key_ptr = rsa;
12232 +err:
12233 +       if (rollback)
12234 +               {
12235 +               /*
12236 +                * We do not care about the return value from C_DestroyObject()
12237 +                * since we are doing rollback.
12238 +                */
12239 +               if (found == 0 &&
12240 +                   (rsa->flags & RSA_FLAG_EXT_PKEY) == 0)
12241 +                       (void) pFuncList->C_DestroyObject(session, h_key);
12242 +               h_key = CK_INVALID_HANDLE;
12243 +               }
12245 +       UNLOCK_OBJSTORE(OP_RSA);
12247 +malloc_err:
12248 +       /*
12249 +        * 6 to 13 entries in the key template are key components.
12250 +        * They need to be freed upon exit or error.
12251 +        */
12252 +       for (i = 6; i <= 13; i++)
12253 +               {
12254 +               if (a_key_template[i].pValue != NULL)
12255 +                       {
12256 +                       (void) memset(a_key_template[i].pValue, 0,
12257 +                               a_key_template[i].ulValueLen);
12258 +                       OPENSSL_free(a_key_template[i].pValue);
12259 +                       a_key_template[i].pValue = NULL;
12260 +                       }
12261 +               }
12263 +       return (h_key);
12264 +       }
12267 + * Check for cache miss and clean the object pointer and handle
12268 + * in such case. Return 1 for cache hit, 0 for cache miss.
12269 + */
12270 +static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa)
12271 +       {
12272 +       /*
12273 +        * Provide protection against RSA structure reuse by making the
12274 +        * check for cache hit stronger. Only public components of RSA
12275 +        * key matter here so it is sufficient to compare them with values
12276 +        * cached in PK11_SESSION structure.
12277 +        *
12278 +        * We must check the handle as well since with key by reference, public
12279 +        * components 'n'/'e' are cached in private keys as well. That means we
12280 +        * could have a cache hit in a private key when looking for a public
12281 +        * key. That would not work, you cannot have one PKCS#11 object for
12282 +        * both data signing and verifying.
12283 +        */
12284 +       if ((sp->opdata_rsa_pub != rsa) ||
12285 +           (BN_cmp(sp->opdata_rsa_n_num, rsa->n) != 0) ||
12286 +           (BN_cmp(sp->opdata_rsa_e_num, rsa->e) != 0) ||
12287 +           (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE))
12288 +               {
12289 +               /*
12290 +                * We do not check the return value because even in case of
12291 +                * failure the sp structure will have both key pointer
12292 +                * and object handle cleaned and pk11_destroy_object()
12293 +                * reports the failure to the OpenSSL error message buffer.
12294 +                */
12295 +               (void) pk11_destroy_rsa_object_pub(sp, TRUE);
12296 +               return (0);
12297 +               }
12298 +       return (1);
12299 +       }
12302 + * Check for cache miss and clean the object pointer and handle
12303 + * in such case. Return 1 for cache hit, 0 for cache miss.
12304 + */
12305 +static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa)
12306 +       {
12307 +       /*
12308 +        * Provide protection against RSA structure reuse by making
12309 +        * the check for cache hit stronger. Comparing public exponent
12310 +        * of RSA key with value cached in PK11_SESSION structure
12311 +        * should be sufficient. Note that we want to compare the
12312 +        * public component since with the keys by reference
12313 +        * mechanism, private components are not in the RSA
12314 +        * structure. Also, see check_new_rsa_key_pub() about why we
12315 +        * compare the handle as well.
12316 +        */
12317 +       if ((sp->opdata_rsa_priv != rsa) ||
12318 +           (BN_cmp(sp->opdata_rsa_pn_num, rsa->n) != 0) ||
12319 +           (BN_cmp(sp->opdata_rsa_pe_num, rsa->e) != 0) ||
12320 +           (sp->opdata_rsa_pn_num == NULL) ||
12321 +           (sp->opdata_rsa_pe_num == NULL) ||
12322 +           (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE))
12323 +               {
12324 +               /*
12325 +                * We do not check the return value because even in case of
12326 +                * failure the sp structure will have both key pointer
12327 +                * and object handle cleaned and pk11_destroy_object()
12328 +                * reports the failure to the OpenSSL error message buffer.
12329 +                */
12330 +               (void) pk11_destroy_rsa_object_priv(sp, TRUE);
12331 +               return (0);
12332 +               }
12333 +       return (1);
12334 +       }
12337 + * Local function to simplify key template population
12338 + * Return 0 -- error, 1 -- no error
12339 + */
12340 +static int
12341 +init_template_value(BIGNUM *bn, CK_VOID_PTR *p_value,
12342 +       CK_ULONG *ul_value_len)
12343 +       {
12344 +       CK_ULONG len = 0;
12346 +       /*
12347 +        * This function can be used on non-initialized BIGNUMs. It is
12348 +        * easier to check that here than individually in the callers.
12349 +        */
12350 +       if (bn != NULL)
12351 +               len = BN_num_bytes(bn);
12353 +       if (bn == NULL || len == 0)
12354 +               return (1);
12356 +       *ul_value_len = len;
12357 +       *p_value = (CK_VOID_PTR)OPENSSL_malloc((size_t)*ul_value_len);
12358 +       if (*p_value == NULL)
12359 +               return (0);
12361 +       BN_bn2bin(bn, *p_value);
12363 +       return (1);
12364 +       }
12366 +static void
12367 +attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn)
12368 +       {
12369 +       if (attr->ulValueLen > 0)
12370 +               *bn = BN_bin2bn(attr_data, attr->ulValueLen, NULL);
12371 +       }
12374 + * Find one object in the token. It is an error if we can not find the
12375 + * object or if we find more objects based on the template we got.
12376 + * Assume object store locked.
12377 + *
12378 + * Returns:
12379 + *     1 OK
12380 + *     0 no object or more than 1 object found
12381 + */
12382 +static int
12383 +find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
12384 +    CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey)
12385 +       {
12386 +       CK_RV rv;
12387 +       CK_ULONG objcnt;
12389 +       if ((rv = pFuncList->C_FindObjectsInit(s, ptempl, nattr)) != CKR_OK)
12390 +               {
12391 +               PK11err_add_data(PK11_F_FIND_ONE_OBJECT,
12392 +                   PK11_R_FINDOBJECTSINIT, rv);
12393 +               return (0);
12394 +               }
12396 +       rv = pFuncList->C_FindObjects(s, pkey, 1, &objcnt);
12397 +       if (rv != CKR_OK)
12398 +               {
12399 +               (void) pFuncList->C_FindObjectsFinal(s);
12400 +               PK11err_add_data(PK11_F_FIND_ONE_OBJECT, PK11_R_FINDOBJECTS,
12401 +                   rv);
12402 +               return (0);
12403 +               }
12405 +       (void) pFuncList->C_FindObjectsFinal(s);
12407 +       if (objcnt > 1)
12408 +               {
12409 +               PK11err(PK11_F_FIND_ONE_OBJECT,
12410 +                   PK11_R_MORE_THAN_ONE_OBJECT_FOUND);
12411 +               return (0);
12412 +               }
12413 +       else if (objcnt == 0)
12414 +               {
12415 +               PK11err(PK11_F_FIND_ONE_OBJECT, PK11_R_NO_OBJECT_FOUND);
12416 +               return (0);
12417 +               }
12418 +       return (1);
12419 +       }
12421 +/* from uri stuff */
12423 +extern char *pk11_pin;
12425 +static int pk11_get_pin(void);
12427 +static int
12428 +pk11_get_pin(void)
12430 +       char *pin;
12432 +       /* The getpassphrase() function is not MT safe. */
12433 +#ifndef NOPTHREADS
12434 +       OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
12435 +#else
12436 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
12437 +#endif
12438 +       pin = getpassphrase("Enter PIN: ");
12439 +       if (pin == NULL)
12440 +               {
12441 +               PK11err(PK11_F_GET_PIN, PK11_R_COULD_NOT_READ_PIN);
12442 +#ifndef NOPTHREADS
12443 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12444 +#else
12445 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12446 +#endif
12447 +               return (0);
12448 +               }
12449 +       pk11_pin = BUF_strdup(pin);
12450 +       if (pk11_pin == NULL)
12451 +               {
12452 +               PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_MALLOC_FAILURE);
12453 +#ifndef NOPTHREADS
12454 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12455 +#else
12456 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12457 +#endif
12458 +               return (0);
12459 +               }
12460 +       memset(pin, 0, strlen(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 (1);
12467 +       }
12470 + * Log in to the keystore if we are supposed to do that at all. Take care of
12471 + * reading and caching the PIN etc. Log in only once even when called from
12472 + * multiple threads.
12473 + *
12474 + * Returns:
12475 + *     1 on success
12476 + *     0 on failure
12477 + */
12478 +static int
12479 +pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
12480 +    CK_BBOOL is_private)
12481 +       {
12482 +       CK_RV rv;
12484 +#if 0
12485 +       /* doesn't work on the AEP Keyper??? */
12486 +       if ((pubkey_token_flags & CKF_TOKEN_INITIALIZED) == 0)
12487 +               {
12488 +               PK11err(PK11_F_TOKEN_LOGIN,
12489 +                   PK11_R_TOKEN_NOT_INITIALIZED);
12490 +               return (0);
12491 +               }
12492 +#endif
12494 +       /*
12495 +        * If login is required or needed but the PIN has not been
12496 +        * even initialized we can bail out right now. Note that we
12497 +        * are supposed to always log in if we are going to access
12498 +        * private keys. However, we may need to log in even for
12499 +        * accessing public keys in case that the CKF_LOGIN_REQUIRED
12500 +        * flag is set.
12501 +        */
12502 +       if (((pubkey_token_flags & CKF_LOGIN_REQUIRED) ||
12503 +            (is_private == CK_TRUE)) &&
12504 +           (~pubkey_token_flags & CKF_USER_PIN_INITIALIZED))
12505 +               {
12506 +               PK11err(PK11_F_TOKEN_LOGIN, PK11_R_TOKEN_PIN_NOT_SET);
12507 +               return (0);
12508 +               }
12510 +       /*
12511 +        * Note on locking: it is possible that more than one thread
12512 +        * gets into pk11_get_pin() so we must deal with that. We
12513 +        * cannot avoid it since we cannot guard fork() in there with
12514 +        * a lock because we could end up in a dead lock in the
12515 +        * child. Why? Remember we are in a multithreaded environment
12516 +        * so we must lock all mutexes in the prefork function to
12517 +        * avoid a situation in which a thread that did not call
12518 +        * fork() held a lock, making future unlocking impossible. We
12519 +        * lock right before C_Login().
12520 +        */
12521 +       if ((pubkey_token_flags & CKF_LOGIN_REQUIRED) ||
12522 +           (is_private == CK_TRUE))
12523 +               {
12524 +               if (*login_done == CK_FALSE)
12525 +                       {
12526 +                       if ((pk11_pin == NULL) && (pk11_get_pin() == 0))
12527 +                               {
12528 +                               PK11err(PK11_F_TOKEN_LOGIN,
12529 +                                   PK11_R_TOKEN_PIN_NOT_PROVIDED);
12530 +                               return (0);
12531 +                               }
12532 +                       }
12534 +               /*
12535 +                * Note that what we are logging into is the keystore from
12536 +                * pubkey_SLOTID because we work with OP_RSA session type here.
12537 +                * That also means that we can work with only one keystore in
12538 +                * the engine.
12539 +                *
12540 +                * We must make sure we do not try to login more than once.
12541 +                * Also, see the comment above on locking strategy.
12542 +                */
12544 +#ifndef NOPTHREADS
12545 +               OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
12546 +#else
12547 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
12548 +#endif
12549 +               if (*login_done == CK_FALSE)
12550 +                       {
12551 +                       if ((rv = pFuncList->C_Login(session,
12552 +                           CKU_USER, (CK_UTF8CHAR*)pk11_pin,
12553 +                           strlen(pk11_pin))) != CKR_OK)
12554 +                               {
12555 +                               PK11err_add_data(PK11_F_TOKEN_LOGIN,
12556 +                                   PK11_R_TOKEN_LOGIN_FAILED, rv);
12557 +                               goto err_locked;
12558 +                               }
12560 +                       *login_done = CK_TRUE;
12562 +                       }
12563 +#ifndef NOPTHREADS
12564 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12565 +#else
12566 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12567 +#endif
12568 +               }
12569 +       else
12570 +               {
12571 +                       /*
12572 +                        * If token does not require login we take it as the
12573 +                        * login was done.
12574 +                        */
12575 +                       *login_done = CK_TRUE;
12576 +               }
12578 +       return (1);
12580 +err_locked:
12581 +       if (pk11_pin) {
12582 +               memset(pk11_pin, 0, strlen(pk11_pin));
12583 +               OPENSSL_free((void*)pk11_pin);
12584 +       }
12585 +       pk11_pin = NULL;
12586 +#ifndef NOPTHREADS
12587 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12588 +#else
12589 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12590 +#endif
12591 +       return (0);
12592 +       }
12595 + * Log in to the keystore in the child if we were logged in in the
12596 + * parent. There are similarities in the code with pk11_token_login()
12597 + * but still it is quite different so we need a separate function for
12598 + * this.
12599 + *
12600 + * Note that this function is called under the locked session mutex when fork is
12601 + * detected. That means that C_Login() will be called from the child just once.
12602 + *
12603 + * Returns:
12604 + *     1 on success
12605 + *     0 on failure
12606 + */
12607 +int
12608 +pk11_token_relogin(CK_SESSION_HANDLE session)
12609 +       {
12610 +       CK_RV rv;
12612 +       if ((pk11_pin == NULL) && (pk11_get_pin() == 0))
12613 +               return (0);
12615 +#ifndef NOPTHREADS
12616 +       OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
12617 +#else
12618 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
12619 +#endif
12620 +       if ((rv = pFuncList->C_Login(session, CKU_USER,
12621 +           (CK_UTF8CHAR_PTR)pk11_pin, strlen(pk11_pin))) != CKR_OK)
12622 +               {
12623 +               PK11err_add_data(PK11_F_TOKEN_RELOGIN,
12624 +                   PK11_R_TOKEN_LOGIN_FAILED, rv);
12625 +#ifndef NOPTHREADS
12626 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12627 +#else
12628 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12629 +#endif
12630 +               return (0);
12631 +               }
12632 +#ifndef NOPTHREADS
12633 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12634 +#else
12635 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12636 +#endif
12638 +       return (1);
12639 +       }
12641 +#ifdef OPENSSL_SYS_WIN32
12642 +char *getpassphrase(const char *prompt)
12643 +       {
12644 +       static char buf[128];
12645 +       HANDLE h;
12646 +       DWORD cc, mode;
12647 +       int cnt;
12649 +       h = GetStdHandle(STD_INPUT_HANDLE);
12650 +       fputs(prompt, stderr);
12651 +       fflush(stderr);
12652 +       fflush(stdout);
12653 +       FlushConsoleInputBuffer(h);
12654 +       GetConsoleMode(h, &mode);
12655 +       SetConsoleMode(h, ENABLE_PROCESSED_INPUT);
12657 +       for (cnt = 0; cnt < sizeof(buf) - 1; cnt++)
12658 +               {
12659 +               ReadFile(h, buf + cnt, 1, &cc, NULL);
12660 +               if (buf[cnt] == '\r')
12661 +                       break;
12662 +               fputc('*', stdout);
12663 +               fflush(stderr);
12664 +               fflush(stdout);
12665 +               }
12667 +       SetConsoleMode(h, mode);
12668 +       buf[cnt] = '\0';
12669 +       fputs("\n", stderr);
12670 +       return buf;
12671 +       }
12672 +#endif /* OPENSSL_SYS_WIN32 */
12673 +#endif /* OPENSSL_NO_HW_PK11SO */
12674 +#endif /* OPENSSL_NO_HW_PK11 */
12675 +#endif /* OPENSSL_NO_HW */
12676 Index: openssl/crypto/engine/pkcs11.h
12677 diff -u /dev/null openssl/crypto/engine/pkcs11.h:1.1.1.1
12678 --- /dev/null   Fri Jan  2 14:26:17 2015
12679 +++ openssl/crypto/engine/pkcs11.h      Wed Oct 24 23:27:09 2007
12680 @@ -0,0 +1,299 @@
12681 +/* pkcs11.h include file for PKCS #11. */
12682 +/* Revision: 1.1.1.1  */
12684 +/* License to copy and use this software is granted provided that it is
12685 + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
12686 + * (Cryptoki)" in all material mentioning or referencing this software.
12688 + * License is also granted to make and use derivative works provided that
12689 + * such works are identified as "derived from the RSA Security Inc. PKCS #11
12690 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
12691 + * referencing the derived work.
12693 + * RSA Security Inc. makes no representations concerning either the 
12694 + * merchantability of this software or the suitability of this software for
12695 + * any particular purpose. It is provided "as is" without express or implied
12696 + * warranty of any kind.
12697 + */
12699 +#ifndef _PKCS11_H_
12700 +#define _PKCS11_H_ 1
12702 +#ifdef __cplusplus
12703 +extern "C" {
12704 +#endif
12706 +/* Before including this file (pkcs11.h) (or pkcs11t.h by
12707 + * itself), 6 platform-specific macros must be defined.  These
12708 + * macros are described below, and typical definitions for them
12709 + * are also given.  Be advised that these definitions can depend
12710 + * on both the platform and the compiler used (and possibly also
12711 + * on whether a Cryptoki library is linked statically or
12712 + * dynamically).
12713 + *
12714 + * In addition to defining these 6 macros, the packing convention
12715 + * for Cryptoki structures should be set.  The Cryptoki
12716 + * convention on packing is that structures should be 1-byte
12717 + * aligned.
12718 + *
12719 + * If you're using Microsoft Developer Studio 5.0 to produce
12720 + * Win32 stuff, this might be done by using the following
12721 + * preprocessor directive before including pkcs11.h or pkcs11t.h:
12722 + *
12723 + * #pragma pack(push, cryptoki, 1)
12724 + *
12725 + * and using the following preprocessor directive after including
12726 + * pkcs11.h or pkcs11t.h:
12727 + *
12728 + * #pragma pack(pop, cryptoki)
12729 + *
12730 + * If you're using an earlier version of Microsoft Developer
12731 + * Studio to produce Win16 stuff, this might be done by using
12732 + * the following preprocessor directive before including
12733 + * pkcs11.h or pkcs11t.h:
12734 + *
12735 + * #pragma pack(1)
12736 + *
12737 + * In a UNIX environment, you're on your own for this.  You might
12738 + * not need to do (or be able to do!) anything.
12739 + *
12740 + *
12741 + * Now for the macros:
12742 + *
12743 + *
12744 + * 1. CK_PTR: The indirection string for making a pointer to an
12745 + * object.  It can be used like this:
12746 + *
12747 + * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
12748 + *
12749 + * If you're using Microsoft Developer Studio 5.0 to produce
12750 + * Win32 stuff, it might be defined by:
12751 + *
12752 + * #define CK_PTR *
12753 + *
12754 + * If you're using an earlier version of Microsoft Developer
12755 + * Studio to produce Win16 stuff, it might be defined by:
12756 + *
12757 + * #define CK_PTR far *
12758 + *
12759 + * In a typical UNIX environment, it might be defined by:
12760 + *
12761 + * #define CK_PTR *
12762 + *
12763 + *
12764 + * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
12765 + * an exportable Cryptoki library function definition out of a
12766 + * return type and a function name.  It should be used in the
12767 + * following fashion to define the exposed Cryptoki functions in
12768 + * a Cryptoki library:
12769 + *
12770 + * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
12771 + *   CK_VOID_PTR pReserved
12772 + * )
12773 + * {
12774 + *   ...
12775 + * }
12776 + *
12777 + * If you're using Microsoft Developer Studio 5.0 to define a
12778 + * function in a Win32 Cryptoki .dll, it might be defined by:
12779 + *
12780 + * #define CK_DEFINE_FUNCTION(returnType, name) \
12781 + *   returnType __declspec(dllexport) name
12782 + *
12783 + * If you're using an earlier version of Microsoft Developer
12784 + * Studio to define a function in a Win16 Cryptoki .dll, it
12785 + * might be defined by:
12786 + *
12787 + * #define CK_DEFINE_FUNCTION(returnType, name) \
12788 + *   returnType __export _far _pascal name
12789 + *
12790 + * In a UNIX environment, it might be defined by:
12791 + *
12792 + * #define CK_DEFINE_FUNCTION(returnType, name) \
12793 + *   returnType name
12794 + *
12795 + *
12796 + * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
12797 + * an importable Cryptoki library function declaration out of a
12798 + * return type and a function name.  It should be used in the
12799 + * following fashion:
12800 + *
12801 + * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
12802 + *   CK_VOID_PTR pReserved
12803 + * );
12804 + *
12805 + * If you're using Microsoft Developer Studio 5.0 to declare a
12806 + * function in a Win32 Cryptoki .dll, it might be defined by:
12807 + *
12808 + * #define CK_DECLARE_FUNCTION(returnType, name) \
12809 + *   returnType __declspec(dllimport) name
12810 + *
12811 + * If you're using an earlier version of Microsoft Developer
12812 + * Studio to declare a function in a Win16 Cryptoki .dll, it
12813 + * might be defined by:
12814 + *
12815 + * #define CK_DECLARE_FUNCTION(returnType, name) \
12816 + *   returnType __export _far _pascal name
12817 + *
12818 + * In a UNIX environment, it might be defined by:
12819 + *
12820 + * #define CK_DECLARE_FUNCTION(returnType, name) \
12821 + *   returnType name
12822 + *
12823 + *
12824 + * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
12825 + * which makes a Cryptoki API function pointer declaration or
12826 + * function pointer type declaration out of a return type and a
12827 + * function name.  It should be used in the following fashion:
12828 + *
12829 + * // Define funcPtr to be a pointer to a Cryptoki API function
12830 + * // taking arguments args and returning CK_RV.
12831 + * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
12832 + *
12833 + * or
12834 + *
12835 + * // Define funcPtrType to be the type of a pointer to a
12836 + * // Cryptoki API function taking arguments args and returning
12837 + * // CK_RV, and then define funcPtr to be a variable of type
12838 + * // funcPtrType.
12839 + * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
12840 + * funcPtrType funcPtr;
12841 + *
12842 + * If you're using Microsoft Developer Studio 5.0 to access
12843 + * functions in a Win32 Cryptoki .dll, in might be defined by:
12844 + *
12845 + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
12846 + *   returnType __declspec(dllimport) (* name)
12847 + *
12848 + * If you're using an earlier version of Microsoft Developer
12849 + * Studio to access functions in a Win16 Cryptoki .dll, it might
12850 + * be defined by:
12851 + *
12852 + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
12853 + *   returnType __export _far _pascal (* name)
12854 + *
12855 + * In a UNIX environment, it might be defined by:
12856 + *
12857 + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
12858 + *   returnType (* name)
12859 + *
12860 + *
12861 + * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
12862 + * a function pointer type for an application callback out of
12863 + * a return type for the callback and a name for the callback.
12864 + * It should be used in the following fashion:
12865 + *
12866 + * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
12867 + *
12868 + * to declare a function pointer, myCallback, to a callback
12869 + * which takes arguments args and returns a CK_RV.  It can also
12870 + * be used like this:
12871 + *
12872 + * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
12873 + * myCallbackType myCallback;
12874 + *
12875 + * If you're using Microsoft Developer Studio 5.0 to do Win32
12876 + * Cryptoki development, it might be defined by:
12877 + *
12878 + * #define CK_CALLBACK_FUNCTION(returnType, name) \
12879 + *   returnType (* name)
12880 + *
12881 + * If you're using an earlier version of Microsoft Developer
12882 + * Studio to do Win16 development, it might be defined by:
12883 + *
12884 + * #define CK_CALLBACK_FUNCTION(returnType, name) \
12885 + *   returnType _far _pascal (* name)
12886 + *
12887 + * In a UNIX environment, it might be defined by:
12888 + *
12889 + * #define CK_CALLBACK_FUNCTION(returnType, name) \
12890 + *   returnType (* name)
12891 + *
12892 + *
12893 + * 6. NULL_PTR: This macro is the value of a NULL pointer.
12894 + *
12895 + * In any ANSI/ISO C environment (and in many others as well),
12896 + * this should best be defined by
12897 + *
12898 + * #ifndef NULL_PTR
12899 + * #define NULL_PTR 0
12900 + * #endif
12901 + */
12904 +/* All the various Cryptoki types and #define'd values are in the
12905 + * file pkcs11t.h. */
12906 +#include "pkcs11t.h"
12908 +#define __PASTE(x,y)      x##y
12911 +/* ==============================================================
12912 + * Define the "extern" form of all the entry points.
12913 + * ==============================================================
12914 + */
12916 +#define CK_NEED_ARG_LIST  1
12917 +#define CK_PKCS11_FUNCTION_INFO(name) \
12918 +  extern CK_DECLARE_FUNCTION(CK_RV, name)
12920 +/* pkcs11f.h has all the information about the Cryptoki
12921 + * function prototypes. */
12922 +#include "pkcs11f.h"
12924 +#undef CK_NEED_ARG_LIST
12925 +#undef CK_PKCS11_FUNCTION_INFO
12928 +/* ==============================================================
12929 + * Define the typedef form of all the entry points.  That is, for
12930 + * each Cryptoki function C_XXX, define a type CK_C_XXX which is
12931 + * a pointer to that kind of function.
12932 + * ==============================================================
12933 + */
12935 +#define CK_NEED_ARG_LIST  1
12936 +#define CK_PKCS11_FUNCTION_INFO(name) \
12937 +  typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
12939 +/* pkcs11f.h has all the information about the Cryptoki
12940 + * function prototypes. */
12941 +#include "pkcs11f.h"
12943 +#undef CK_NEED_ARG_LIST
12944 +#undef CK_PKCS11_FUNCTION_INFO
12947 +/* ==============================================================
12948 + * Define structed vector of entry points.  A CK_FUNCTION_LIST
12949 + * contains a CK_VERSION indicating a library's Cryptoki version
12950 + * and then a whole slew of function pointers to the routines in
12951 + * the library.  This type was declared, but not defined, in
12952 + * pkcs11t.h.
12953 + * ==============================================================
12954 + */
12956 +#define CK_PKCS11_FUNCTION_INFO(name) \
12957 +  __PASTE(CK_,name) name;
12958 +  
12959 +struct CK_FUNCTION_LIST {
12961 +  CK_VERSION    version;  /* Cryptoki version */
12963 +/* Pile all the function pointers into the CK_FUNCTION_LIST. */
12964 +/* pkcs11f.h has all the information about the Cryptoki
12965 + * function prototypes. */
12966 +#include "pkcs11f.h"
12970 +#undef CK_PKCS11_FUNCTION_INFO
12973 +#undef __PASTE
12975 +#ifdef __cplusplus
12977 +#endif
12979 +#endif
12980 Index: openssl/crypto/engine/pkcs11f.h
12981 diff -u /dev/null openssl/crypto/engine/pkcs11f.h:1.1.1.1
12982 --- /dev/null   Fri Jan  2 14:26:17 2015
12983 +++ openssl/crypto/engine/pkcs11f.h     Wed Oct 24 23:27:09 2007
12984 @@ -0,0 +1,912 @@
12985 +/* pkcs11f.h include file for PKCS #11. */
12986 +/* Revision: 1.1.1.1  */
12988 +/* License to copy and use this software is granted provided that it is
12989 + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
12990 + * (Cryptoki)" in all material mentioning or referencing this software.
12992 + * License is also granted to make and use derivative works provided that
12993 + * such works are identified as "derived from the RSA Security Inc. PKCS #11
12994 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
12995 + * referencing the derived work.
12997 + * RSA Security Inc. makes no representations concerning either the 
12998 + * merchantability of this software or the suitability of this software for
12999 + * any particular purpose. It is provided "as is" without express or implied
13000 + * warranty of any kind.
13001 + */
13003 +/* This header file contains pretty much everything about all the */
13004 +/* Cryptoki function prototypes.  Because this information is */
13005 +/* used for more than just declaring function prototypes, the */
13006 +/* order of the functions appearing herein is important, and */
13007 +/* should not be altered. */
13009 +/* General-purpose */
13011 +/* C_Initialize initializes the Cryptoki library. */
13012 +CK_PKCS11_FUNCTION_INFO(C_Initialize)
13013 +#ifdef CK_NEED_ARG_LIST
13015 +  CK_VOID_PTR   pInitArgs  /* if this is not NULL_PTR, it gets
13016 +                            * cast to CK_C_INITIALIZE_ARGS_PTR
13017 +                            * and dereferenced */
13019 +#endif
13022 +/* C_Finalize indicates that an application is done with the
13023 + * Cryptoki library. */
13024 +CK_PKCS11_FUNCTION_INFO(C_Finalize)
13025 +#ifdef CK_NEED_ARG_LIST
13027 +  CK_VOID_PTR   pReserved  /* reserved.  Should be NULL_PTR */
13029 +#endif
13032 +/* C_GetInfo returns general information about Cryptoki. */
13033 +CK_PKCS11_FUNCTION_INFO(C_GetInfo)
13034 +#ifdef CK_NEED_ARG_LIST
13036 +  CK_INFO_PTR   pInfo  /* location that receives information */
13038 +#endif
13041 +/* C_GetFunctionList returns the function list. */
13042 +CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
13043 +#ifdef CK_NEED_ARG_LIST
13045 +  CK_FUNCTION_LIST_PTR_PTR ppFunctionList  /* receives pointer to
13046 +                                            * function list */
13048 +#endif
13052 +/* Slot and token management */
13054 +/* C_GetSlotList obtains a list of slots in the system. */
13055 +CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
13056 +#ifdef CK_NEED_ARG_LIST
13058 +  CK_BBOOL       tokenPresent,  /* only slots with tokens? */
13059 +  CK_SLOT_ID_PTR pSlotList,     /* receives array of slot IDs */
13060 +  CK_ULONG_PTR   pulCount       /* receives number of slots */
13062 +#endif
13065 +/* C_GetSlotInfo obtains information about a particular slot in
13066 + * the system. */
13067 +CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
13068 +#ifdef CK_NEED_ARG_LIST
13070 +  CK_SLOT_ID       slotID,  /* the ID of the slot */
13071 +  CK_SLOT_INFO_PTR pInfo    /* receives the slot information */
13073 +#endif
13076 +/* C_GetTokenInfo obtains information about a particular token
13077 + * in the system. */
13078 +CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
13079 +#ifdef CK_NEED_ARG_LIST
13081 +  CK_SLOT_ID        slotID,  /* ID of the token's slot */
13082 +  CK_TOKEN_INFO_PTR pInfo    /* receives the token information */
13084 +#endif
13087 +/* C_GetMechanismList obtains a list of mechanism types
13088 + * supported by a token. */
13089 +CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
13090 +#ifdef CK_NEED_ARG_LIST
13092 +  CK_SLOT_ID            slotID,          /* ID of token's slot */
13093 +  CK_MECHANISM_TYPE_PTR pMechanismList,  /* gets mech. array */
13094 +  CK_ULONG_PTR          pulCount         /* gets # of mechs. */
13096 +#endif
13099 +/* C_GetMechanismInfo obtains information about a particular
13100 + * mechanism possibly supported by a token. */
13101 +CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
13102 +#ifdef CK_NEED_ARG_LIST
13104 +  CK_SLOT_ID            slotID,  /* ID of the token's slot */
13105 +  CK_MECHANISM_TYPE     type,    /* type of mechanism */
13106 +  CK_MECHANISM_INFO_PTR pInfo    /* receives mechanism info */
13108 +#endif
13111 +/* C_InitToken initializes a token. */
13112 +CK_PKCS11_FUNCTION_INFO(C_InitToken)
13113 +#ifdef CK_NEED_ARG_LIST
13114 +/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
13116 +  CK_SLOT_ID      slotID,    /* ID of the token's slot */
13117 +  CK_UTF8CHAR_PTR pPin,      /* the SO's initial PIN */
13118 +  CK_ULONG        ulPinLen,  /* length in bytes of the PIN */
13119 +  CK_UTF8CHAR_PTR pLabel     /* 32-byte token label (blank padded) */
13121 +#endif
13124 +/* C_InitPIN initializes the normal user's PIN. */
13125 +CK_PKCS11_FUNCTION_INFO(C_InitPIN)
13126 +#ifdef CK_NEED_ARG_LIST
13128 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13129 +  CK_UTF8CHAR_PTR   pPin,      /* the normal user's PIN */
13130 +  CK_ULONG          ulPinLen   /* length in bytes of the PIN */
13132 +#endif
13135 +/* C_SetPIN modifies the PIN of the user who is logged in. */
13136 +CK_PKCS11_FUNCTION_INFO(C_SetPIN)
13137 +#ifdef CK_NEED_ARG_LIST
13139 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13140 +  CK_UTF8CHAR_PTR   pOldPin,   /* the old PIN */
13141 +  CK_ULONG          ulOldLen,  /* length of the old PIN */
13142 +  CK_UTF8CHAR_PTR   pNewPin,   /* the new PIN */
13143 +  CK_ULONG          ulNewLen   /* length of the new PIN */
13145 +#endif
13149 +/* Session management */
13151 +/* C_OpenSession opens a session between an application and a
13152 + * token. */
13153 +CK_PKCS11_FUNCTION_INFO(C_OpenSession)
13154 +#ifdef CK_NEED_ARG_LIST
13156 +  CK_SLOT_ID            slotID,        /* the slot's ID */
13157 +  CK_FLAGS              flags,         /* from CK_SESSION_INFO */
13158 +  CK_VOID_PTR           pApplication,  /* passed to callback */
13159 +  CK_NOTIFY             Notify,        /* callback function */
13160 +  CK_SESSION_HANDLE_PTR phSession      /* gets session handle */
13162 +#endif
13165 +/* C_CloseSession closes a session between an application and a
13166 + * token. */
13167 +CK_PKCS11_FUNCTION_INFO(C_CloseSession)
13168 +#ifdef CK_NEED_ARG_LIST
13170 +  CK_SESSION_HANDLE hSession  /* the session's handle */
13172 +#endif
13175 +/* C_CloseAllSessions closes all sessions with a token. */
13176 +CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
13177 +#ifdef CK_NEED_ARG_LIST
13179 +  CK_SLOT_ID     slotID  /* the token's slot */
13181 +#endif
13184 +/* C_GetSessionInfo obtains information about the session. */
13185 +CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
13186 +#ifdef CK_NEED_ARG_LIST
13188 +  CK_SESSION_HANDLE   hSession,  /* the session's handle */
13189 +  CK_SESSION_INFO_PTR pInfo      /* receives session info */
13191 +#endif
13194 +/* C_GetOperationState obtains the state of the cryptographic operation
13195 + * in a session. */
13196 +CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
13197 +#ifdef CK_NEED_ARG_LIST
13199 +  CK_SESSION_HANDLE hSession,             /* session's handle */
13200 +  CK_BYTE_PTR       pOperationState,      /* gets state */
13201 +  CK_ULONG_PTR      pulOperationStateLen  /* gets state length */
13203 +#endif
13206 +/* C_SetOperationState restores the state of the cryptographic
13207 + * operation in a session. */
13208 +CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
13209 +#ifdef CK_NEED_ARG_LIST
13211 +  CK_SESSION_HANDLE hSession,            /* session's handle */
13212 +  CK_BYTE_PTR      pOperationState,      /* holds state */
13213 +  CK_ULONG         ulOperationStateLen,  /* holds state length */
13214 +  CK_OBJECT_HANDLE hEncryptionKey,       /* en/decryption key */
13215 +  CK_OBJECT_HANDLE hAuthenticationKey    /* sign/verify key */
13217 +#endif
13220 +/* C_Login logs a user into a token. */
13221 +CK_PKCS11_FUNCTION_INFO(C_Login)
13222 +#ifdef CK_NEED_ARG_LIST
13224 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13225 +  CK_USER_TYPE      userType,  /* the user type */
13226 +  CK_UTF8CHAR_PTR   pPin,      /* the user's PIN */
13227 +  CK_ULONG          ulPinLen   /* the length of the PIN */
13229 +#endif
13232 +/* C_Logout logs a user out from a token. */
13233 +CK_PKCS11_FUNCTION_INFO(C_Logout)
13234 +#ifdef CK_NEED_ARG_LIST
13236 +  CK_SESSION_HANDLE hSession  /* the session's handle */
13238 +#endif
13242 +/* Object management */
13244 +/* C_CreateObject creates a new object. */
13245 +CK_PKCS11_FUNCTION_INFO(C_CreateObject)
13246 +#ifdef CK_NEED_ARG_LIST
13248 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
13249 +  CK_ATTRIBUTE_PTR  pTemplate,   /* the object's template */
13250 +  CK_ULONG          ulCount,     /* attributes in template */
13251 +  CK_OBJECT_HANDLE_PTR phObject  /* gets new object's handle. */
13253 +#endif
13256 +/* C_CopyObject copies an object, creating a new object for the
13257 + * copy. */
13258 +CK_PKCS11_FUNCTION_INFO(C_CopyObject)
13259 +#ifdef CK_NEED_ARG_LIST
13261 +  CK_SESSION_HANDLE    hSession,    /* the session's handle */
13262 +  CK_OBJECT_HANDLE     hObject,     /* the object's handle */
13263 +  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new object */
13264 +  CK_ULONG             ulCount,     /* attributes in template */
13265 +  CK_OBJECT_HANDLE_PTR phNewObject  /* receives handle of copy */
13267 +#endif
13270 +/* C_DestroyObject destroys an object. */
13271 +CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
13272 +#ifdef CK_NEED_ARG_LIST
13274 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13275 +  CK_OBJECT_HANDLE  hObject    /* the object's handle */
13277 +#endif
13280 +/* C_GetObjectSize gets the size of an object in bytes. */
13281 +CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
13282 +#ifdef CK_NEED_ARG_LIST
13284 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13285 +  CK_OBJECT_HANDLE  hObject,   /* the object's handle */
13286 +  CK_ULONG_PTR      pulSize    /* receives size of object */
13288 +#endif
13291 +/* C_GetAttributeValue obtains the value of one or more object
13292 + * attributes. */
13293 +CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
13294 +#ifdef CK_NEED_ARG_LIST
13296 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
13297 +  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
13298 +  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs; gets vals */
13299 +  CK_ULONG          ulCount     /* attributes in template */
13301 +#endif
13304 +/* C_SetAttributeValue modifies the value of one or more object
13305 + * attributes */
13306 +CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
13307 +#ifdef CK_NEED_ARG_LIST
13309 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
13310 +  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
13311 +  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs and values */
13312 +  CK_ULONG          ulCount     /* attributes in template */
13314 +#endif
13317 +/* C_FindObjectsInit initializes a search for token and session
13318 + * objects that match a template. */
13319 +CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
13320 +#ifdef CK_NEED_ARG_LIST
13322 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
13323 +  CK_ATTRIBUTE_PTR  pTemplate,  /* attribute values to match */
13324 +  CK_ULONG          ulCount     /* attrs in search template */
13326 +#endif
13329 +/* C_FindObjects continues a search for token and session
13330 + * objects that match a template, obtaining additional object
13331 + * handles. */
13332 +CK_PKCS11_FUNCTION_INFO(C_FindObjects)
13333 +#ifdef CK_NEED_ARG_LIST
13335 + CK_SESSION_HANDLE    hSession,          /* session's handle */
13336 + CK_OBJECT_HANDLE_PTR phObject,          /* gets obj. handles */
13337 + CK_ULONG             ulMaxObjectCount,  /* max handles to get */
13338 + CK_ULONG_PTR         pulObjectCount     /* actual # returned */
13340 +#endif
13343 +/* C_FindObjectsFinal finishes a search for token and session
13344 + * objects. */
13345 +CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
13346 +#ifdef CK_NEED_ARG_LIST
13348 +  CK_SESSION_HANDLE hSession  /* the session's handle */
13350 +#endif
13354 +/* Encryption and decryption */
13356 +/* C_EncryptInit initializes an encryption operation. */
13357 +CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
13358 +#ifdef CK_NEED_ARG_LIST
13360 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
13361 +  CK_MECHANISM_PTR  pMechanism,  /* the encryption mechanism */
13362 +  CK_OBJECT_HANDLE  hKey         /* handle of encryption key */
13364 +#endif
13367 +/* C_Encrypt encrypts single-part data. */
13368 +CK_PKCS11_FUNCTION_INFO(C_Encrypt)
13369 +#ifdef CK_NEED_ARG_LIST
13371 +  CK_SESSION_HANDLE hSession,            /* session's handle */
13372 +  CK_BYTE_PTR       pData,               /* the plaintext data */
13373 +  CK_ULONG          ulDataLen,           /* bytes of plaintext */
13374 +  CK_BYTE_PTR       pEncryptedData,      /* gets ciphertext */
13375 +  CK_ULONG_PTR      pulEncryptedDataLen  /* gets c-text size */
13377 +#endif
13380 +/* C_EncryptUpdate continues a multiple-part encryption
13381 + * operation. */
13382 +CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
13383 +#ifdef CK_NEED_ARG_LIST
13385 +  CK_SESSION_HANDLE hSession,           /* session's handle */
13386 +  CK_BYTE_PTR       pPart,              /* the plaintext data */
13387 +  CK_ULONG          ulPartLen,          /* plaintext data len */
13388 +  CK_BYTE_PTR       pEncryptedPart,     /* gets ciphertext */
13389 +  CK_ULONG_PTR      pulEncryptedPartLen /* gets c-text size */
13391 +#endif
13394 +/* C_EncryptFinal finishes a multiple-part encryption
13395 + * operation. */
13396 +CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
13397 +#ifdef CK_NEED_ARG_LIST
13399 +  CK_SESSION_HANDLE hSession,                /* session handle */
13400 +  CK_BYTE_PTR       pLastEncryptedPart,      /* last c-text */
13401 +  CK_ULONG_PTR      pulLastEncryptedPartLen  /* gets last size */
13403 +#endif
13406 +/* C_DecryptInit initializes a decryption operation. */
13407 +CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
13408 +#ifdef CK_NEED_ARG_LIST
13410 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
13411 +  CK_MECHANISM_PTR  pMechanism,  /* the decryption mechanism */
13412 +  CK_OBJECT_HANDLE  hKey         /* handle of decryption key */
13414 +#endif
13417 +/* C_Decrypt decrypts encrypted data in a single part. */
13418 +CK_PKCS11_FUNCTION_INFO(C_Decrypt)
13419 +#ifdef CK_NEED_ARG_LIST
13421 +  CK_SESSION_HANDLE hSession,           /* session's handle */
13422 +  CK_BYTE_PTR       pEncryptedData,     /* ciphertext */
13423 +  CK_ULONG          ulEncryptedDataLen, /* ciphertext length */
13424 +  CK_BYTE_PTR       pData,              /* gets plaintext */
13425 +  CK_ULONG_PTR      pulDataLen          /* gets p-text size */
13427 +#endif
13430 +/* C_DecryptUpdate continues a multiple-part decryption
13431 + * operation. */
13432 +CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
13433 +#ifdef CK_NEED_ARG_LIST
13435 +  CK_SESSION_HANDLE hSession,            /* session's handle */
13436 +  CK_BYTE_PTR       pEncryptedPart,      /* encrypted data */
13437 +  CK_ULONG          ulEncryptedPartLen,  /* input length */
13438 +  CK_BYTE_PTR       pPart,               /* gets plaintext */
13439 +  CK_ULONG_PTR      pulPartLen           /* p-text size */
13441 +#endif
13444 +/* C_DecryptFinal finishes a multiple-part decryption
13445 + * operation. */
13446 +CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
13447 +#ifdef CK_NEED_ARG_LIST
13449 +  CK_SESSION_HANDLE hSession,       /* the session's handle */
13450 +  CK_BYTE_PTR       pLastPart,      /* gets plaintext */
13451 +  CK_ULONG_PTR      pulLastPartLen  /* p-text size */
13453 +#endif
13457 +/* Message digesting */
13459 +/* C_DigestInit initializes a message-digesting operation. */
13460 +CK_PKCS11_FUNCTION_INFO(C_DigestInit)
13461 +#ifdef CK_NEED_ARG_LIST
13463 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
13464 +  CK_MECHANISM_PTR  pMechanism  /* the digesting mechanism */
13466 +#endif
13469 +/* C_Digest digests data in a single part. */
13470 +CK_PKCS11_FUNCTION_INFO(C_Digest)
13471 +#ifdef CK_NEED_ARG_LIST
13473 +  CK_SESSION_HANDLE hSession,     /* the session's handle */
13474 +  CK_BYTE_PTR       pData,        /* data to be digested */
13475 +  CK_ULONG          ulDataLen,    /* bytes of data to digest */
13476 +  CK_BYTE_PTR       pDigest,      /* gets the message digest */
13477 +  CK_ULONG_PTR      pulDigestLen  /* gets digest length */
13479 +#endif
13482 +/* C_DigestUpdate continues a multiple-part message-digesting
13483 + * operation. */
13484 +CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
13485 +#ifdef CK_NEED_ARG_LIST
13487 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13488 +  CK_BYTE_PTR       pPart,     /* data to be digested */
13489 +  CK_ULONG          ulPartLen  /* bytes of data to be digested */
13491 +#endif
13494 +/* C_DigestKey continues a multi-part message-digesting
13495 + * operation, by digesting the value of a secret key as part of
13496 + * the data already digested. */
13497 +CK_PKCS11_FUNCTION_INFO(C_DigestKey)
13498 +#ifdef CK_NEED_ARG_LIST
13500 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13501 +  CK_OBJECT_HANDLE  hKey       /* secret key to digest */
13503 +#endif
13506 +/* C_DigestFinal finishes a multiple-part message-digesting
13507 + * operation. */
13508 +CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
13509 +#ifdef CK_NEED_ARG_LIST
13511 +  CK_SESSION_HANDLE hSession,     /* the session's handle */
13512 +  CK_BYTE_PTR       pDigest,      /* gets the message digest */
13513 +  CK_ULONG_PTR      pulDigestLen  /* gets byte count of digest */
13515 +#endif
13519 +/* Signing and MACing */
13521 +/* C_SignInit initializes a signature (private key encryption)
13522 + * operation, where the signature is (will be) an appendix to
13523 + * the data, and plaintext cannot be recovered from the
13524 + *signature. */
13525 +CK_PKCS11_FUNCTION_INFO(C_SignInit)
13526 +#ifdef CK_NEED_ARG_LIST
13528 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
13529 +  CK_MECHANISM_PTR  pMechanism,  /* the signature mechanism */
13530 +  CK_OBJECT_HANDLE  hKey         /* handle of signature key */
13532 +#endif
13535 +/* C_Sign signs (encrypts with private key) data in a single
13536 + * part, where the signature is (will be) an appendix to the
13537 + * data, and plaintext cannot be recovered from the signature. */
13538 +CK_PKCS11_FUNCTION_INFO(C_Sign)
13539 +#ifdef CK_NEED_ARG_LIST
13541 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
13542 +  CK_BYTE_PTR       pData,           /* the data to sign */
13543 +  CK_ULONG          ulDataLen,       /* count of bytes to sign */
13544 +  CK_BYTE_PTR       pSignature,      /* gets the signature */
13545 +  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
13547 +#endif
13550 +/* C_SignUpdate continues a multiple-part signature operation,
13551 + * where the signature is (will be) an appendix to the data, 
13552 + * and plaintext cannot be recovered from the signature. */
13553 +CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
13554 +#ifdef CK_NEED_ARG_LIST
13556 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13557 +  CK_BYTE_PTR       pPart,     /* the data to sign */
13558 +  CK_ULONG          ulPartLen  /* count of bytes to sign */
13560 +#endif
13563 +/* C_SignFinal finishes a multiple-part signature operation, 
13564 + * returning the signature. */
13565 +CK_PKCS11_FUNCTION_INFO(C_SignFinal)
13566 +#ifdef CK_NEED_ARG_LIST
13568 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
13569 +  CK_BYTE_PTR       pSignature,      /* gets the signature */
13570 +  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
13572 +#endif
13575 +/* C_SignRecoverInit initializes a signature operation, where
13576 + * the data can be recovered from the signature. */
13577 +CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
13578 +#ifdef CK_NEED_ARG_LIST
13580 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
13581 +  CK_MECHANISM_PTR  pMechanism, /* the signature mechanism */
13582 +  CK_OBJECT_HANDLE  hKey        /* handle of the signature key */
13584 +#endif
13587 +/* C_SignRecover signs data in a single operation, where the
13588 + * data can be recovered from the signature. */
13589 +CK_PKCS11_FUNCTION_INFO(C_SignRecover)
13590 +#ifdef CK_NEED_ARG_LIST
13592 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
13593 +  CK_BYTE_PTR       pData,           /* the data to sign */
13594 +  CK_ULONG          ulDataLen,       /* count of bytes to sign */
13595 +  CK_BYTE_PTR       pSignature,      /* gets the signature */
13596 +  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
13598 +#endif
13602 +/* Verifying signatures and MACs */
13604 +/* C_VerifyInit initializes a verification operation, where the
13605 + * signature is an appendix to the data, and plaintext cannot
13606 + *  cannot be recovered from the signature (e.g. DSA). */
13607 +CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
13608 +#ifdef CK_NEED_ARG_LIST
13610 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
13611 +  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
13612 +  CK_OBJECT_HANDLE  hKey         /* verification key */ 
13614 +#endif
13617 +/* C_Verify verifies a signature in a single-part operation, 
13618 + * where the signature is an appendix to the data, and plaintext
13619 + * cannot be recovered from the signature. */
13620 +CK_PKCS11_FUNCTION_INFO(C_Verify)
13621 +#ifdef CK_NEED_ARG_LIST
13623 +  CK_SESSION_HANDLE hSession,       /* the session's handle */
13624 +  CK_BYTE_PTR       pData,          /* signed data */
13625 +  CK_ULONG          ulDataLen,      /* length of signed data */
13626 +  CK_BYTE_PTR       pSignature,     /* signature */
13627 +  CK_ULONG          ulSignatureLen  /* signature length*/
13629 +#endif
13632 +/* C_VerifyUpdate continues a multiple-part verification
13633 + * operation, where the signature is an appendix to the data, 
13634 + * and plaintext cannot be recovered from the signature. */
13635 +CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
13636 +#ifdef CK_NEED_ARG_LIST
13638 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13639 +  CK_BYTE_PTR       pPart,     /* signed data */
13640 +  CK_ULONG          ulPartLen  /* length of signed data */
13642 +#endif
13645 +/* C_VerifyFinal finishes a multiple-part verification
13646 + * operation, checking the signature. */
13647 +CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
13648 +#ifdef CK_NEED_ARG_LIST
13650 +  CK_SESSION_HANDLE hSession,       /* the session's handle */
13651 +  CK_BYTE_PTR       pSignature,     /* signature to verify */
13652 +  CK_ULONG          ulSignatureLen  /* signature length */
13654 +#endif
13657 +/* C_VerifyRecoverInit initializes a signature verification
13658 + * operation, where the data is recovered from the signature. */
13659 +CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
13660 +#ifdef CK_NEED_ARG_LIST
13662 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
13663 +  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
13664 +  CK_OBJECT_HANDLE  hKey         /* verification key */
13666 +#endif
13669 +/* C_VerifyRecover verifies a signature in a single-part
13670 + * operation, where the data is recovered from the signature. */
13671 +CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
13672 +#ifdef CK_NEED_ARG_LIST
13674 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
13675 +  CK_BYTE_PTR       pSignature,      /* signature to verify */
13676 +  CK_ULONG          ulSignatureLen,  /* signature length */
13677 +  CK_BYTE_PTR       pData,           /* gets signed data */
13678 +  CK_ULONG_PTR      pulDataLen       /* gets signed data len */
13680 +#endif
13684 +/* Dual-function cryptographic operations */
13686 +/* C_DigestEncryptUpdate continues a multiple-part digesting
13687 + * and encryption operation. */
13688 +CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
13689 +#ifdef CK_NEED_ARG_LIST
13691 +  CK_SESSION_HANDLE hSession,            /* session's handle */
13692 +  CK_BYTE_PTR       pPart,               /* the plaintext data */
13693 +  CK_ULONG          ulPartLen,           /* plaintext length */
13694 +  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
13695 +  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
13697 +#endif
13700 +/* C_DecryptDigestUpdate continues a multiple-part decryption and
13701 + * digesting operation. */
13702 +CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
13703 +#ifdef CK_NEED_ARG_LIST
13705 +  CK_SESSION_HANDLE hSession,            /* session's handle */
13706 +  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
13707 +  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
13708 +  CK_BYTE_PTR       pPart,               /* gets plaintext */
13709 +  CK_ULONG_PTR      pulPartLen           /* gets plaintext len */
13711 +#endif
13714 +/* C_SignEncryptUpdate continues a multiple-part signing and
13715 + * encryption operation. */
13716 +CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
13717 +#ifdef CK_NEED_ARG_LIST
13719 +  CK_SESSION_HANDLE hSession,            /* session's handle */
13720 +  CK_BYTE_PTR       pPart,               /* the plaintext data */
13721 +  CK_ULONG          ulPartLen,           /* plaintext length */
13722 +  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
13723 +  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
13725 +#endif
13728 +/* C_DecryptVerifyUpdate continues a multiple-part decryption and
13729 + * verify operation. */
13730 +CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
13731 +#ifdef CK_NEED_ARG_LIST
13733 +  CK_SESSION_HANDLE hSession,            /* session's handle */
13734 +  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
13735 +  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
13736 +  CK_BYTE_PTR       pPart,               /* gets plaintext */
13737 +  CK_ULONG_PTR      pulPartLen           /* gets p-text length */
13739 +#endif
13743 +/* Key management */
13745 +/* C_GenerateKey generates a secret key, creating a new key
13746 + * object. */
13747 +CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
13748 +#ifdef CK_NEED_ARG_LIST
13750 +  CK_SESSION_HANDLE    hSession,    /* the session's handle */
13751 +  CK_MECHANISM_PTR     pMechanism,  /* key generation mech. */
13752 +  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new key */
13753 +  CK_ULONG             ulCount,     /* # of attrs in template */
13754 +  CK_OBJECT_HANDLE_PTR phKey        /* gets handle of new key */
13756 +#endif
13759 +/* C_GenerateKeyPair generates a public-key/private-key pair, 
13760 + * creating new key objects. */
13761 +CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
13762 +#ifdef CK_NEED_ARG_LIST
13764 +  CK_SESSION_HANDLE    hSession,                    /* session
13765 +                                                     * handle */
13766 +  CK_MECHANISM_PTR     pMechanism,                  /* key-gen
13767 +                                                     * mech. */
13768 +  CK_ATTRIBUTE_PTR     pPublicKeyTemplate,          /* template
13769 +                                                     * for pub.
13770 +                                                     * key */
13771 +  CK_ULONG             ulPublicKeyAttributeCount,   /* # pub.
13772 +                                                     * attrs. */
13773 +  CK_ATTRIBUTE_PTR     pPrivateKeyTemplate,         /* template
13774 +                                                     * for priv.
13775 +                                                     * key */
13776 +  CK_ULONG             ulPrivateKeyAttributeCount,  /* # priv.
13777 +                                                     * attrs. */
13778 +  CK_OBJECT_HANDLE_PTR phPublicKey,                 /* gets pub.
13779 +                                                     * key
13780 +                                                     * handle */
13781 +  CK_OBJECT_HANDLE_PTR phPrivateKey                 /* gets
13782 +                                                     * priv. key
13783 +                                                     * handle */
13785 +#endif
13788 +/* C_WrapKey wraps (i.e., encrypts) a key. */
13789 +CK_PKCS11_FUNCTION_INFO(C_WrapKey)
13790 +#ifdef CK_NEED_ARG_LIST
13792 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
13793 +  CK_MECHANISM_PTR  pMechanism,      /* the wrapping mechanism */
13794 +  CK_OBJECT_HANDLE  hWrappingKey,    /* wrapping key */
13795 +  CK_OBJECT_HANDLE  hKey,            /* key to be wrapped */
13796 +  CK_BYTE_PTR       pWrappedKey,     /* gets wrapped key */
13797 +  CK_ULONG_PTR      pulWrappedKeyLen /* gets wrapped key size */
13799 +#endif
13802 +/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
13803 + * key object. */
13804 +CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
13805 +#ifdef CK_NEED_ARG_LIST
13807 +  CK_SESSION_HANDLE    hSession,          /* session's handle */
13808 +  CK_MECHANISM_PTR     pMechanism,        /* unwrapping mech. */
13809 +  CK_OBJECT_HANDLE     hUnwrappingKey,    /* unwrapping key */
13810 +  CK_BYTE_PTR          pWrappedKey,       /* the wrapped key */
13811 +  CK_ULONG             ulWrappedKeyLen,   /* wrapped key len */
13812 +  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
13813 +  CK_ULONG             ulAttributeCount,  /* template length */
13814 +  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
13816 +#endif
13819 +/* C_DeriveKey derives a key from a base key, creating a new key
13820 + * object. */
13821 +CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
13822 +#ifdef CK_NEED_ARG_LIST
13824 +  CK_SESSION_HANDLE    hSession,          /* session's handle */
13825 +  CK_MECHANISM_PTR     pMechanism,        /* key deriv. mech. */
13826 +  CK_OBJECT_HANDLE     hBaseKey,          /* base key */
13827 +  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
13828 +  CK_ULONG             ulAttributeCount,  /* template length */
13829 +  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
13831 +#endif
13835 +/* Random number generation */
13837 +/* C_SeedRandom mixes additional seed material into the token's
13838 + * random number generator. */
13839 +CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
13840 +#ifdef CK_NEED_ARG_LIST
13842 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13843 +  CK_BYTE_PTR       pSeed,     /* the seed material */
13844 +  CK_ULONG          ulSeedLen  /* length of seed material */
13846 +#endif
13849 +/* C_GenerateRandom generates random data. */
13850 +CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
13851 +#ifdef CK_NEED_ARG_LIST
13853 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
13854 +  CK_BYTE_PTR       RandomData,  /* receives the random data */
13855 +  CK_ULONG          ulRandomLen  /* # of bytes to generate */
13857 +#endif
13861 +/* Parallel function management */
13863 +/* C_GetFunctionStatus is a legacy function; it obtains an
13864 + * updated status of a function running in parallel with an
13865 + * application. */
13866 +CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
13867 +#ifdef CK_NEED_ARG_LIST
13869 +  CK_SESSION_HANDLE hSession  /* the session's handle */
13871 +#endif
13874 +/* C_CancelFunction is a legacy function; it cancels a function
13875 + * running in parallel. */
13876 +CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
13877 +#ifdef CK_NEED_ARG_LIST
13879 +  CK_SESSION_HANDLE hSession  /* the session's handle */
13881 +#endif
13885 +/* Functions added in for Cryptoki Version 2.01 or later */
13887 +/* C_WaitForSlotEvent waits for a slot event (token insertion,
13888 + * removal, etc.) to occur. */
13889 +CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
13890 +#ifdef CK_NEED_ARG_LIST
13892 +  CK_FLAGS flags,        /* blocking/nonblocking flag */
13893 +  CK_SLOT_ID_PTR pSlot,  /* location that receives the slot ID */
13894 +  CK_VOID_PTR pRserved   /* reserved.  Should be NULL_PTR */
13896 +#endif
13897 Index: openssl/crypto/engine/pkcs11t.h
13898 diff -u /dev/null openssl/crypto/engine/pkcs11t.h:1.2
13899 --- /dev/null   Fri Jan  2 14:26:17 2015
13900 +++ openssl/crypto/engine/pkcs11t.h     Sat Aug 30 11:58:07 2008
13901 @@ -0,0 +1,1885 @@
13902 +/* pkcs11t.h include file for PKCS #11. */
13903 +/* Revision: 1.2  */
13905 +/* License to copy and use this software is granted provided that it is
13906 + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
13907 + * (Cryptoki)" in all material mentioning or referencing this software.
13909 + * License is also granted to make and use derivative works provided that
13910 + * such works are identified as "derived from the RSA Security Inc. PKCS #11
13911 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
13912 + * referencing the derived work.
13914 + * RSA Security Inc. makes no representations concerning either the
13915 + * merchantability of this software or the suitability of this software for
13916 + * any particular purpose. It is provided "as is" without express or implied
13917 + * warranty of any kind.
13918 + */
13920 +/* See top of pkcs11.h for information about the macros that
13921 + * must be defined and the structure-packing conventions that
13922 + * must be set before including this file. */
13924 +#ifndef _PKCS11T_H_
13925 +#define _PKCS11T_H_ 1
13927 +#define CRYPTOKI_VERSION_MAJOR 2
13928 +#define CRYPTOKI_VERSION_MINOR 20
13929 +#define CRYPTOKI_VERSION_AMENDMENT 3
13931 +#define CK_TRUE 1
13932 +#define CK_FALSE 0
13934 +#ifndef CK_DISABLE_TRUE_FALSE
13935 +#ifndef FALSE
13936 +#define FALSE CK_FALSE
13937 +#endif
13939 +#ifndef TRUE
13940 +#define TRUE CK_TRUE
13941 +#endif
13942 +#endif
13944 +/* an unsigned 8-bit value */
13945 +typedef unsigned char     CK_BYTE;
13947 +/* an unsigned 8-bit character */
13948 +typedef CK_BYTE           CK_CHAR;
13950 +/* an 8-bit UTF-8 character */
13951 +typedef CK_BYTE           CK_UTF8CHAR;
13953 +/* a BYTE-sized Boolean flag */
13954 +typedef CK_BYTE           CK_BBOOL;
13956 +/* an unsigned value, at least 32 bits long */
13957 +typedef unsigned long int CK_ULONG;
13959 +/* a signed value, the same size as a CK_ULONG */
13960 +/* CK_LONG is new for v2.0 */
13961 +typedef long int          CK_LONG;
13963 +/* at least 32 bits; each bit is a Boolean flag */
13964 +typedef CK_ULONG          CK_FLAGS;
13967 +/* some special values for certain CK_ULONG variables */
13968 +#define CK_UNAVAILABLE_INFORMATION (~0UL)
13969 +#define CK_EFFECTIVELY_INFINITE    0
13972 +typedef CK_BYTE     CK_PTR   CK_BYTE_PTR;
13973 +typedef CK_CHAR     CK_PTR   CK_CHAR_PTR;
13974 +typedef CK_UTF8CHAR CK_PTR   CK_UTF8CHAR_PTR;
13975 +typedef CK_ULONG    CK_PTR   CK_ULONG_PTR;
13976 +typedef void        CK_PTR   CK_VOID_PTR;
13978 +/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
13979 +typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
13982 +/* The following value is always invalid if used as a session */
13983 +/* handle or object handle */
13984 +#define CK_INVALID_HANDLE 0
13987 +typedef struct CK_VERSION {
13988 +  CK_BYTE       major;  /* integer portion of version number */
13989 +  CK_BYTE       minor;  /* 1/100ths portion of version number */
13990 +} CK_VERSION;
13992 +typedef CK_VERSION CK_PTR CK_VERSION_PTR;
13995 +typedef struct CK_INFO {
13996 +  /* manufacturerID and libraryDecription have been changed from
13997 +   * CK_CHAR to CK_UTF8CHAR for v2.10 */
13998 +  CK_VERSION    cryptokiVersion;     /* Cryptoki interface ver */
13999 +  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
14000 +  CK_FLAGS      flags;               /* must be zero */
14002 +  /* libraryDescription and libraryVersion are new for v2.0 */
14003 +  CK_UTF8CHAR   libraryDescription[32];  /* blank padded */
14004 +  CK_VERSION    libraryVersion;          /* version of library */
14005 +} CK_INFO;
14007 +typedef CK_INFO CK_PTR    CK_INFO_PTR;
14010 +/* CK_NOTIFICATION enumerates the types of notifications that
14011 + * Cryptoki provides to an application */
14012 +/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
14013 + * for v2.0 */
14014 +typedef CK_ULONG CK_NOTIFICATION;
14015 +#define CKN_SURRENDER       0
14017 +/* The following notification is new for PKCS #11 v2.20 amendment 3 */
14018 +#define CKN_OTP_CHANGED     1
14021 +typedef CK_ULONG          CK_SLOT_ID;
14023 +typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
14026 +/* CK_SLOT_INFO provides information about a slot */
14027 +typedef struct CK_SLOT_INFO {
14028 +  /* slotDescription and manufacturerID have been changed from
14029 +   * CK_CHAR to CK_UTF8CHAR for v2.10 */
14030 +  CK_UTF8CHAR   slotDescription[64];  /* blank padded */
14031 +  CK_UTF8CHAR   manufacturerID[32];   /* blank padded */
14032 +  CK_FLAGS      flags;
14034 +  /* hardwareVersion and firmwareVersion are new for v2.0 */
14035 +  CK_VERSION    hardwareVersion;  /* version of hardware */
14036 +  CK_VERSION    firmwareVersion;  /* version of firmware */
14037 +} CK_SLOT_INFO;
14039 +/* flags: bit flags that provide capabilities of the slot
14040 + *      Bit Flag              Mask        Meaning
14041 + */
14042 +#define CKF_TOKEN_PRESENT     0x00000001  /* a token is there */
14043 +#define CKF_REMOVABLE_DEVICE  0x00000002  /* removable devices*/
14044 +#define CKF_HW_SLOT           0x00000004  /* hardware slot */
14046 +typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
14049 +/* CK_TOKEN_INFO provides information about a token */
14050 +typedef struct CK_TOKEN_INFO {
14051 +  /* label, manufacturerID, and model have been changed from
14052 +   * CK_CHAR to CK_UTF8CHAR for v2.10 */
14053 +  CK_UTF8CHAR   label[32];           /* blank padded */
14054 +  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
14055 +  CK_UTF8CHAR   model[16];           /* blank padded */
14056 +  CK_CHAR       serialNumber[16];    /* blank padded */
14057 +  CK_FLAGS      flags;               /* see below */
14059 +  /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
14060 +   * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
14061 +   * changed from CK_USHORT to CK_ULONG for v2.0 */
14062 +  CK_ULONG      ulMaxSessionCount;     /* max open sessions */
14063 +  CK_ULONG      ulSessionCount;        /* sess. now open */
14064 +  CK_ULONG      ulMaxRwSessionCount;   /* max R/W sessions */
14065 +  CK_ULONG      ulRwSessionCount;      /* R/W sess. now open */
14066 +  CK_ULONG      ulMaxPinLen;           /* in bytes */
14067 +  CK_ULONG      ulMinPinLen;           /* in bytes */
14068 +  CK_ULONG      ulTotalPublicMemory;   /* in bytes */
14069 +  CK_ULONG      ulFreePublicMemory;    /* in bytes */
14070 +  CK_ULONG      ulTotalPrivateMemory;  /* in bytes */
14071 +  CK_ULONG      ulFreePrivateMemory;   /* in bytes */
14073 +  /* hardwareVersion, firmwareVersion, and time are new for
14074 +   * v2.0 */
14075 +  CK_VERSION    hardwareVersion;       /* version of hardware */
14076 +  CK_VERSION    firmwareVersion;       /* version of firmware */
14077 +  CK_CHAR       utcTime[16];           /* time */
14078 +} CK_TOKEN_INFO;
14080 +/* The flags parameter is defined as follows:
14081 + *      Bit Flag                    Mask        Meaning
14082 + */
14083 +#define CKF_RNG                     0x00000001  /* has random #
14084 +                                                 * generator */
14085 +#define CKF_WRITE_PROTECTED         0x00000002  /* token is
14086 +                                                 * write-
14087 +                                                 * protected */
14088 +#define CKF_LOGIN_REQUIRED          0x00000004  /* user must
14089 +                                                 * login */
14090 +#define CKF_USER_PIN_INITIALIZED    0x00000008  /* normal user's
14091 +                                                 * PIN is set */
14093 +/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0.  If it is set,
14094 + * that means that *every* time the state of cryptographic
14095 + * operations of a session is successfully saved, all keys
14096 + * needed to continue those operations are stored in the state */
14097 +#define CKF_RESTORE_KEY_NOT_NEEDED  0x00000020
14099 +/* CKF_CLOCK_ON_TOKEN is new for v2.0.  If it is set, that means
14100 + * that the token has some sort of clock.  The time on that
14101 + * clock is returned in the token info structure */
14102 +#define CKF_CLOCK_ON_TOKEN          0x00000040
14104 +/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0.  If it is
14105 + * set, that means that there is some way for the user to login
14106 + * without sending a PIN through the Cryptoki library itself */
14107 +#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
14109 +/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0.  If it is true,
14110 + * that means that a single session with the token can perform
14111 + * dual simultaneous cryptographic operations (digest and
14112 + * encrypt; decrypt and digest; sign and encrypt; and decrypt
14113 + * and sign) */
14114 +#define CKF_DUAL_CRYPTO_OPERATIONS  0x00000200
14116 +/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
14117 + * token has been initialized using C_InitializeToken or an
14118 + * equivalent mechanism outside the scope of PKCS #11.
14119 + * Calling C_InitializeToken when this flag is set will cause
14120 + * the token to be reinitialized. */
14121 +#define CKF_TOKEN_INITIALIZED       0x00000400
14123 +/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
14124 + * true, the token supports secondary authentication for
14125 + * private key objects. This flag is deprecated in v2.11 and
14126 +   onwards. */
14127 +#define CKF_SECONDARY_AUTHENTICATION  0x00000800
14129 +/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
14130 + * incorrect user login PIN has been entered at least once
14131 + * since the last successful authentication. */
14132 +#define CKF_USER_PIN_COUNT_LOW       0x00010000
14134 +/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
14135 + * supplying an incorrect user PIN will it to become locked. */
14136 +#define CKF_USER_PIN_FINAL_TRY       0x00020000
14138 +/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
14139 + * user PIN has been locked. User login to the token is not
14140 + * possible. */
14141 +#define CKF_USER_PIN_LOCKED          0x00040000
14143 +/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
14144 + * the user PIN value is the default value set by token
14145 + * initialization or manufacturing, or the PIN has been
14146 + * expired by the card. */
14147 +#define CKF_USER_PIN_TO_BE_CHANGED   0x00080000
14149 +/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
14150 + * incorrect SO login PIN has been entered at least once since
14151 + * the last successful authentication. */
14152 +#define CKF_SO_PIN_COUNT_LOW         0x00100000
14154 +/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
14155 + * supplying an incorrect SO PIN will it to become locked. */
14156 +#define CKF_SO_PIN_FINAL_TRY         0x00200000
14158 +/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
14159 + * PIN has been locked. SO login to the token is not possible.
14160 + */
14161 +#define CKF_SO_PIN_LOCKED            0x00400000
14163 +/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
14164 + * the SO PIN value is the default value set by token
14165 + * initialization or manufacturing, or the PIN has been
14166 + * expired by the card. */
14167 +#define CKF_SO_PIN_TO_BE_CHANGED     0x00800000
14169 +typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
14172 +/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
14173 + * identifies a session */
14174 +typedef CK_ULONG          CK_SESSION_HANDLE;
14176 +typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
14179 +/* CK_USER_TYPE enumerates the types of Cryptoki users */
14180 +/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
14181 + * v2.0 */
14182 +typedef CK_ULONG          CK_USER_TYPE;
14183 +/* Security Officer */
14184 +#define CKU_SO    0
14185 +/* Normal user */
14186 +#define CKU_USER  1
14187 +/* Context specific (added in v2.20) */
14188 +#define CKU_CONTEXT_SPECIFIC   2
14190 +/* CK_STATE enumerates the session states */
14191 +/* CK_STATE has been changed from an enum to a CK_ULONG for
14192 + * v2.0 */
14193 +typedef CK_ULONG          CK_STATE;
14194 +#define CKS_RO_PUBLIC_SESSION  0
14195 +#define CKS_RO_USER_FUNCTIONS  1
14196 +#define CKS_RW_PUBLIC_SESSION  2
14197 +#define CKS_RW_USER_FUNCTIONS  3
14198 +#define CKS_RW_SO_FUNCTIONS    4
14201 +/* CK_SESSION_INFO provides information about a session */
14202 +typedef struct CK_SESSION_INFO {
14203 +  CK_SLOT_ID    slotID;
14204 +  CK_STATE      state;
14205 +  CK_FLAGS      flags;          /* see below */
14207 +  /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
14208 +   * v2.0 */
14209 +  CK_ULONG      ulDeviceError;  /* device-dependent error code */
14210 +} CK_SESSION_INFO;
14212 +/* The flags are defined in the following table:
14213 + *      Bit Flag                Mask        Meaning
14214 + */
14215 +#define CKF_RW_SESSION          0x00000002  /* session is r/w */
14216 +#define CKF_SERIAL_SESSION      0x00000004  /* no parallel */
14218 +typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
14221 +/* CK_OBJECT_HANDLE is a token-specific identifier for an
14222 + * object  */
14223 +typedef CK_ULONG          CK_OBJECT_HANDLE;
14225 +typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
14228 +/* CK_OBJECT_CLASS is a value that identifies the classes (or
14229 + * types) of objects that Cryptoki recognizes.  It is defined
14230 + * as follows: */
14231 +/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
14232 + * v2.0 */
14233 +typedef CK_ULONG          CK_OBJECT_CLASS;
14235 +/* The following classes of objects are defined: */
14236 +/* CKO_HW_FEATURE is new for v2.10 */
14237 +/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
14238 +/* CKO_MECHANISM is new for v2.20 */
14239 +#define CKO_DATA              0x00000000
14240 +#define CKO_CERTIFICATE       0x00000001
14241 +#define CKO_PUBLIC_KEY        0x00000002
14242 +#define CKO_PRIVATE_KEY       0x00000003
14243 +#define CKO_SECRET_KEY        0x00000004
14244 +#define CKO_HW_FEATURE        0x00000005
14245 +#define CKO_DOMAIN_PARAMETERS 0x00000006
14246 +#define CKO_MECHANISM         0x00000007
14248 +/* CKO_OTP_KEY is new for PKCS #11 v2.20 amendment 1 */
14249 +#define CKO_OTP_KEY           0x00000008
14251 +#define CKO_VENDOR_DEFINED    0x80000000
14253 +typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
14255 +/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
14256 + * value that identifies the hardware feature type of an object
14257 + * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
14258 +typedef CK_ULONG          CK_HW_FEATURE_TYPE;
14260 +/* The following hardware feature types are defined */
14261 +/* CKH_USER_INTERFACE is new for v2.20 */
14262 +#define CKH_MONOTONIC_COUNTER  0x00000001
14263 +#define CKH_CLOCK           0x00000002
14264 +#define CKH_USER_INTERFACE  0x00000003
14265 +#define CKH_VENDOR_DEFINED  0x80000000
14267 +/* CK_KEY_TYPE is a value that identifies a key type */
14268 +/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
14269 +typedef CK_ULONG          CK_KEY_TYPE;
14271 +/* the following key types are defined: */
14272 +#define CKK_RSA             0x00000000
14273 +#define CKK_DSA             0x00000001
14274 +#define CKK_DH              0x00000002
14276 +/* CKK_ECDSA and CKK_KEA are new for v2.0 */
14277 +/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
14278 +#define CKK_ECDSA           0x00000003
14279 +#define CKK_EC              0x00000003
14280 +#define CKK_X9_42_DH        0x00000004
14281 +#define CKK_KEA             0x00000005
14283 +#define CKK_GENERIC_SECRET  0x00000010
14284 +#define CKK_RC2             0x00000011
14285 +#define CKK_RC4             0x00000012
14286 +#define CKK_DES             0x00000013
14287 +#define CKK_DES2            0x00000014
14288 +#define CKK_DES3            0x00000015
14290 +/* all these key types are new for v2.0 */
14291 +#define CKK_CAST            0x00000016
14292 +#define CKK_CAST3           0x00000017
14293 +/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
14294 +#define CKK_CAST5           0x00000018
14295 +#define CKK_CAST128         0x00000018
14296 +#define CKK_RC5             0x00000019
14297 +#define CKK_IDEA            0x0000001A
14298 +#define CKK_SKIPJACK        0x0000001B
14299 +#define CKK_BATON           0x0000001C
14300 +#define CKK_JUNIPER         0x0000001D
14301 +#define CKK_CDMF            0x0000001E
14302 +#define CKK_AES             0x0000001F
14304 +/* BlowFish and TwoFish are new for v2.20 */
14305 +#define CKK_BLOWFISH        0x00000020
14306 +#define CKK_TWOFISH         0x00000021
14308 +/* SecurID, HOTP, and ACTI are new for PKCS #11 v2.20 amendment 1 */
14309 +#define CKK_SECURID         0x00000022
14310 +#define CKK_HOTP            0x00000023
14311 +#define CKK_ACTI            0x00000024
14313 +/* Camellia is new for PKCS #11 v2.20 amendment 3 */
14314 +#define CKK_CAMELLIA                   0x00000025
14315 +/* ARIA is new for PKCS #11 v2.20 amendment 3 */
14316 +#define CKK_ARIA                       0x00000026
14319 +#define CKK_VENDOR_DEFINED  0x80000000
14322 +/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
14323 + * type */
14324 +/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
14325 + * for v2.0 */
14326 +typedef CK_ULONG          CK_CERTIFICATE_TYPE;
14328 +/* The following certificate types are defined: */
14329 +/* CKC_X_509_ATTR_CERT is new for v2.10 */
14330 +/* CKC_WTLS is new for v2.20 */
14331 +#define CKC_X_509           0x00000000
14332 +#define CKC_X_509_ATTR_CERT 0x00000001
14333 +#define CKC_WTLS            0x00000002
14334 +#define CKC_VENDOR_DEFINED  0x80000000
14337 +/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
14338 + * type */
14339 +/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
14340 + * v2.0 */
14341 +typedef CK_ULONG          CK_ATTRIBUTE_TYPE;
14343 +/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
14344 +   consists of an array of values. */
14345 +#define CKF_ARRAY_ATTRIBUTE    0x40000000
14347 +/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1
14348 +   and relates to the CKA_OTP_FORMAT attribute */
14349 +#define CK_OTP_FORMAT_DECIMAL      0
14350 +#define CK_OTP_FORMAT_HEXADECIMAL  1
14351 +#define CK_OTP_FORMAT_ALPHANUMERIC 2
14352 +#define CK_OTP_FORMAT_BINARY       3
14354 +/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1
14355 +   and relates to the CKA_OTP_..._REQUIREMENT attributes */
14356 +#define CK_OTP_PARAM_IGNORED       0
14357 +#define CK_OTP_PARAM_OPTIONAL      1
14358 +#define CK_OTP_PARAM_MANDATORY     2
14360 +/* The following attribute types are defined: */
14361 +#define CKA_CLASS              0x00000000
14362 +#define CKA_TOKEN              0x00000001
14363 +#define CKA_PRIVATE            0x00000002
14364 +#define CKA_LABEL              0x00000003
14365 +#define CKA_APPLICATION        0x00000010
14366 +#define CKA_VALUE              0x00000011
14368 +/* CKA_OBJECT_ID is new for v2.10 */
14369 +#define CKA_OBJECT_ID          0x00000012
14371 +#define CKA_CERTIFICATE_TYPE   0x00000080
14372 +#define CKA_ISSUER             0x00000081
14373 +#define CKA_SERIAL_NUMBER      0x00000082
14375 +/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
14376 + * for v2.10 */
14377 +#define CKA_AC_ISSUER          0x00000083
14378 +#define CKA_OWNER              0x00000084
14379 +#define CKA_ATTR_TYPES         0x00000085
14381 +/* CKA_TRUSTED is new for v2.11 */
14382 +#define CKA_TRUSTED            0x00000086
14384 +/* CKA_CERTIFICATE_CATEGORY ...
14385 + * CKA_CHECK_VALUE are new for v2.20 */
14386 +#define CKA_CERTIFICATE_CATEGORY        0x00000087
14387 +#define CKA_JAVA_MIDP_SECURITY_DOMAIN   0x00000088
14388 +#define CKA_URL                         0x00000089
14389 +#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY  0x0000008A
14390 +#define CKA_HASH_OF_ISSUER_PUBLIC_KEY   0x0000008B
14391 +#define CKA_CHECK_VALUE                 0x00000090
14393 +#define CKA_KEY_TYPE           0x00000100
14394 +#define CKA_SUBJECT            0x00000101
14395 +#define CKA_ID                 0x00000102
14396 +#define CKA_SENSITIVE          0x00000103
14397 +#define CKA_ENCRYPT            0x00000104
14398 +#define CKA_DECRYPT            0x00000105
14399 +#define CKA_WRAP               0x00000106
14400 +#define CKA_UNWRAP             0x00000107
14401 +#define CKA_SIGN               0x00000108
14402 +#define CKA_SIGN_RECOVER       0x00000109
14403 +#define CKA_VERIFY             0x0000010A
14404 +#define CKA_VERIFY_RECOVER     0x0000010B
14405 +#define CKA_DERIVE             0x0000010C
14406 +#define CKA_START_DATE         0x00000110
14407 +#define CKA_END_DATE           0x00000111
14408 +#define CKA_MODULUS            0x00000120
14409 +#define CKA_MODULUS_BITS       0x00000121
14410 +#define CKA_PUBLIC_EXPONENT    0x00000122
14411 +#define CKA_PRIVATE_EXPONENT   0x00000123
14412 +#define CKA_PRIME_1            0x00000124
14413 +#define CKA_PRIME_2            0x00000125
14414 +#define CKA_EXPONENT_1         0x00000126
14415 +#define CKA_EXPONENT_2         0x00000127
14416 +#define CKA_COEFFICIENT        0x00000128
14417 +#define CKA_PRIME              0x00000130
14418 +#define CKA_SUBPRIME           0x00000131
14419 +#define CKA_BASE               0x00000132
14421 +/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
14422 +#define CKA_PRIME_BITS         0x00000133
14423 +#define CKA_SUBPRIME_BITS      0x00000134
14424 +#define CKA_SUB_PRIME_BITS     CKA_SUBPRIME_BITS
14425 +/* (To retain backwards-compatibility) */
14427 +#define CKA_VALUE_BITS         0x00000160
14428 +#define CKA_VALUE_LEN          0x00000161
14430 +/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
14431 + * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
14432 + * and CKA_EC_POINT are new for v2.0 */
14433 +#define CKA_EXTRACTABLE        0x00000162
14434 +#define CKA_LOCAL              0x00000163
14435 +#define CKA_NEVER_EXTRACTABLE  0x00000164
14436 +#define CKA_ALWAYS_SENSITIVE   0x00000165
14438 +/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
14439 +#define CKA_KEY_GEN_MECHANISM  0x00000166
14441 +#define CKA_MODIFIABLE         0x00000170
14443 +/* CKA_ECDSA_PARAMS is deprecated in v2.11,
14444 + * CKA_EC_PARAMS is preferred. */
14445 +#define CKA_ECDSA_PARAMS       0x00000180
14446 +#define CKA_EC_PARAMS          0x00000180
14448 +#define CKA_EC_POINT           0x00000181
14450 +/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
14451 + * are new for v2.10. Deprecated in v2.11 and onwards. */
14452 +#define CKA_SECONDARY_AUTH     0x00000200
14453 +#define CKA_AUTH_PIN_FLAGS     0x00000201
14455 +/* CKA_ALWAYS_AUTHENTICATE ...
14456 + * CKA_UNWRAP_TEMPLATE are new for v2.20 */
14457 +#define CKA_ALWAYS_AUTHENTICATE  0x00000202
14459 +#define CKA_WRAP_WITH_TRUSTED    0x00000210
14460 +#define CKA_WRAP_TEMPLATE        (CKF_ARRAY_ATTRIBUTE|0x00000211)
14461 +#define CKA_UNWRAP_TEMPLATE      (CKF_ARRAY_ATTRIBUTE|0x00000212)
14463 +/* CKA_OTP... atttributes are new for PKCS #11 v2.20 amendment 3. */
14464 +#define CKA_OTP_FORMAT                0x00000220
14465 +#define CKA_OTP_LENGTH                0x00000221
14466 +#define CKA_OTP_TIME_INTERVAL         0x00000222
14467 +#define CKA_OTP_USER_FRIENDLY_MODE    0x00000223
14468 +#define CKA_OTP_CHALLENGE_REQUIREMENT 0x00000224
14469 +#define CKA_OTP_TIME_REQUIREMENT      0x00000225
14470 +#define CKA_OTP_COUNTER_REQUIREMENT   0x00000226
14471 +#define CKA_OTP_PIN_REQUIREMENT       0x00000227
14472 +#define CKA_OTP_COUNTER               0x0000022E
14473 +#define CKA_OTP_TIME                  0x0000022F
14474 +#define CKA_OTP_USER_IDENTIFIER       0x0000022A
14475 +#define CKA_OTP_SERVICE_IDENTIFIER    0x0000022B
14476 +#define CKA_OTP_SERVICE_LOGO          0x0000022C
14477 +#define CKA_OTP_SERVICE_LOGO_TYPE     0x0000022D
14480 +/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
14481 + * are new for v2.10 */
14482 +#define CKA_HW_FEATURE_TYPE    0x00000300
14483 +#define CKA_RESET_ON_INIT      0x00000301
14484 +#define CKA_HAS_RESET          0x00000302
14486 +/* The following attributes are new for v2.20 */
14487 +#define CKA_PIXEL_X                     0x00000400
14488 +#define CKA_PIXEL_Y                     0x00000401
14489 +#define CKA_RESOLUTION                  0x00000402
14490 +#define CKA_CHAR_ROWS                   0x00000403
14491 +#define CKA_CHAR_COLUMNS                0x00000404
14492 +#define CKA_COLOR                       0x00000405
14493 +#define CKA_BITS_PER_PIXEL              0x00000406
14494 +#define CKA_CHAR_SETS                   0x00000480
14495 +#define CKA_ENCODING_METHODS            0x00000481
14496 +#define CKA_MIME_TYPES                  0x00000482
14497 +#define CKA_MECHANISM_TYPE              0x00000500
14498 +#define CKA_REQUIRED_CMS_ATTRIBUTES     0x00000501
14499 +#define CKA_DEFAULT_CMS_ATTRIBUTES      0x00000502
14500 +#define CKA_SUPPORTED_CMS_ATTRIBUTES    0x00000503
14501 +#define CKA_ALLOWED_MECHANISMS          (CKF_ARRAY_ATTRIBUTE|0x00000600)
14503 +#define CKA_VENDOR_DEFINED     0x80000000
14505 +/* CK_ATTRIBUTE is a structure that includes the type, length
14506 + * and value of an attribute */
14507 +typedef struct CK_ATTRIBUTE {
14508 +  CK_ATTRIBUTE_TYPE type;
14509 +  CK_VOID_PTR       pValue;
14511 +  /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
14512 +  CK_ULONG          ulValueLen;  /* in bytes */
14513 +} CK_ATTRIBUTE;
14515 +typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
14518 +/* CK_DATE is a structure that defines a date */
14519 +typedef struct CK_DATE{
14520 +  CK_CHAR       year[4];   /* the year ("1900" - "9999") */
14521 +  CK_CHAR       month[2];  /* the month ("01" - "12") */
14522 +  CK_CHAR       day[2];    /* the day   ("01" - "31") */
14523 +} CK_DATE;
14526 +/* CK_MECHANISM_TYPE is a value that identifies a mechanism
14527 + * type */
14528 +/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
14529 + * v2.0 */
14530 +typedef CK_ULONG          CK_MECHANISM_TYPE;
14532 +/* the following mechanism types are defined: */
14533 +#define CKM_RSA_PKCS_KEY_PAIR_GEN      0x00000000
14534 +#define CKM_RSA_PKCS                   0x00000001
14535 +#define CKM_RSA_9796                   0x00000002
14536 +#define CKM_RSA_X_509                  0x00000003
14538 +/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
14539 + * are new for v2.0.  They are mechanisms which hash and sign */
14540 +#define CKM_MD2_RSA_PKCS               0x00000004
14541 +#define CKM_MD5_RSA_PKCS               0x00000005
14542 +#define CKM_SHA1_RSA_PKCS              0x00000006
14544 +/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
14545 + * CKM_RSA_PKCS_OAEP are new for v2.10 */
14546 +#define CKM_RIPEMD128_RSA_PKCS         0x00000007
14547 +#define CKM_RIPEMD160_RSA_PKCS         0x00000008
14548 +#define CKM_RSA_PKCS_OAEP              0x00000009
14550 +/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
14551 + * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
14552 +#define CKM_RSA_X9_31_KEY_PAIR_GEN     0x0000000A
14553 +#define CKM_RSA_X9_31                  0x0000000B
14554 +#define CKM_SHA1_RSA_X9_31             0x0000000C
14555 +#define CKM_RSA_PKCS_PSS               0x0000000D
14556 +#define CKM_SHA1_RSA_PKCS_PSS          0x0000000E
14558 +#define CKM_DSA_KEY_PAIR_GEN           0x00000010
14559 +#define CKM_DSA                        0x00000011
14560 +#define CKM_DSA_SHA1                   0x00000012
14561 +#define CKM_DH_PKCS_KEY_PAIR_GEN       0x00000020
14562 +#define CKM_DH_PKCS_DERIVE             0x00000021
14564 +/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
14565 + * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
14566 + * v2.11 */
14567 +#define CKM_X9_42_DH_KEY_PAIR_GEN      0x00000030
14568 +#define CKM_X9_42_DH_DERIVE            0x00000031
14569 +#define CKM_X9_42_DH_HYBRID_DERIVE     0x00000032
14570 +#define CKM_X9_42_MQV_DERIVE           0x00000033
14572 +/* CKM_SHA256/384/512 are new for v2.20 */
14573 +#define CKM_SHA256_RSA_PKCS            0x00000040
14574 +#define CKM_SHA384_RSA_PKCS            0x00000041
14575 +#define CKM_SHA512_RSA_PKCS            0x00000042
14576 +#define CKM_SHA256_RSA_PKCS_PSS        0x00000043
14577 +#define CKM_SHA384_RSA_PKCS_PSS        0x00000044
14578 +#define CKM_SHA512_RSA_PKCS_PSS        0x00000045
14580 +/* SHA-224 RSA mechanisms are new for PKCS #11 v2.20 amendment 3 */
14581 +#define CKM_SHA224_RSA_PKCS            0x00000046
14582 +#define CKM_SHA224_RSA_PKCS_PSS        0x00000047
14584 +#define CKM_RC2_KEY_GEN                0x00000100
14585 +#define CKM_RC2_ECB                    0x00000101
14586 +#define CKM_RC2_CBC                    0x00000102
14587 +#define CKM_RC2_MAC                    0x00000103
14589 +/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
14590 +#define CKM_RC2_MAC_GENERAL            0x00000104
14591 +#define CKM_RC2_CBC_PAD                0x00000105
14593 +#define CKM_RC4_KEY_GEN                0x00000110
14594 +#define CKM_RC4                        0x00000111
14595 +#define CKM_DES_KEY_GEN                0x00000120
14596 +#define CKM_DES_ECB                    0x00000121
14597 +#define CKM_DES_CBC                    0x00000122
14598 +#define CKM_DES_MAC                    0x00000123
14600 +/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
14601 +#define CKM_DES_MAC_GENERAL            0x00000124
14602 +#define CKM_DES_CBC_PAD                0x00000125
14604 +#define CKM_DES2_KEY_GEN               0x00000130
14605 +#define CKM_DES3_KEY_GEN               0x00000131
14606 +#define CKM_DES3_ECB                   0x00000132
14607 +#define CKM_DES3_CBC                   0x00000133
14608 +#define CKM_DES3_MAC                   0x00000134
14610 +/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
14611 + * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
14612 + * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
14613 +#define CKM_DES3_MAC_GENERAL           0x00000135
14614 +#define CKM_DES3_CBC_PAD               0x00000136
14615 +#define CKM_CDMF_KEY_GEN               0x00000140
14616 +#define CKM_CDMF_ECB                   0x00000141
14617 +#define CKM_CDMF_CBC                   0x00000142
14618 +#define CKM_CDMF_MAC                   0x00000143
14619 +#define CKM_CDMF_MAC_GENERAL           0x00000144
14620 +#define CKM_CDMF_CBC_PAD               0x00000145
14622 +/* the following four DES mechanisms are new for v2.20 */
14623 +#define CKM_DES_OFB64                  0x00000150
14624 +#define CKM_DES_OFB8                   0x00000151
14625 +#define CKM_DES_CFB64                  0x00000152
14626 +#define CKM_DES_CFB8                   0x00000153
14628 +#define CKM_MD2                        0x00000200
14630 +/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
14631 +#define CKM_MD2_HMAC                   0x00000201
14632 +#define CKM_MD2_HMAC_GENERAL           0x00000202
14634 +#define CKM_MD5                        0x00000210
14636 +/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
14637 +#define CKM_MD5_HMAC                   0x00000211
14638 +#define CKM_MD5_HMAC_GENERAL           0x00000212
14640 +#define CKM_SHA_1                      0x00000220
14642 +/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
14643 +#define CKM_SHA_1_HMAC                 0x00000221
14644 +#define CKM_SHA_1_HMAC_GENERAL         0x00000222
14646 +/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
14647 + * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
14648 + * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
14649 +#define CKM_RIPEMD128                  0x00000230
14650 +#define CKM_RIPEMD128_HMAC             0x00000231
14651 +#define CKM_RIPEMD128_HMAC_GENERAL     0x00000232
14652 +#define CKM_RIPEMD160                  0x00000240
14653 +#define CKM_RIPEMD160_HMAC             0x00000241
14654 +#define CKM_RIPEMD160_HMAC_GENERAL     0x00000242
14656 +/* CKM_SHA256/384/512 are new for v2.20 */
14657 +#define CKM_SHA256                     0x00000250
14658 +#define CKM_SHA256_HMAC                0x00000251
14659 +#define CKM_SHA256_HMAC_GENERAL        0x00000252
14661 +/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
14662 +#define CKM_SHA224                     0x00000255
14663 +#define CKM_SHA224_HMAC                0x00000256
14664 +#define CKM_SHA224_HMAC_GENERAL        0x00000257
14666 +#define CKM_SHA384                     0x00000260
14667 +#define CKM_SHA384_HMAC                0x00000261
14668 +#define CKM_SHA384_HMAC_GENERAL        0x00000262
14669 +#define CKM_SHA512                     0x00000270
14670 +#define CKM_SHA512_HMAC                0x00000271
14671 +#define CKM_SHA512_HMAC_GENERAL        0x00000272
14673 +/* SecurID is new for PKCS #11 v2.20 amendment 1 */
14674 +#define CKM_SECURID_KEY_GEN            0x00000280
14675 +#define CKM_SECURID                    0x00000282
14677 +/* HOTP is new for PKCS #11 v2.20 amendment 1 */
14678 +#define CKM_HOTP_KEY_GEN    0x00000290
14679 +#define CKM_HOTP            0x00000291
14681 +/* ACTI is new for PKCS #11 v2.20 amendment 1 */
14682 +#define CKM_ACTI            0x000002A0
14683 +#define CKM_ACTI_KEY_GEN    0x000002A1
14685 +/* All of the following mechanisms are new for v2.0 */
14686 +/* Note that CAST128 and CAST5 are the same algorithm */
14687 +#define CKM_CAST_KEY_GEN               0x00000300
14688 +#define CKM_CAST_ECB                   0x00000301
14689 +#define CKM_CAST_CBC                   0x00000302
14690 +#define CKM_CAST_MAC                   0x00000303
14691 +#define CKM_CAST_MAC_GENERAL           0x00000304
14692 +#define CKM_CAST_CBC_PAD               0x00000305
14693 +#define CKM_CAST3_KEY_GEN              0x00000310
14694 +#define CKM_CAST3_ECB                  0x00000311
14695 +#define CKM_CAST3_CBC                  0x00000312
14696 +#define CKM_CAST3_MAC                  0x00000313
14697 +#define CKM_CAST3_MAC_GENERAL          0x00000314
14698 +#define CKM_CAST3_CBC_PAD              0x00000315
14699 +#define CKM_CAST5_KEY_GEN              0x00000320
14700 +#define CKM_CAST128_KEY_GEN            0x00000320
14701 +#define CKM_CAST5_ECB                  0x00000321
14702 +#define CKM_CAST128_ECB                0x00000321
14703 +#define CKM_CAST5_CBC                  0x00000322
14704 +#define CKM_CAST128_CBC                0x00000322
14705 +#define CKM_CAST5_MAC                  0x00000323
14706 +#define CKM_CAST128_MAC                0x00000323
14707 +#define CKM_CAST5_MAC_GENERAL          0x00000324
14708 +#define CKM_CAST128_MAC_GENERAL        0x00000324
14709 +#define CKM_CAST5_CBC_PAD              0x00000325
14710 +#define CKM_CAST128_CBC_PAD            0x00000325
14711 +#define CKM_RC5_KEY_GEN                0x00000330
14712 +#define CKM_RC5_ECB                    0x00000331
14713 +#define CKM_RC5_CBC                    0x00000332
14714 +#define CKM_RC5_MAC                    0x00000333
14715 +#define CKM_RC5_MAC_GENERAL            0x00000334
14716 +#define CKM_RC5_CBC_PAD                0x00000335
14717 +#define CKM_IDEA_KEY_GEN               0x00000340
14718 +#define CKM_IDEA_ECB                   0x00000341
14719 +#define CKM_IDEA_CBC                   0x00000342
14720 +#define CKM_IDEA_MAC                   0x00000343
14721 +#define CKM_IDEA_MAC_GENERAL           0x00000344
14722 +#define CKM_IDEA_CBC_PAD               0x00000345
14723 +#define CKM_GENERIC_SECRET_KEY_GEN     0x00000350
14724 +#define CKM_CONCATENATE_BASE_AND_KEY   0x00000360
14725 +#define CKM_CONCATENATE_BASE_AND_DATA  0x00000362
14726 +#define CKM_CONCATENATE_DATA_AND_BASE  0x00000363
14727 +#define CKM_XOR_BASE_AND_DATA          0x00000364
14728 +#define CKM_EXTRACT_KEY_FROM_KEY       0x00000365
14729 +#define CKM_SSL3_PRE_MASTER_KEY_GEN    0x00000370
14730 +#define CKM_SSL3_MASTER_KEY_DERIVE     0x00000371
14731 +#define CKM_SSL3_KEY_AND_MAC_DERIVE    0x00000372
14733 +/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
14734 + * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
14735 + * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
14736 +#define CKM_SSL3_MASTER_KEY_DERIVE_DH  0x00000373
14737 +#define CKM_TLS_PRE_MASTER_KEY_GEN     0x00000374
14738 +#define CKM_TLS_MASTER_KEY_DERIVE      0x00000375
14739 +#define CKM_TLS_KEY_AND_MAC_DERIVE     0x00000376
14740 +#define CKM_TLS_MASTER_KEY_DERIVE_DH   0x00000377
14742 +/* CKM_TLS_PRF is new for v2.20 */
14743 +#define CKM_TLS_PRF                    0x00000378
14745 +#define CKM_SSL3_MD5_MAC               0x00000380
14746 +#define CKM_SSL3_SHA1_MAC              0x00000381
14747 +#define CKM_MD5_KEY_DERIVATION         0x00000390
14748 +#define CKM_MD2_KEY_DERIVATION         0x00000391
14749 +#define CKM_SHA1_KEY_DERIVATION        0x00000392
14751 +/* CKM_SHA256/384/512 are new for v2.20 */
14752 +#define CKM_SHA256_KEY_DERIVATION      0x00000393
14753 +#define CKM_SHA384_KEY_DERIVATION      0x00000394
14754 +#define CKM_SHA512_KEY_DERIVATION      0x00000395
14756 +/* SHA-224 key derivation is new for PKCS #11 v2.20 amendment 3 */
14757 +#define CKM_SHA224_KEY_DERIVATION      0x00000396
14759 +#define CKM_PBE_MD2_DES_CBC            0x000003A0
14760 +#define CKM_PBE_MD5_DES_CBC            0x000003A1
14761 +#define CKM_PBE_MD5_CAST_CBC           0x000003A2
14762 +#define CKM_PBE_MD5_CAST3_CBC          0x000003A3
14763 +#define CKM_PBE_MD5_CAST5_CBC          0x000003A4
14764 +#define CKM_PBE_MD5_CAST128_CBC        0x000003A4
14765 +#define CKM_PBE_SHA1_CAST5_CBC         0x000003A5
14766 +#define CKM_PBE_SHA1_CAST128_CBC       0x000003A5
14767 +#define CKM_PBE_SHA1_RC4_128           0x000003A6
14768 +#define CKM_PBE_SHA1_RC4_40            0x000003A7
14769 +#define CKM_PBE_SHA1_DES3_EDE_CBC      0x000003A8
14770 +#define CKM_PBE_SHA1_DES2_EDE_CBC      0x000003A9
14771 +#define CKM_PBE_SHA1_RC2_128_CBC       0x000003AA
14772 +#define CKM_PBE_SHA1_RC2_40_CBC        0x000003AB
14774 +/* CKM_PKCS5_PBKD2 is new for v2.10 */
14775 +#define CKM_PKCS5_PBKD2                0x000003B0
14777 +#define CKM_PBA_SHA1_WITH_SHA1_HMAC    0x000003C0
14779 +/* WTLS mechanisms are new for v2.20 */
14780 +#define CKM_WTLS_PRE_MASTER_KEY_GEN         0x000003D0
14781 +#define CKM_WTLS_MASTER_KEY_DERIVE          0x000003D1
14782 +#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC   0x000003D2
14783 +#define CKM_WTLS_PRF                        0x000003D3
14784 +#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE  0x000003D4
14785 +#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE  0x000003D5
14787 +#define CKM_KEY_WRAP_LYNKS             0x00000400
14788 +#define CKM_KEY_WRAP_SET_OAEP          0x00000401
14790 +/* CKM_CMS_SIG is new for v2.20 */
14791 +#define CKM_CMS_SIG                    0x00000500
14793 +/* CKM_KIP mechanisms are new for PKCS #11 v2.20 amendment 2 */
14794 +#define CKM_KIP_DERIVE                 0x00000510
14795 +#define CKM_KIP_WRAP                   0x00000511
14796 +#define CKM_KIP_MAC                    0x00000512
14798 +/* Camellia is new for PKCS #11 v2.20 amendment 3 */
14799 +#define CKM_CAMELLIA_KEY_GEN           0x00000550
14800 +#define CKM_CAMELLIA_ECB               0x00000551
14801 +#define CKM_CAMELLIA_CBC               0x00000552
14802 +#define CKM_CAMELLIA_MAC               0x00000553
14803 +#define CKM_CAMELLIA_MAC_GENERAL       0x00000554
14804 +#define CKM_CAMELLIA_CBC_PAD           0x00000555
14805 +#define CKM_CAMELLIA_ECB_ENCRYPT_DATA  0x00000556
14806 +#define CKM_CAMELLIA_CBC_ENCRYPT_DATA  0x00000557
14807 +#define CKM_CAMELLIA_CTR               0x00000558
14809 +/* ARIA is new for PKCS #11 v2.20 amendment 3 */
14810 +#define CKM_ARIA_KEY_GEN               0x00000560
14811 +#define CKM_ARIA_ECB                   0x00000561
14812 +#define CKM_ARIA_CBC                   0x00000562
14813 +#define CKM_ARIA_MAC                   0x00000563
14814 +#define CKM_ARIA_MAC_GENERAL           0x00000564
14815 +#define CKM_ARIA_CBC_PAD               0x00000565
14816 +#define CKM_ARIA_ECB_ENCRYPT_DATA      0x00000566
14817 +#define CKM_ARIA_CBC_ENCRYPT_DATA      0x00000567
14819 +/* Fortezza mechanisms */
14820 +#define CKM_SKIPJACK_KEY_GEN           0x00001000
14821 +#define CKM_SKIPJACK_ECB64             0x00001001
14822 +#define CKM_SKIPJACK_CBC64             0x00001002
14823 +#define CKM_SKIPJACK_OFB64             0x00001003
14824 +#define CKM_SKIPJACK_CFB64             0x00001004
14825 +#define CKM_SKIPJACK_CFB32             0x00001005
14826 +#define CKM_SKIPJACK_CFB16             0x00001006
14827 +#define CKM_SKIPJACK_CFB8              0x00001007
14828 +#define CKM_SKIPJACK_WRAP              0x00001008
14829 +#define CKM_SKIPJACK_PRIVATE_WRAP      0x00001009
14830 +#define CKM_SKIPJACK_RELAYX            0x0000100a
14831 +#define CKM_KEA_KEY_PAIR_GEN           0x00001010
14832 +#define CKM_KEA_KEY_DERIVE             0x00001011
14833 +#define CKM_FORTEZZA_TIMESTAMP         0x00001020
14834 +#define CKM_BATON_KEY_GEN              0x00001030
14835 +#define CKM_BATON_ECB128               0x00001031
14836 +#define CKM_BATON_ECB96                0x00001032
14837 +#define CKM_BATON_CBC128               0x00001033
14838 +#define CKM_BATON_COUNTER              0x00001034
14839 +#define CKM_BATON_SHUFFLE              0x00001035
14840 +#define CKM_BATON_WRAP                 0x00001036
14842 +/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
14843 + * CKM_EC_KEY_PAIR_GEN is preferred */
14844 +#define CKM_ECDSA_KEY_PAIR_GEN         0x00001040
14845 +#define CKM_EC_KEY_PAIR_GEN            0x00001040
14847 +#define CKM_ECDSA                      0x00001041
14848 +#define CKM_ECDSA_SHA1                 0x00001042
14850 +/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
14851 + * are new for v2.11 */
14852 +#define CKM_ECDH1_DERIVE               0x00001050
14853 +#define CKM_ECDH1_COFACTOR_DERIVE      0x00001051
14854 +#define CKM_ECMQV_DERIVE               0x00001052
14856 +#define CKM_JUNIPER_KEY_GEN            0x00001060
14857 +#define CKM_JUNIPER_ECB128             0x00001061
14858 +#define CKM_JUNIPER_CBC128             0x00001062
14859 +#define CKM_JUNIPER_COUNTER            0x00001063
14860 +#define CKM_JUNIPER_SHUFFLE            0x00001064
14861 +#define CKM_JUNIPER_WRAP               0x00001065
14862 +#define CKM_FASTHASH                   0x00001070
14864 +/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
14865 + * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
14866 + * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
14867 + * new for v2.11 */
14868 +#define CKM_AES_KEY_GEN                0x00001080
14869 +#define CKM_AES_ECB                    0x00001081
14870 +#define CKM_AES_CBC                    0x00001082
14871 +#define CKM_AES_MAC                    0x00001083
14872 +#define CKM_AES_MAC_GENERAL            0x00001084
14873 +#define CKM_AES_CBC_PAD                0x00001085
14875 +/* AES counter mode is new for PKCS #11 v2.20 amendment 3 */
14876 +#define CKM_AES_CTR                    0x00001086
14878 +/* BlowFish and TwoFish are new for v2.20 */
14879 +#define CKM_BLOWFISH_KEY_GEN           0x00001090
14880 +#define CKM_BLOWFISH_CBC               0x00001091
14881 +#define CKM_TWOFISH_KEY_GEN            0x00001092
14882 +#define CKM_TWOFISH_CBC                0x00001093
14885 +/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */
14886 +#define CKM_DES_ECB_ENCRYPT_DATA       0x00001100
14887 +#define CKM_DES_CBC_ENCRYPT_DATA       0x00001101
14888 +#define CKM_DES3_ECB_ENCRYPT_DATA      0x00001102
14889 +#define CKM_DES3_CBC_ENCRYPT_DATA      0x00001103
14890 +#define CKM_AES_ECB_ENCRYPT_DATA       0x00001104
14891 +#define CKM_AES_CBC_ENCRYPT_DATA       0x00001105
14893 +#define CKM_DSA_PARAMETER_GEN          0x00002000
14894 +#define CKM_DH_PKCS_PARAMETER_GEN      0x00002001
14895 +#define CKM_X9_42_DH_PARAMETER_GEN     0x00002002
14897 +#define CKM_VENDOR_DEFINED             0x80000000
14899 +typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
14902 +/* CK_MECHANISM is a structure that specifies a particular
14903 + * mechanism  */
14904 +typedef struct CK_MECHANISM {
14905 +  CK_MECHANISM_TYPE mechanism;
14906 +  CK_VOID_PTR       pParameter;
14908 +  /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
14909 +   * v2.0 */
14910 +  CK_ULONG          ulParameterLen;  /* in bytes */
14911 +} CK_MECHANISM;
14913 +typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
14916 +/* CK_MECHANISM_INFO provides information about a particular
14917 + * mechanism */
14918 +typedef struct CK_MECHANISM_INFO {
14919 +    CK_ULONG    ulMinKeySize;
14920 +    CK_ULONG    ulMaxKeySize;
14921 +    CK_FLAGS    flags;
14922 +} CK_MECHANISM_INFO;
14924 +/* The flags are defined as follows:
14925 + *      Bit Flag               Mask        Meaning */
14926 +#define CKF_HW                 0x00000001  /* performed by HW */
14928 +/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
14929 + * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
14930 + * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
14931 + * and CKF_DERIVE are new for v2.0.  They specify whether or not
14932 + * a mechanism can be used for a particular task */
14933 +#define CKF_ENCRYPT            0x00000100
14934 +#define CKF_DECRYPT            0x00000200
14935 +#define CKF_DIGEST             0x00000400
14936 +#define CKF_SIGN               0x00000800
14937 +#define CKF_SIGN_RECOVER       0x00001000
14938 +#define CKF_VERIFY             0x00002000
14939 +#define CKF_VERIFY_RECOVER     0x00004000
14940 +#define CKF_GENERATE           0x00008000
14941 +#define CKF_GENERATE_KEY_PAIR  0x00010000
14942 +#define CKF_WRAP               0x00020000
14943 +#define CKF_UNWRAP             0x00040000
14944 +#define CKF_DERIVE             0x00080000
14946 +/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
14947 + * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
14948 + * describe a token's EC capabilities not available in mechanism
14949 + * information. */
14950 +#define CKF_EC_F_P             0x00100000
14951 +#define CKF_EC_F_2M            0x00200000
14952 +#define CKF_EC_ECPARAMETERS    0x00400000
14953 +#define CKF_EC_NAMEDCURVE      0x00800000
14954 +#define CKF_EC_UNCOMPRESS      0x01000000
14955 +#define CKF_EC_COMPRESS        0x02000000
14957 +#define CKF_EXTENSION          0x80000000 /* FALSE for this version */
14959 +typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
14962 +/* CK_RV is a value that identifies the return value of a
14963 + * Cryptoki function */
14964 +/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
14965 +typedef CK_ULONG          CK_RV;
14967 +#define CKR_OK                                0x00000000
14968 +#define CKR_CANCEL                            0x00000001
14969 +#define CKR_HOST_MEMORY                       0x00000002
14970 +#define CKR_SLOT_ID_INVALID                   0x00000003
14972 +/* CKR_FLAGS_INVALID was removed for v2.0 */
14974 +/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
14975 +#define CKR_GENERAL_ERROR                     0x00000005
14976 +#define CKR_FUNCTION_FAILED                   0x00000006
14978 +/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
14979 + * and CKR_CANT_LOCK are new for v2.01 */
14980 +#define CKR_ARGUMENTS_BAD                     0x00000007
14981 +#define CKR_NO_EVENT                          0x00000008
14982 +#define CKR_NEED_TO_CREATE_THREADS            0x00000009
14983 +#define CKR_CANT_LOCK                         0x0000000A
14985 +#define CKR_ATTRIBUTE_READ_ONLY               0x00000010
14986 +#define CKR_ATTRIBUTE_SENSITIVE               0x00000011
14987 +#define CKR_ATTRIBUTE_TYPE_INVALID            0x00000012
14988 +#define CKR_ATTRIBUTE_VALUE_INVALID           0x00000013
14989 +#define CKR_DATA_INVALID                      0x00000020
14990 +#define CKR_DATA_LEN_RANGE                    0x00000021
14991 +#define CKR_DEVICE_ERROR                      0x00000030
14992 +#define CKR_DEVICE_MEMORY                     0x00000031
14993 +#define CKR_DEVICE_REMOVED                    0x00000032
14994 +#define CKR_ENCRYPTED_DATA_INVALID            0x00000040
14995 +#define CKR_ENCRYPTED_DATA_LEN_RANGE          0x00000041
14996 +#define CKR_FUNCTION_CANCELED                 0x00000050
14997 +#define CKR_FUNCTION_NOT_PARALLEL             0x00000051
14999 +/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
15000 +#define CKR_FUNCTION_NOT_SUPPORTED            0x00000054
15002 +#define CKR_KEY_HANDLE_INVALID                0x00000060
15004 +/* CKR_KEY_SENSITIVE was removed for v2.0 */
15006 +#define CKR_KEY_SIZE_RANGE                    0x00000062
15007 +#define CKR_KEY_TYPE_INCONSISTENT             0x00000063
15009 +/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
15010 + * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
15011 + * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
15012 + * v2.0 */
15013 +#define CKR_KEY_NOT_NEEDED                    0x00000064
15014 +#define CKR_KEY_CHANGED                       0x00000065
15015 +#define CKR_KEY_NEEDED                        0x00000066
15016 +#define CKR_KEY_INDIGESTIBLE                  0x00000067
15017 +#define CKR_KEY_FUNCTION_NOT_PERMITTED        0x00000068
15018 +#define CKR_KEY_NOT_WRAPPABLE                 0x00000069
15019 +#define CKR_KEY_UNEXTRACTABLE                 0x0000006A
15021 +#define CKR_MECHANISM_INVALID                 0x00000070
15022 +#define CKR_MECHANISM_PARAM_INVALID           0x00000071
15024 +/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
15025 + * were removed for v2.0 */
15026 +#define CKR_OBJECT_HANDLE_INVALID             0x00000082
15027 +#define CKR_OPERATION_ACTIVE                  0x00000090
15028 +#define CKR_OPERATION_NOT_INITIALIZED         0x00000091
15029 +#define CKR_PIN_INCORRECT                     0x000000A0
15030 +#define CKR_PIN_INVALID                       0x000000A1
15031 +#define CKR_PIN_LEN_RANGE                     0x000000A2
15033 +/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
15034 +#define CKR_PIN_EXPIRED                       0x000000A3
15035 +#define CKR_PIN_LOCKED                        0x000000A4
15037 +#define CKR_SESSION_CLOSED                    0x000000B0
15038 +#define CKR_SESSION_COUNT                     0x000000B1
15039 +#define CKR_SESSION_HANDLE_INVALID            0x000000B3
15040 +#define CKR_SESSION_PARALLEL_NOT_SUPPORTED    0x000000B4
15041 +#define CKR_SESSION_READ_ONLY                 0x000000B5
15042 +#define CKR_SESSION_EXISTS                    0x000000B6
15044 +/* CKR_SESSION_READ_ONLY_EXISTS and
15045 + * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
15046 +#define CKR_SESSION_READ_ONLY_EXISTS          0x000000B7
15047 +#define CKR_SESSION_READ_WRITE_SO_EXISTS      0x000000B8
15049 +#define CKR_SIGNATURE_INVALID                 0x000000C0
15050 +#define CKR_SIGNATURE_LEN_RANGE               0x000000C1
15051 +#define CKR_TEMPLATE_INCOMPLETE               0x000000D0
15052 +#define CKR_TEMPLATE_INCONSISTENT             0x000000D1
15053 +#define CKR_TOKEN_NOT_PRESENT                 0x000000E0
15054 +#define CKR_TOKEN_NOT_RECOGNIZED              0x000000E1
15055 +#define CKR_TOKEN_WRITE_PROTECTED             0x000000E2
15056 +#define CKR_UNWRAPPING_KEY_HANDLE_INVALID     0x000000F0
15057 +#define CKR_UNWRAPPING_KEY_SIZE_RANGE         0x000000F1
15058 +#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT  0x000000F2
15059 +#define CKR_USER_ALREADY_LOGGED_IN            0x00000100
15060 +#define CKR_USER_NOT_LOGGED_IN                0x00000101
15061 +#define CKR_USER_PIN_NOT_INITIALIZED          0x00000102
15062 +#define CKR_USER_TYPE_INVALID                 0x00000103
15064 +/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
15065 + * are new to v2.01 */
15066 +#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN    0x00000104
15067 +#define CKR_USER_TOO_MANY_TYPES               0x00000105
15069 +#define CKR_WRAPPED_KEY_INVALID               0x00000110
15070 +#define CKR_WRAPPED_KEY_LEN_RANGE             0x00000112
15071 +#define CKR_WRAPPING_KEY_HANDLE_INVALID       0x00000113
15072 +#define CKR_WRAPPING_KEY_SIZE_RANGE           0x00000114
15073 +#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT    0x00000115
15074 +#define CKR_RANDOM_SEED_NOT_SUPPORTED         0x00000120
15076 +/* These are new to v2.0 */
15077 +#define CKR_RANDOM_NO_RNG                     0x00000121
15079 +/* These are new to v2.11 */
15080 +#define CKR_DOMAIN_PARAMS_INVALID             0x00000130
15082 +/* These are new to v2.0 */
15083 +#define CKR_BUFFER_TOO_SMALL                  0x00000150
15084 +#define CKR_SAVED_STATE_INVALID               0x00000160
15085 +#define CKR_INFORMATION_SENSITIVE             0x00000170
15086 +#define CKR_STATE_UNSAVEABLE                  0x00000180
15088 +/* These are new to v2.01 */
15089 +#define CKR_CRYPTOKI_NOT_INITIALIZED          0x00000190
15090 +#define CKR_CRYPTOKI_ALREADY_INITIALIZED      0x00000191
15091 +#define CKR_MUTEX_BAD                         0x000001A0
15092 +#define CKR_MUTEX_NOT_LOCKED                  0x000001A1
15094 +/* The following return values are new for PKCS #11 v2.20 amendment 3 */
15095 +#define CKR_NEW_PIN_MODE                      0x000001B0
15096 +#define CKR_NEXT_OTP                          0x000001B1
15098 +/* This is new to v2.20 */
15099 +#define CKR_FUNCTION_REJECTED                 0x00000200
15101 +#define CKR_VENDOR_DEFINED                    0x80000000
15104 +/* CK_NOTIFY is an application callback that processes events */
15105 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
15106 +  CK_SESSION_HANDLE hSession,     /* the session's handle */
15107 +  CK_NOTIFICATION   event,
15108 +  CK_VOID_PTR       pApplication  /* passed to C_OpenSession */
15112 +/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
15113 + * version and pointers of appropriate types to all the
15114 + * Cryptoki functions */
15115 +/* CK_FUNCTION_LIST is new for v2.0 */
15116 +typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
15118 +typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
15120 +typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
15123 +/* CK_CREATEMUTEX is an application callback for creating a
15124 + * mutex object */
15125 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
15126 +  CK_VOID_PTR_PTR ppMutex  /* location to receive ptr to mutex */
15130 +/* CK_DESTROYMUTEX is an application callback for destroying a
15131 + * mutex object */
15132 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
15133 +  CK_VOID_PTR pMutex  /* pointer to mutex */
15137 +/* CK_LOCKMUTEX is an application callback for locking a mutex */
15138 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
15139 +  CK_VOID_PTR pMutex  /* pointer to mutex */
15143 +/* CK_UNLOCKMUTEX is an application callback for unlocking a
15144 + * mutex */
15145 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
15146 +  CK_VOID_PTR pMutex  /* pointer to mutex */
15150 +/* CK_C_INITIALIZE_ARGS provides the optional arguments to
15151 + * C_Initialize */
15152 +typedef struct CK_C_INITIALIZE_ARGS {
15153 +  CK_CREATEMUTEX CreateMutex;
15154 +  CK_DESTROYMUTEX DestroyMutex;
15155 +  CK_LOCKMUTEX LockMutex;
15156 +  CK_UNLOCKMUTEX UnlockMutex;
15157 +  CK_FLAGS flags;
15158 +  CK_VOID_PTR pReserved;
15159 +} CK_C_INITIALIZE_ARGS;
15161 +/* flags: bit flags that provide capabilities of the slot
15162 + *      Bit Flag                           Mask       Meaning
15163 + */
15164 +#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
15165 +#define CKF_OS_LOCKING_OK                  0x00000002
15167 +typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
15170 +/* additional flags for parameters to functions */
15172 +/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
15173 +#define CKF_DONT_BLOCK     1
15175 +/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
15176 + * CK_RSA_PKCS_OAEP_MGF_TYPE  is used to indicate the Message
15177 + * Generation Function (MGF) applied to a message block when
15178 + * formatting a message block for the PKCS #1 OAEP encryption
15179 + * scheme. */
15180 +typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
15182 +typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
15184 +/* The following MGFs are defined */
15185 +/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512
15186 + * are new for v2.20 */
15187 +#define CKG_MGF1_SHA1         0x00000001
15188 +#define CKG_MGF1_SHA256       0x00000002
15189 +#define CKG_MGF1_SHA384       0x00000003
15190 +#define CKG_MGF1_SHA512       0x00000004
15191 +/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
15192 +#define CKG_MGF1_SHA224       0x00000005
15194 +/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
15195 + * CK_RSA_PKCS_OAEP_SOURCE_TYPE  is used to indicate the source
15196 + * of the encoding parameter when formatting a message block
15197 + * for the PKCS #1 OAEP encryption scheme. */
15198 +typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
15200 +typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
15202 +/* The following encoding parameter sources are defined */
15203 +#define CKZ_DATA_SPECIFIED    0x00000001
15205 +/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
15206 + * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
15207 + * CKM_RSA_PKCS_OAEP mechanism. */
15208 +typedef struct CK_RSA_PKCS_OAEP_PARAMS {
15209 +        CK_MECHANISM_TYPE hashAlg;
15210 +        CK_RSA_PKCS_MGF_TYPE mgf;
15211 +        CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
15212 +        CK_VOID_PTR pSourceData;
15213 +        CK_ULONG ulSourceDataLen;
15214 +} CK_RSA_PKCS_OAEP_PARAMS;
15216 +typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
15218 +/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11.
15219 + * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
15220 + * CKM_RSA_PKCS_PSS mechanism(s). */
15221 +typedef struct CK_RSA_PKCS_PSS_PARAMS {
15222 +        CK_MECHANISM_TYPE    hashAlg;
15223 +        CK_RSA_PKCS_MGF_TYPE mgf;
15224 +        CK_ULONG             sLen;
15225 +} CK_RSA_PKCS_PSS_PARAMS;
15227 +typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
15229 +/* CK_EC_KDF_TYPE is new for v2.11. */
15230 +typedef CK_ULONG CK_EC_KDF_TYPE;
15232 +/* The following EC Key Derivation Functions are defined */
15233 +#define CKD_NULL                 0x00000001
15234 +#define CKD_SHA1_KDF             0x00000002
15236 +/* CK_ECDH1_DERIVE_PARAMS is new for v2.11.
15237 + * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
15238 + * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
15239 + * where each party contributes one key pair.
15240 + */
15241 +typedef struct CK_ECDH1_DERIVE_PARAMS {
15242 +  CK_EC_KDF_TYPE kdf;
15243 +  CK_ULONG ulSharedDataLen;
15244 +  CK_BYTE_PTR pSharedData;
15245 +  CK_ULONG ulPublicDataLen;
15246 +  CK_BYTE_PTR pPublicData;
15247 +} CK_ECDH1_DERIVE_PARAMS;
15249 +typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
15252 +/* CK_ECDH2_DERIVE_PARAMS is new for v2.11.
15253 + * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
15254 + * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */
15255 +typedef struct CK_ECDH2_DERIVE_PARAMS {
15256 +  CK_EC_KDF_TYPE kdf;
15257 +  CK_ULONG ulSharedDataLen;
15258 +  CK_BYTE_PTR pSharedData;
15259 +  CK_ULONG ulPublicDataLen;
15260 +  CK_BYTE_PTR pPublicData;
15261 +  CK_ULONG ulPrivateDataLen;
15262 +  CK_OBJECT_HANDLE hPrivateData;
15263 +  CK_ULONG ulPublicDataLen2;
15264 +  CK_BYTE_PTR pPublicData2;
15265 +} CK_ECDH2_DERIVE_PARAMS;
15267 +typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
15269 +typedef struct CK_ECMQV_DERIVE_PARAMS {
15270 +  CK_EC_KDF_TYPE kdf;
15271 +  CK_ULONG ulSharedDataLen;
15272 +  CK_BYTE_PTR pSharedData;
15273 +  CK_ULONG ulPublicDataLen;
15274 +  CK_BYTE_PTR pPublicData;
15275 +  CK_ULONG ulPrivateDataLen;
15276 +  CK_OBJECT_HANDLE hPrivateData;
15277 +  CK_ULONG ulPublicDataLen2;
15278 +  CK_BYTE_PTR pPublicData2;
15279 +  CK_OBJECT_HANDLE publicKey;
15280 +} CK_ECMQV_DERIVE_PARAMS;
15282 +typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
15284 +/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
15285 + * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */
15286 +typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
15287 +typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
15289 +/* The following X9.42 DH key derivation functions are defined
15290 +   (besides CKD_NULL already defined : */
15291 +#define CKD_SHA1_KDF_ASN1        0x00000003
15292 +#define CKD_SHA1_KDF_CONCATENATE 0x00000004
15294 +/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11.
15295 + * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
15296 + * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
15297 + * contributes one key pair */
15298 +typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
15299 +  CK_X9_42_DH_KDF_TYPE kdf;
15300 +  CK_ULONG ulOtherInfoLen;
15301 +  CK_BYTE_PTR pOtherInfo;
15302 +  CK_ULONG ulPublicDataLen;
15303 +  CK_BYTE_PTR pPublicData;
15304 +} CK_X9_42_DH1_DERIVE_PARAMS;
15306 +typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
15308 +/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11.
15309 + * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
15310 + * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
15311 + * mechanisms, where each party contributes two key pairs */
15312 +typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
15313 +  CK_X9_42_DH_KDF_TYPE kdf;
15314 +  CK_ULONG ulOtherInfoLen;
15315 +  CK_BYTE_PTR pOtherInfo;
15316 +  CK_ULONG ulPublicDataLen;
15317 +  CK_BYTE_PTR pPublicData;
15318 +  CK_ULONG ulPrivateDataLen;
15319 +  CK_OBJECT_HANDLE hPrivateData;
15320 +  CK_ULONG ulPublicDataLen2;
15321 +  CK_BYTE_PTR pPublicData2;
15322 +} CK_X9_42_DH2_DERIVE_PARAMS;
15324 +typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
15326 +typedef struct CK_X9_42_MQV_DERIVE_PARAMS {
15327 +  CK_X9_42_DH_KDF_TYPE kdf;
15328 +  CK_ULONG ulOtherInfoLen;
15329 +  CK_BYTE_PTR pOtherInfo;
15330 +  CK_ULONG ulPublicDataLen;
15331 +  CK_BYTE_PTR pPublicData;
15332 +  CK_ULONG ulPrivateDataLen;
15333 +  CK_OBJECT_HANDLE hPrivateData;
15334 +  CK_ULONG ulPublicDataLen2;
15335 +  CK_BYTE_PTR pPublicData2;
15336 +  CK_OBJECT_HANDLE publicKey;
15337 +} CK_X9_42_MQV_DERIVE_PARAMS;
15339 +typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
15341 +/* CK_KEA_DERIVE_PARAMS provides the parameters to the
15342 + * CKM_KEA_DERIVE mechanism */
15343 +/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
15344 +typedef struct CK_KEA_DERIVE_PARAMS {
15345 +  CK_BBOOL      isSender;
15346 +  CK_ULONG      ulRandomLen;
15347 +  CK_BYTE_PTR   pRandomA;
15348 +  CK_BYTE_PTR   pRandomB;
15349 +  CK_ULONG      ulPublicDataLen;
15350 +  CK_BYTE_PTR   pPublicData;
15351 +} CK_KEA_DERIVE_PARAMS;
15353 +typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
15356 +/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
15357 + * CKM_RC2_MAC mechanisms.  An instance of CK_RC2_PARAMS just
15358 + * holds the effective keysize */
15359 +typedef CK_ULONG          CK_RC2_PARAMS;
15361 +typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
15364 +/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
15365 + * mechanism */
15366 +typedef struct CK_RC2_CBC_PARAMS {
15367 +  /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
15368 +   * v2.0 */
15369 +  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
15371 +  CK_BYTE       iv[8];            /* IV for CBC mode */
15372 +} CK_RC2_CBC_PARAMS;
15374 +typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
15377 +/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
15378 + * CKM_RC2_MAC_GENERAL mechanism */
15379 +/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
15380 +typedef struct CK_RC2_MAC_GENERAL_PARAMS {
15381 +  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
15382 +  CK_ULONG      ulMacLength;      /* Length of MAC in bytes */
15383 +} CK_RC2_MAC_GENERAL_PARAMS;
15385 +typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
15386 +  CK_RC2_MAC_GENERAL_PARAMS_PTR;
15389 +/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
15390 + * CKM_RC5_MAC mechanisms */
15391 +/* CK_RC5_PARAMS is new for v2.0 */
15392 +typedef struct CK_RC5_PARAMS {
15393 +  CK_ULONG      ulWordsize;  /* wordsize in bits */
15394 +  CK_ULONG      ulRounds;    /* number of rounds */
15395 +} CK_RC5_PARAMS;
15397 +typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
15400 +/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
15401 + * mechanism */
15402 +/* CK_RC5_CBC_PARAMS is new for v2.0 */
15403 +typedef struct CK_RC5_CBC_PARAMS {
15404 +  CK_ULONG      ulWordsize;  /* wordsize in bits */
15405 +  CK_ULONG      ulRounds;    /* number of rounds */
15406 +  CK_BYTE_PTR   pIv;         /* pointer to IV */
15407 +  CK_ULONG      ulIvLen;     /* length of IV in bytes */
15408 +} CK_RC5_CBC_PARAMS;
15410 +typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
15413 +/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
15414 + * CKM_RC5_MAC_GENERAL mechanism */
15415 +/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
15416 +typedef struct CK_RC5_MAC_GENERAL_PARAMS {
15417 +  CK_ULONG      ulWordsize;   /* wordsize in bits */
15418 +  CK_ULONG      ulRounds;     /* number of rounds */
15419 +  CK_ULONG      ulMacLength;  /* Length of MAC in bytes */
15420 +} CK_RC5_MAC_GENERAL_PARAMS;
15422 +typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
15423 +  CK_RC5_MAC_GENERAL_PARAMS_PTR;
15426 +/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
15427 + * ciphers' MAC_GENERAL mechanisms.  Its value is the length of
15428 + * the MAC */
15429 +/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
15430 +typedef CK_ULONG          CK_MAC_GENERAL_PARAMS;
15432 +typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
15434 +/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
15435 +typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
15436 +  CK_BYTE      iv[8];
15437 +  CK_BYTE_PTR  pData;
15438 +  CK_ULONG     length;
15439 +} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
15441 +typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
15443 +typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
15444 +  CK_BYTE      iv[16];
15445 +  CK_BYTE_PTR  pData;
15446 +  CK_ULONG     length;
15447 +} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
15449 +typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
15451 +/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
15452 + * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
15453 +/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
15454 +typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
15455 +  CK_ULONG      ulPasswordLen;
15456 +  CK_BYTE_PTR   pPassword;
15457 +  CK_ULONG      ulPublicDataLen;
15458 +  CK_BYTE_PTR   pPublicData;
15459 +  CK_ULONG      ulPAndGLen;
15460 +  CK_ULONG      ulQLen;
15461 +  CK_ULONG      ulRandomLen;
15462 +  CK_BYTE_PTR   pRandomA;
15463 +  CK_BYTE_PTR   pPrimeP;
15464 +  CK_BYTE_PTR   pBaseG;
15465 +  CK_BYTE_PTR   pSubprimeQ;
15466 +} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
15468 +typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
15469 +  CK_SKIPJACK_PRIVATE_WRAP_PTR;
15472 +/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
15473 + * CKM_SKIPJACK_RELAYX mechanism */
15474 +/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
15475 +typedef struct CK_SKIPJACK_RELAYX_PARAMS {
15476 +  CK_ULONG      ulOldWrappedXLen;
15477 +  CK_BYTE_PTR   pOldWrappedX;
15478 +  CK_ULONG      ulOldPasswordLen;
15479 +  CK_BYTE_PTR   pOldPassword;
15480 +  CK_ULONG      ulOldPublicDataLen;
15481 +  CK_BYTE_PTR   pOldPublicData;
15482 +  CK_ULONG      ulOldRandomLen;
15483 +  CK_BYTE_PTR   pOldRandomA;
15484 +  CK_ULONG      ulNewPasswordLen;
15485 +  CK_BYTE_PTR   pNewPassword;
15486 +  CK_ULONG      ulNewPublicDataLen;
15487 +  CK_BYTE_PTR   pNewPublicData;
15488 +  CK_ULONG      ulNewRandomLen;
15489 +  CK_BYTE_PTR   pNewRandomA;
15490 +} CK_SKIPJACK_RELAYX_PARAMS;
15492 +typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
15493 +  CK_SKIPJACK_RELAYX_PARAMS_PTR;
15496 +typedef struct CK_PBE_PARAMS {
15497 +  CK_BYTE_PTR      pInitVector;
15498 +  CK_UTF8CHAR_PTR  pPassword;
15499 +  CK_ULONG         ulPasswordLen;
15500 +  CK_BYTE_PTR      pSalt;
15501 +  CK_ULONG         ulSaltLen;
15502 +  CK_ULONG         ulIteration;
15503 +} CK_PBE_PARAMS;
15505 +typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
15508 +/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
15509 + * CKM_KEY_WRAP_SET_OAEP mechanism */
15510 +/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
15511 +typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
15512 +  CK_BYTE       bBC;     /* block contents byte */
15513 +  CK_BYTE_PTR   pX;      /* extra data */
15514 +  CK_ULONG      ulXLen;  /* length of extra data in bytes */
15515 +} CK_KEY_WRAP_SET_OAEP_PARAMS;
15517 +typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
15518 +  CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
15521 +typedef struct CK_SSL3_RANDOM_DATA {
15522 +  CK_BYTE_PTR  pClientRandom;
15523 +  CK_ULONG     ulClientRandomLen;
15524 +  CK_BYTE_PTR  pServerRandom;
15525 +  CK_ULONG     ulServerRandomLen;
15526 +} CK_SSL3_RANDOM_DATA;
15529 +typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
15530 +  CK_SSL3_RANDOM_DATA RandomInfo;
15531 +  CK_VERSION_PTR pVersion;
15532 +} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
15534 +typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
15535 +  CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
15538 +typedef struct CK_SSL3_KEY_MAT_OUT {
15539 +  CK_OBJECT_HANDLE hClientMacSecret;
15540 +  CK_OBJECT_HANDLE hServerMacSecret;
15541 +  CK_OBJECT_HANDLE hClientKey;
15542 +  CK_OBJECT_HANDLE hServerKey;
15543 +  CK_BYTE_PTR      pIVClient;
15544 +  CK_BYTE_PTR      pIVServer;
15545 +} CK_SSL3_KEY_MAT_OUT;
15547 +typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
15550 +typedef struct CK_SSL3_KEY_MAT_PARAMS {
15551 +  CK_ULONG                ulMacSizeInBits;
15552 +  CK_ULONG                ulKeySizeInBits;
15553 +  CK_ULONG                ulIVSizeInBits;
15554 +  CK_BBOOL                bIsExport;
15555 +  CK_SSL3_RANDOM_DATA     RandomInfo;
15556 +  CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
15557 +} CK_SSL3_KEY_MAT_PARAMS;
15559 +typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
15561 +/* CK_TLS_PRF_PARAMS is new for version 2.20 */
15562 +typedef struct CK_TLS_PRF_PARAMS {
15563 +  CK_BYTE_PTR  pSeed;
15564 +  CK_ULONG     ulSeedLen;
15565 +  CK_BYTE_PTR  pLabel;
15566 +  CK_ULONG     ulLabelLen;
15567 +  CK_BYTE_PTR  pOutput;
15568 +  CK_ULONG_PTR pulOutputLen;
15569 +} CK_TLS_PRF_PARAMS;
15571 +typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
15573 +/* WTLS is new for version 2.20 */
15574 +typedef struct CK_WTLS_RANDOM_DATA {
15575 +  CK_BYTE_PTR pClientRandom;
15576 +  CK_ULONG    ulClientRandomLen;
15577 +  CK_BYTE_PTR pServerRandom;
15578 +  CK_ULONG    ulServerRandomLen;
15579 +} CK_WTLS_RANDOM_DATA;
15581 +typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
15583 +typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
15584 +  CK_MECHANISM_TYPE   DigestMechanism;
15585 +  CK_WTLS_RANDOM_DATA RandomInfo;
15586 +  CK_BYTE_PTR         pVersion;
15587 +} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
15589 +typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
15590 +  CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
15592 +typedef struct CK_WTLS_PRF_PARAMS {
15593 +  CK_MECHANISM_TYPE DigestMechanism;
15594 +  CK_BYTE_PTR       pSeed;
15595 +  CK_ULONG          ulSeedLen;
15596 +  CK_BYTE_PTR       pLabel;
15597 +  CK_ULONG          ulLabelLen;
15598 +  CK_BYTE_PTR       pOutput;
15599 +  CK_ULONG_PTR      pulOutputLen;
15600 +} CK_WTLS_PRF_PARAMS;
15602 +typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
15604 +typedef struct CK_WTLS_KEY_MAT_OUT {
15605 +  CK_OBJECT_HANDLE hMacSecret;
15606 +  CK_OBJECT_HANDLE hKey;
15607 +  CK_BYTE_PTR      pIV;
15608 +} CK_WTLS_KEY_MAT_OUT;
15610 +typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
15612 +typedef struct CK_WTLS_KEY_MAT_PARAMS {
15613 +  CK_MECHANISM_TYPE       DigestMechanism;
15614 +  CK_ULONG                ulMacSizeInBits;
15615 +  CK_ULONG                ulKeySizeInBits;
15616 +  CK_ULONG                ulIVSizeInBits;
15617 +  CK_ULONG                ulSequenceNumber;
15618 +  CK_BBOOL                bIsExport;
15619 +  CK_WTLS_RANDOM_DATA     RandomInfo;
15620 +  CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
15621 +} CK_WTLS_KEY_MAT_PARAMS;
15623 +typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
15625 +/* CMS is new for version 2.20 */
15626 +typedef struct CK_CMS_SIG_PARAMS {
15627 +  CK_OBJECT_HANDLE      certificateHandle;
15628 +  CK_MECHANISM_PTR      pSigningMechanism;
15629 +  CK_MECHANISM_PTR      pDigestMechanism;
15630 +  CK_UTF8CHAR_PTR       pContentType;
15631 +  CK_BYTE_PTR           pRequestedAttributes;
15632 +  CK_ULONG              ulRequestedAttributesLen;
15633 +  CK_BYTE_PTR           pRequiredAttributes;
15634 +  CK_ULONG              ulRequiredAttributesLen;
15635 +} CK_CMS_SIG_PARAMS;
15637 +typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
15639 +typedef struct CK_KEY_DERIVATION_STRING_DATA {
15640 +  CK_BYTE_PTR pData;
15641 +  CK_ULONG    ulLen;
15642 +} CK_KEY_DERIVATION_STRING_DATA;
15644 +typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
15645 +  CK_KEY_DERIVATION_STRING_DATA_PTR;
15648 +/* The CK_EXTRACT_PARAMS is used for the
15649 + * CKM_EXTRACT_KEY_FROM_KEY mechanism.  It specifies which bit
15650 + * of the base key should be used as the first bit of the
15651 + * derived key */
15652 +/* CK_EXTRACT_PARAMS is new for v2.0 */
15653 +typedef CK_ULONG CK_EXTRACT_PARAMS;
15655 +typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
15657 +/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
15658 + * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
15659 + * indicate the Pseudo-Random Function (PRF) used to generate
15660 + * key bits using PKCS #5 PBKDF2. */
15661 +typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
15663 +typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
15665 +/* The following PRFs are defined in PKCS #5 v2.0. */
15666 +#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
15669 +/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
15670 + * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
15671 + * source of the salt value when deriving a key using PKCS #5
15672 + * PBKDF2. */
15673 +typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
15675 +typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
15677 +/* The following salt value sources are defined in PKCS #5 v2.0. */
15678 +#define CKZ_SALT_SPECIFIED        0x00000001
15680 +/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
15681 + * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
15682 + * parameters to the CKM_PKCS5_PBKD2 mechanism. */
15683 +typedef struct CK_PKCS5_PBKD2_PARAMS {
15684 +        CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE           saltSource;
15685 +        CK_VOID_PTR                                pSaltSourceData;
15686 +        CK_ULONG                                   ulSaltSourceDataLen;
15687 +        CK_ULONG                                   iterations;
15688 +        CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
15689 +        CK_VOID_PTR                                pPrfData;
15690 +        CK_ULONG                                   ulPrfDataLen;
15691 +        CK_UTF8CHAR_PTR                            pPassword;
15692 +        CK_ULONG_PTR                               ulPasswordLen;
15693 +} CK_PKCS5_PBKD2_PARAMS;
15695 +typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
15697 +/* All CK_OTP structs are new for PKCS #11 v2.20 amendment 3 */
15699 +typedef CK_ULONG CK_OTP_PARAM_TYPE;
15700 +typedef CK_OTP_PARAM_TYPE CK_PARAM_TYPE; /* B/w compatibility */
15702 +typedef struct CK_OTP_PARAM {
15703 +    CK_OTP_PARAM_TYPE type;
15704 +    CK_VOID_PTR pValue;
15705 +    CK_ULONG ulValueLen;
15706 +} CK_OTP_PARAM;
15708 +typedef CK_OTP_PARAM CK_PTR CK_OTP_PARAM_PTR;
15710 +typedef struct CK_OTP_PARAMS {
15711 +    CK_OTP_PARAM_PTR pParams;
15712 +    CK_ULONG ulCount;
15713 +} CK_OTP_PARAMS;
15715 +typedef CK_OTP_PARAMS CK_PTR CK_OTP_PARAMS_PTR;
15717 +typedef struct CK_OTP_SIGNATURE_INFO {
15718 +    CK_OTP_PARAM_PTR pParams;
15719 +    CK_ULONG ulCount;
15720 +} CK_OTP_SIGNATURE_INFO;
15722 +typedef CK_OTP_SIGNATURE_INFO CK_PTR CK_OTP_SIGNATURE_INFO_PTR;
15724 +/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */
15725 +#define CK_OTP_VALUE          0
15726 +#define CK_OTP_PIN            1
15727 +#define CK_OTP_CHALLENGE      2
15728 +#define CK_OTP_TIME           3
15729 +#define CK_OTP_COUNTER        4
15730 +#define CK_OTP_FLAGS          5
15731 +#define CK_OTP_OUTPUT_LENGTH  6
15732 +#define CK_OTP_OUTPUT_FORMAT  7
15734 +/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */
15735 +#define CKF_NEXT_OTP          0x00000001
15736 +#define CKF_EXCLUDE_TIME      0x00000002
15737 +#define CKF_EXCLUDE_COUNTER   0x00000004
15738 +#define CKF_EXCLUDE_CHALLENGE 0x00000008
15739 +#define CKF_EXCLUDE_PIN       0x00000010
15740 +#define CKF_USER_FRIENDLY_OTP 0x00000020
15742 +/* CK_KIP_PARAMS is new for PKCS #11 v2.20 amendment 2 */
15743 +typedef struct CK_KIP_PARAMS {
15744 +    CK_MECHANISM_PTR  pMechanism;
15745 +    CK_OBJECT_HANDLE  hKey;
15746 +    CK_BYTE_PTR       pSeed;
15747 +    CK_ULONG          ulSeedLen;
15748 +} CK_KIP_PARAMS;
15750 +typedef CK_KIP_PARAMS CK_PTR CK_KIP_PARAMS_PTR;
15752 +/* CK_AES_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
15753 +typedef struct CK_AES_CTR_PARAMS {
15754 +    CK_ULONG ulCounterBits;
15755 +    CK_BYTE cb[16];
15756 +} CK_AES_CTR_PARAMS;
15758 +typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR;
15760 +/* CK_CAMELLIA_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
15761 +typedef struct CK_CAMELLIA_CTR_PARAMS {
15762 +    CK_ULONG ulCounterBits;
15763 +    CK_BYTE cb[16];
15764 +} CK_CAMELLIA_CTR_PARAMS;
15766 +typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR;
15768 +/* CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
15769 +typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS {
15770 +    CK_BYTE      iv[16];
15771 +    CK_BYTE_PTR  pData;
15772 +    CK_ULONG     length;
15773 +} CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS;
15775 +typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
15777 +/* CK_ARIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
15778 +typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS {
15779 +    CK_BYTE      iv[16];
15780 +    CK_BYTE_PTR  pData;
15781 +    CK_ULONG     length;
15782 +} CK_ARIA_CBC_ENCRYPT_DATA_PARAMS;
15784 +typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
15786 +#endif
15787 Index: openssl/util/libeay.num
15788 diff -u openssl/util/libeay.num:1.8.2.1.6.1.4.1 openssl/util/libeay.num:1.9.2.2
15789 --- openssl/util/libeay.num:1.8.2.1.6.1.4.1     Thu Jul  3 12:17:29 2014
15790 +++ openssl/util/libeay.num     Thu Jul  3 12:35:43 2014
15791 @@ -4196,3 +4196,5 @@
15792  OPENSSL_strncasecmp                     4566   EXIST::FUNCTION:
15793  OPENSSL_gmtime                          4567   EXIST::FUNCTION:
15794  OPENSSL_gmtime_adj                      4568   EXIST::FUNCTION:
15795 +ENGINE_load_pk11ca                      4569   EXIST::FUNCTION:HW_PKCS11CA,ENGINE
15796 +ENGINE_load_pk11so                      4569   EXIST::FUNCTION:HW_PKCS11SO,ENGINE
15797 Index: openssl/util/mk1mf.pl
15798 diff -u openssl/util/mk1mf.pl:1.9.2.1 openssl/util/mk1mf.pl:1.9
15799 --- openssl/util/mk1mf.pl:1.9.2.1       Sun Jan 15 16:09:52 2012
15800 +++ openssl/util/mk1mf.pl       Mon Jun 13 17:13:56 2011
15801 @@ -109,6 +109,8 @@
15802         no-ecdh                                 - No ECDH
15803         no-engine                               - No engine
15804         no-hw                                   - No hw
15805 +       no-hw-pkcs11ca                          - No hw PKCS#11 CA flavor
15806 +       no-hw-pkcs11so                          - No hw PKCS#11 SO flavor
15807         nasm                                    - Use NASM for x86 asm
15808         nw-nasm                                 - Use NASM x86 asm for NetWare
15809         nw-mwasm                                - Use Metrowerks x86 asm for NetWare
15810 @@ -270,6 +272,8 @@
15811  $cflags.=" -DOPENSSL_NO_GOST" if $no_gost;
15812  $cflags.=" -DOPENSSL_NO_ENGINE"   if $no_engine;
15813  $cflags.=" -DOPENSSL_NO_HW"   if $no_hw;
15814 +$cflags.=" -DOPENSSL_NO_HW_PKCS11CA"   if $no_hw_pkcs11ca;
15815 +$cflags.=" -DOPENSSL_NO_HW_PKCS11SO"   if $no_hw_pkcs11so;
15816  $cflags.=" -DOPENSSL_NO_JPAKE"    if $no_jpake;
15817  $cflags.= " -DZLIB" if $zlib_opt;
15818  $cflags.= " -DZLIB_SHARED" if $zlib_opt == 2;
15819 @@ -335,6 +339,9 @@
15820                 $dir=$val;
15821                 }
15823 +       if ($key eq "PK11_LIB_LOCATION")
15824 +               { $cflags .= " -D$key=\\\"$val\\\"" if $val ne "";}
15826         if ($key eq "KRB5_INCLUDES")
15827                 { $cflags .= " $val";}
15829 @@ -1067,6 +1074,8 @@
15830                 "no-gost" => \$no_gost,
15831                 "no-engine" => \$no_engine,
15832                 "no-hw" => \$no_hw,
15833 +               "no-hw-pkcs11ca" => \$no_hw_pkcs11ca,
15834 +               "no-hw-pkcs11so" => \$no_hw_pkcs11so,
15835                 "just-ssl" =>
15836                         [\$no_rc2, \$no_idea, \$no_des, \$no_bf, \$no_cast,
15837                           \$no_md2, \$no_sha, \$no_mdc2, \$no_dsa, \$no_dh,
15838 Index: openssl/util/mkdef.pl
15839 diff -u openssl/util/mkdef.pl:1.7.2.1 openssl/util/mkdef.pl:1.8
15840 --- openssl/util/mkdef.pl:1.7.2.1       Sun Jan 15 16:09:52 2012
15841 +++ openssl/util/mkdef.pl       Sun Jan 15 16:30:10 2012
15842 @@ -94,7 +94,7 @@
15843                          # External "algorithms"
15844                          "FP_API", "STDIO", "SOCK", "KRB5", "DGRAM",
15845                          # Engines
15846 -                        "STATIC_ENGINE", "ENGINE", "HW", "GMP",
15847 +                        "STATIC_ENGINE", "ENGINE", "HW", "GMP", "HW_PKCS11CA", "HW_PKCS11SO",
15848                          # RFC3779
15849                          "RFC3779",
15850                          # TLS
15851 @@ -125,6 +125,7 @@
15852  my $no_md2; my $no_md4; my $no_md5; my $no_sha; my $no_ripemd; my $no_mdc2;
15853  my $no_rsa; my $no_dsa; my $no_dh; my $no_hmac=0; my $no_aes; my $no_krb5;
15854  my $no_ec; my $no_ecdsa; my $no_ecdh; my $no_engine; my $no_hw;
15855 +my $no_pkcs11ca; my $no_pkcs11so;
15856  my $no_fp_api; my $no_static_engine=1; my $no_gmp; my $no_deprecated;
15857  my $no_rfc3779; my $no_psk; my $no_tlsext; my $no_cms; my $no_capieng;
15858  my $no_jpake; my $no_ssl2;
15859 @@ -218,6 +219,8 @@
15860         elsif (/^no-ssl2$/)     { $no_ssl2=1; }
15861         elsif (/^no-capieng$/)  { $no_capieng=1; }
15862         elsif (/^no-jpake$/)    { $no_jpake=1; }
15863 +       elsif (/^no-hw-pkcs11ca$/) { $no_pkcs11ca=1; }
15864 +       elsif (/^no-hw-pkcs11so$/) { $no_pkcs11so=1; }
15865         }
15868 @@ -1165,6 +1168,8 @@
15869                         if ($keyword eq "KRB5" && $no_krb5) { return 0; }
15870                         if ($keyword eq "ENGINE" && $no_engine) { return 0; }
15871                         if ($keyword eq "HW" && $no_hw) { return 0; }
15872 +                       if ($keyword eq "HW_PKCS11CA" && $no_pkcs11ca) { return 0; }
15873 +                       if ($keyword eq "HW_PKCS11SO" && $no_pkcs11so) { return 0; }
15874                         if ($keyword eq "FP_API" && $no_fp_api) { return 0; }
15875                         if ($keyword eq "STATIC_ENGINE" && $no_static_engine) { return 0; }
15876                         if ($keyword eq "GMP" && $no_gmp) { return 0; }
15877 Index: openssl/util/pl/VC-32.pl
15878 diff -u openssl/util/pl/VC-32.pl:1.7.2.1 openssl/util/pl/VC-32.pl:1.7
15879 --- openssl/util/pl/VC-32.pl:1.7.2.1    Sun Jan 15 16:09:52 2012
15880 +++ openssl/util/pl/VC-32.pl    Mon Jun 13 17:13:57 2011
15881 @@ -36,7 +36,7 @@
15882      my $f = $shlib?' /MD':' /MT';
15883      $lib_cflag='/Zl' if (!$shlib);     # remove /DEFAULTLIBs from static lib
15884      $opt_cflags=$f.' /Ox';
15885 -    $dbg_cflags=$f.'d /Od -DDEBUG -D_DEBUG';
15886 +    $dbg_cflags=$f.'d /Od /Zi -DDEBUG -D_DEBUG';
15887      $lflags="/nologo /subsystem:console /opt:ref";
15889      *::perlasm_compile_target = sub {