etc/services - sync with NetBSD-8
[minix.git] / external / bsd / bind / dist / bin / pkcs11 / openssl-1.0.1j-patch
blob7aa2134a51ce2d6d0cffd79bae61fbff8461e910
1 Index: openssl/Configure
2 diff -u openssl/Configure:1.9.2.1.2.1.2.1.2.1.2.1.2.1.4.1 openssl/Configure:1.16
3 --- openssl/Configure:1.9.2.1.2.1.2.1.2.1.2.1.2.1.4.1   Fri Jan  2 14:55:31 2015
4 +++ openssl/Configure   Fri Jan  2 14:56:42 2015
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] [sctp] [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] [sctp] [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 @@ -352,7 +358,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 @@ -360,7 +366,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::-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::-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  "linux64-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}:64:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR):::64",
43  #### So called "highgprs" target for z/Architecture CPUs
44  # "Highgprs" is kernel feature first implemented in Linux 2.6.32, see
45 @@ -657,6 +663,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 @@ -877,6 +887,14 @@
57                                 $_ =~ s/%([0-9a-f]{1,2})/chr(hex($1))/gei;
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 @@ -1044,6 +1062,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 @@ -1121,6 +1155,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 @@ -1210,6 +1263,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 @@ -1599,6 +1654,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.2.1.2.1.2.1.2.1 openssl/Makefile.org:1.10
139 --- openssl/Makefile.org:1.5.2.1.2.1.2.1.2.1.2.1.2.1    Mon Apr 14 12:42:45 2014
140 +++ openssl/Makefile.org        Mon Apr 14 12:44:20 2014
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.8
153 --- /dev/null   Fri Jan  2 14:59:07 2015
154 +++ openssl/README.pkcs11       Fri Oct  4 14:16:43 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.4.1.10.1 openssl/crypto/opensslconf.h:1.8
424 --- openssl/crypto/opensslconf.h:1.6.2.1.4.1.10.1       Fri Jan  2 14:55:34 2015
425 +++ openssl/crypto/opensslconf.h        Fri Jan  2 14:56:43 2015
426 @@ -41,6 +41,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 @@ -82,6 +85,8 @@
437  # endif
438  #endif
440 +#define OPENSSL_CPUID_OBJ
442  /* crypto/opensslconf.h.in */
444  /* Generate 80386 code? */
445 @@ -128,7 +133,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 @@ -136,7 +141,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 @@ -147,9 +152,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 @@ -161,7 +166,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 @@ -191,7 +196,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.4.1 openssl/crypto/engine/Makefile:1.9
508 --- openssl/crypto/engine/Makefile:1.8.2.1.4.1  Tue Jun 19 15:30:00 2012
509 +++ openssl/crypto/engine/Makefile      Tue Jun 19 16:18:00 2012
510 @@ -22,13 +22,15 @@
511         tb_rsa.c tb_dsa.c tb_ecdsa.c tb_dh.c tb_ecdh.c tb_rand.c tb_store.c \
512         tb_cipher.c tb_digest.c tb_pkmeth.c tb_asnmth.c \
513         eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c \
514 -       eng_rsax.c eng_rdrand.c
515 +       eng_rsax.c eng_rdrand.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_rsax.o eng_rdrand.o
523 +       eng_rsax.o eng_rdrand.o \
524 +       hw_pk11.o hw_pk11_pub.o hw_pk11so.o hw_pk11so_pub.o
526  SRC= $(LIBSRC)
528 @@ -294,6 +296,83 @@
529  eng_table.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
530  eng_table.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
531  eng_table.o: eng_table.c
532 +hw_pk11.o: ../../e_os.h ../../include/openssl/aes.h
533 +hw_pk11.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
534 +hw_pk11.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h
535 +hw_pk11.o: ../../include/openssl/crypto.h ../../include/openssl/dh.h
536 +hw_pk11.o: ../../include/openssl/dsa.h ../../include/openssl/dso.h
537 +hw_pk11.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h
538 +hw_pk11.o: ../../include/openssl/ecdh.h ../../include/openssl/ecdsa.h
539 +hw_pk11.o: ../../include/openssl/engine.h ../../include/openssl/err.h
540 +hw_pk11.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
541 +hw_pk11.o: ../../include/openssl/md5.h ../../include/openssl/obj_mac.h
542 +hw_pk11.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
543 +hw_pk11.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
544 +hw_pk11.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
545 +hw_pk11.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
546 +hw_pk11.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
547 +hw_pk11.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
548 +hw_pk11.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
549 +hw_pk11.o: ../../include/openssl/x509_vfy.h ../cryptlib.h cryptoki.h hw_pk11.c
550 +hw_pk11.o: hw_pk11_err.c hw_pk11_err.h hw_pk11ca.h pkcs11.h pkcs11f.h pkcs11t.h
551 +hw_pk11_pub.o: ../../e_os.h ../../include/openssl/asn1.h
552 +hw_pk11_pub.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
553 +hw_pk11_pub.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
554 +hw_pk11_pub.o: ../../include/openssl/dh.h ../../include/openssl/dsa.h
555 +hw_pk11_pub.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
556 +hw_pk11_pub.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
557 +hw_pk11_pub.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
558 +hw_pk11_pub.o: ../../include/openssl/err.h ../../include/openssl/evp.h
559 +hw_pk11_pub.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
560 +hw_pk11_pub.o: ../../include/openssl/objects.h
561 +hw_pk11_pub.o: ../../include/openssl/opensslconf.h
562 +hw_pk11_pub.o: ../../include/openssl/opensslv.h
563 +hw_pk11_pub.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
564 +hw_pk11_pub.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
565 +hw_pk11_pub.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
566 +hw_pk11_pub.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
567 +hw_pk11_pub.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
568 +hw_pk11_pub.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
569 +hw_pk11_pub.o: ../cryptlib.h cryptoki.h hw_pk11_err.h hw_pk11_pub.c hw_pk11ca.h
570 +hw_pk11_pub.o: pkcs11.h pkcs11f.h pkcs11t.h
571 +hw_pk11so.o: ../../e_os.h ../../include/openssl/asn1.h
572 +hw_pk11so.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
573 +hw_pk11so.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
574 +hw_pk11so.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
575 +hw_pk11so.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
576 +hw_pk11so.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
577 +hw_pk11so.o: ../../include/openssl/err.h ../../include/openssl/evp.h
578 +hw_pk11so.o: ../../include/openssl/lhash.h ../../include/openssl/md5.h
579 +hw_pk11so.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
580 +hw_pk11so.o: ../../include/openssl/opensslconf.h
581 +hw_pk11so.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
582 +hw_pk11so.o: ../../include/openssl/pem.h ../../include/openssl/pem2.h
583 +hw_pk11so.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
584 +hw_pk11so.o: ../../include/openssl/rsa.h ../../include/openssl/safestack.h
585 +hw_pk11so.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
586 +hw_pk11so.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
587 +hw_pk11so.o: ../../include/openssl/x509_vfy.h ../cryptlib.h cryptoki.h
588 +hw_pk11so.o: hw_pk11_err.c hw_pk11_err.h hw_pk11so.c hw_pk11so.h pkcs11.h
589 +hw_pk11so.o: pkcs11f.h pkcs11t.h
590 +hw_pk11so_pub.o: ../../e_os.h ../../include/openssl/asn1.h
591 +hw_pk11so_pub.o: ../../include/openssl/bio.h ../../include/openssl/bn.h
592 +hw_pk11so_pub.o: ../../include/openssl/buffer.h ../../include/openssl/crypto.h
593 +hw_pk11so_pub.o: ../../include/openssl/dso.h ../../include/openssl/e_os2.h
594 +hw_pk11so_pub.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
595 +hw_pk11so_pub.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
596 +hw_pk11so_pub.o: ../../include/openssl/err.h ../../include/openssl/evp.h
597 +hw_pk11so_pub.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
598 +hw_pk11so_pub.o: ../../include/openssl/objects.h
599 +hw_pk11so_pub.o: ../../include/openssl/opensslconf.h
600 +hw_pk11so_pub.o: ../../include/openssl/opensslv.h
601 +hw_pk11so_pub.o: ../../include/openssl/ossl_typ.h ../../include/openssl/pem.h
602 +hw_pk11so_pub.o: ../../include/openssl/pem2.h ../../include/openssl/pkcs7.h
603 +hw_pk11so_pub.o: ../../include/openssl/rand.h ../../include/openssl/rsa.h
604 +hw_pk11so_pub.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
605 +hw_pk11so_pub.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
606 +hw_pk11so_pub.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
607 +hw_pk11so_pub.o: ../cryptlib.h cryptoki.h hw_pk11_err.h hw_pk11so.h
608 +hw_pk11so_pub.o: hw_pk11so_pub.c pkcs11.h pkcs11f.h pkcs11t.h
609  tb_asnmth.o: ../../e_os.h ../../include/openssl/asn1.h
610  tb_asnmth.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
611  tb_asnmth.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
612 Index: openssl/crypto/engine/cryptoki.h
613 diff -u /dev/null openssl/crypto/engine/cryptoki.h:1.4
614 --- /dev/null   Fri Jan  2 14:59:08 2015
615 +++ openssl/crypto/engine/cryptoki.h    Thu Dec 18 00:14:12 2008
616 @@ -0,0 +1,103 @@
618 + * CDDL HEADER START
619 + *
620 + * The contents of this file are subject to the terms of the
621 + * Common Development and Distribution License, Version 1.0 only
622 + * (the "License").  You may not use this file except in compliance
623 + * with the License.
624 + *
625 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
626 + * or http://www.opensolaris.org/os/licensing.
627 + * See the License for the specific language governing permissions
628 + * and limitations under the License.
629 + *
630 + * When distributing Covered Code, include this CDDL HEADER in each
631 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
632 + * If applicable, add the following below this CDDL HEADER, with the
633 + * fields enclosed by brackets "[]" replaced with your own identifying
634 + * information: Portions Copyright [yyyy] [name of copyright owner]
635 + *
636 + * CDDL HEADER END
637 + */
639 + * Copyright 2003 Sun Microsystems, Inc.   All rights reserved.
640 + * Use is subject to license terms.
641 + */
643 +#ifndef        _CRYPTOKI_H
644 +#define        _CRYPTOKI_H
646 +/* ident       "@(#)cryptoki.h 1.2     05/06/08 SMI" */
648 +#ifdef __cplusplus
649 +extern "C" {
650 +#endif
652 +#ifndef        CK_PTR
653 +#define        CK_PTR *
654 +#endif
656 +#ifndef CK_DEFINE_FUNCTION
657 +#define        CK_DEFINE_FUNCTION(returnType, name) returnType name
658 +#endif
660 +#ifndef CK_DECLARE_FUNCTION
661 +#define        CK_DECLARE_FUNCTION(returnType, name) returnType name
662 +#endif
664 +#ifndef CK_DECLARE_FUNCTION_POINTER
665 +#define        CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
666 +#endif
668 +#ifndef CK_CALLBACK_FUNCTION
669 +#define        CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
670 +#endif
672 +#ifndef NULL_PTR
673 +#include <unistd.h>    /* For NULL */
674 +#define        NULL_PTR NULL
675 +#endif
678 + * pkcs11t.h defines TRUE and FALSE in a way that upsets lint
679 + */
680 +#ifndef        CK_DISABLE_TRUE_FALSE
681 +#define        CK_DISABLE_TRUE_FALSE
682 +#ifndef        TRUE
683 +#define        TRUE    1
684 +#endif /* TRUE */
685 +#ifndef        FALSE
686 +#define        FALSE   0
687 +#endif /* FALSE */
688 +#endif /* CK_DISABLE_TRUE_FALSE */
690 +#undef CK_PKCS11_FUNCTION_INFO
692 +#include "pkcs11.h"
694 +/* Solaris specific functions */
696 +#include <stdlib.h>
699 + * SUNW_C_GetMechSession will initialize the framework and do all
700 + * the necessary PKCS#11 calls to create a session capable of
701 + * providing operations on the requested mechanism
702 + */
703 +CK_RV SUNW_C_GetMechSession(CK_MECHANISM_TYPE mech,
704 +    CK_SESSION_HANDLE_PTR hSession);
707 + * SUNW_C_KeyToObject will create a secret key object for the given
708 + * mechanism from the rawkey data.
709 + */
710 +CK_RV SUNW_C_KeyToObject(CK_SESSION_HANDLE hSession,
711 +    CK_MECHANISM_TYPE mech, const void *rawkey, size_t rawkey_len,
712 +    CK_OBJECT_HANDLE_PTR obj);
715 +#ifdef __cplusplus
717 +#endif
719 +#endif /* _CRYPTOKI_H */
720 Index: openssl/crypto/engine/eng_all.c
721 diff -u openssl/crypto/engine/eng_all.c:1.5.2.1.4.1 openssl/crypto/engine/eng_all.c:1.6
722 --- openssl/crypto/engine/eng_all.c:1.5.2.1.4.1 Tue Jun 19 15:30:00 2012
723 +++ openssl/crypto/engine/eng_all.c     Tue Jun 19 16:18:00 2012
724 @@ -119,6 +119,14 @@
725  #if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
726         ENGINE_load_capi();
727  #endif
728 +#ifndef OPENSSL_NO_HW_PKCS11
729 +#ifndef OPENSSL_NO_HW_PKCS11CA
730 +       ENGINE_load_pk11ca();
731 +#endif
732 +#ifndef OPENSSL_NO_HW_PKCS11SO
733 +       ENGINE_load_pk11so();
734 +#endif
735 +#endif
736  #endif
737         ENGINE_register_all_complete();
738         }
739 Index: openssl/crypto/engine/engine.h
740 diff -u openssl/crypto/engine/engine.h:1.5.2.1.4.1 openssl/crypto/engine/engine.h:1.6
741 --- openssl/crypto/engine/engine.h:1.5.2.1.4.1  Tue Jun 19 15:30:00 2012
742 +++ openssl/crypto/engine/engine.h      Tue Jun 19 16:18:00 2012
743 @@ -343,6 +343,12 @@
744  void ENGINE_load_ubsec(void);
745  void ENGINE_load_padlock(void);
746  void ENGINE_load_capi(void);
747 +#ifndef OPENSSL_NO_HW_PKCS11CA
748 +void ENGINE_load_pk11ca(void);
749 +#endif
750 +#ifndef OPENSSL_NO_HW_PKCS11SO
751 +void ENGINE_load_pk11so(void);
752 +#endif
753  #ifndef OPENSSL_NO_GMP
754  void ENGINE_load_gmp(void);
755  #endif
756 Index: openssl/crypto/engine/hw_pk11.c
757 diff -u /dev/null openssl/crypto/engine/hw_pk11.c:1.33
758 --- /dev/null   Fri Jan  2 14:59:08 2015
759 +++ openssl/crypto/engine/hw_pk11.c     Fri Oct  4 14:07:41 2013
760 @@ -0,0 +1,4010 @@
762 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
763 + * Use is subject to license terms.
764 + */
766 +/* crypto/engine/hw_pk11.c */
768 + * This product includes software developed by the OpenSSL Project for
769 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
770 + *
771 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
772 + * Afchine Madjlessi.
773 + */
775 + * ====================================================================
776 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
777 + *
778 + * Redistribution and use in source and binary forms, with or without
779 + * modification, are permitted provided that the following conditions
780 + * are met:
781 + *
782 + * 1. Redistributions of source code must retain the above copyright
783 + *    notice, this list of conditions and the following disclaimer.
784 + *
785 + * 2. Redistributions in binary form must reproduce the above copyright
786 + *    notice, this list of conditions and the following disclaimer in
787 + *    the documentation and/or other materials provided with the
788 + *    distribution.
789 + *
790 + * 3. All advertising materials mentioning features or use of this
791 + *    software must display the following acknowledgment:
792 + *    "This product includes software developed by the OpenSSL Project
793 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
794 + *
795 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
796 + *    endorse or promote products derived from this software without
797 + *    prior written permission. For written permission, please contact
798 + *    licensing@OpenSSL.org.
799 + *
800 + * 5. Products derived from this software may not be called "OpenSSL"
801 + *    nor may "OpenSSL" appear in their names without prior written
802 + *    permission of the OpenSSL Project.
803 + *
804 + * 6. Redistributions of any form whatsoever must retain the following
805 + *    acknowledgment:
806 + *    "This product includes software developed by the OpenSSL Project
807 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
808 + *
809 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
810 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
811 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
812 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
813 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
814 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
815 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
816 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
817 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
818 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
819 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
820 + * OF THE POSSIBILITY OF SUCH DAMAGE.
821 + * ====================================================================
822 + *
823 + * This product includes cryptographic software written by Eric Young
824 + * (eay@cryptsoft.com).  This product includes software written by Tim
825 + * Hudson (tjh@cryptsoft.com).
826 + *
827 + */
829 +#include <stdio.h>
830 +#include <stdlib.h>
831 +#include <string.h>
832 +#include <sys/types.h>
834 +#include <openssl/e_os2.h>
835 +#include <openssl/crypto.h>
836 +#include <cryptlib.h>
837 +#include <openssl/engine.h>
838 +#include <openssl/dso.h>
839 +#include <openssl/err.h>
840 +#include <openssl/bn.h>
841 +#include <openssl/md5.h>
842 +#include <openssl/pem.h>
843 +#ifndef OPENSSL_NO_RSA
844 +#include <openssl/rsa.h>
845 +#endif
846 +#ifndef OPENSSL_NO_DSA
847 +#include <openssl/dsa.h>
848 +#endif
849 +#ifndef OPENSSL_NO_DH
850 +#include <openssl/dh.h>
851 +#endif
852 +#include <openssl/rand.h>
853 +#include <openssl/objects.h>
854 +#include <openssl/x509.h>
855 +#include <openssl/aes.h>
856 +#include <openssl/des.h>
858 +#ifdef OPENSSL_SYS_WIN32
859 +typedef int pid_t;
860 +#define getpid() GetCurrentProcessId()
861 +#define NOPTHREADS
862 +#ifndef NULL_PTR
863 +#define NULL_PTR NULL
864 +#endif
865 +#define CK_DEFINE_FUNCTION(returnType, name) \
866 +       returnType __declspec(dllexport) name
867 +#define CK_DECLARE_FUNCTION(returnType, name) \
868 +       returnType __declspec(dllimport) name
869 +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
870 +       returnType __declspec(dllimport) (* name)
871 +#else
872 +#include <signal.h>
873 +#include <unistd.h>
874 +#include <dlfcn.h>
875 +#endif
877 +/* Debug mutexes */
878 +/*#undef DEBUG_MUTEX */
879 +#define DEBUG_MUTEX
881 +#ifndef NOPTHREADS
882 +/* for pthread error check on Linuxes */
883 +#ifdef DEBUG_MUTEX
884 +#define __USE_UNIX98
885 +#endif
886 +#include <pthread.h>
887 +#endif
889 +#ifndef OPENSSL_NO_HW
890 +#ifndef OPENSSL_NO_HW_PK11
891 +#ifndef OPENSSL_NO_HW_PK11CA
893 +/* label for debug messages printed on stderr */
894 +#define        PK11_DBG        "PKCS#11 ENGINE DEBUG"
895 +/* prints a lot of debug messages on stderr about slot selection process */
896 +/* #undef      DEBUG_SLOT_SELECTION */
898 + * Solaris specific code. See comment at check_hw_mechanisms() for more
899 + * information.
900 + */
901 +#if defined(__SVR4) && defined(__sun)
902 +#undef SOLARIS_HW_SLOT_SELECTION
903 +#endif
905 +#ifdef OPENSSL_SYS_WIN32
906 +#pragma pack(push, cryptoki, 1)
907 +#include "cryptoki.h"
908 +#include "pkcs11.h"
909 +#pragma pack(pop, cryptoki)
910 +#else
911 +#include "cryptoki.h"
912 +#include "pkcs11.h"
913 +#endif
914 +#include "hw_pk11ca.h"
915 +#include "hw_pk11_err.c"
918 + * We use this lock to prevent multiple C_Login()s, guard getpassphrase(),
919 + * uri_struct manipulation, and static token info. All of that is used by the
920 + * RSA keys by reference feature.
921 + */
922 +#ifndef NOPTHREADS
923 +pthread_mutex_t *token_lock;
924 +#endif
926 +#ifdef SOLARIS_HW_SLOT_SELECTION
928 + * Tables for symmetric ciphers and digest mechs found in the pkcs11_kernel
929 + * library. See comment at check_hw_mechanisms() for more information.
930 + */
931 +static int *hw_cnids;
932 +static int *hw_dnids;
933 +#endif /* SOLARIS_HW_SLOT_SELECTION */
935 +/* PKCS#11 session caches and their locks for all operation types */
936 +static PK11_CACHE session_cache[OP_MAX];
939 + * We cache the flags so that we do not have to run C_GetTokenInfo() again when
940 + * logging into the token.
941 + */
942 +CK_FLAGS pubkey_token_flags;
945 + * As stated in v2.20, 11.7 Object Management Function, in section for
946 + * C_FindObjectsInit(), at most one search operation may be active at a given
947 + * time in a given session. Therefore, C_Find{,Init,Final}Objects() should be
948 + * grouped together to form one atomic search operation. This is already
949 + * ensured by the property of unique PKCS#11 session handle used for each
950 + * PK11_SESSION object.
951 + *
952 + * This is however not the biggest concern - maintaining consistency of the
953 + * underlying object store is more important. The same section of the spec also
954 + * says that one thread can be in the middle of a search operation while another
955 + * thread destroys the object matching the search template which would result in
956 + * invalid handle returned from the search operation.
957 + *
958 + * Hence, the following locks are used for both protection of the object stores.
959 + * They are also used for active list protection.
960 + */
961 +#ifndef NOPTHREADS
962 +pthread_mutex_t *find_lock[OP_MAX] = { NULL };
963 +#endif
966 + * lists of asymmetric key handles which are active (referenced by at least one
967 + * PK11_SESSION structure, either held by a thread or present in free_session
968 + * list) for given algorithm type
969 + */
970 +PK11_active *active_list[OP_MAX] = { NULL };
973 + * Create all secret key objects in a global session so that they are available
974 + * to use for other sessions. These other sessions may be opened or closed
975 + * without losing the secret key objects.
976 + */
977 +static CK_SESSION_HANDLE       global_session = CK_INVALID_HANDLE;
979 +/* ENGINE level stuff */
980 +static int pk11_init(ENGINE *e);
981 +static int pk11_library_init(ENGINE *e);
982 +static int pk11_finish(ENGINE *e);
983 +static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
984 +static int pk11_destroy(ENGINE *e);
986 +/* RAND stuff */
987 +static void pk11_rand_seed(const void *buf, int num);
988 +static void pk11_rand_add(const void *buf, int num, double add_entropy);
989 +static void pk11_rand_cleanup(void);
990 +static int pk11_rand_bytes(unsigned char *buf, int num);
991 +static int pk11_rand_status(void);
993 +/* These functions are also used in other files */
994 +PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
995 +void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
997 +/* active list manipulation functions used in this file */
998 +extern int pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type);
999 +extern void pk11_free_active_list(PK11_OPTYPE type);
1001 +#ifndef OPENSSL_NO_RSA
1002 +int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
1003 +int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
1004 +int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
1005 +#endif
1006 +#ifndef OPENSSL_NO_DSA
1007 +int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
1008 +int pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
1009 +int pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
1010 +#endif
1011 +#ifndef OPENSSL_NO_DH
1012 +int pk11_destroy_dh_key_objects(PK11_SESSION *session);
1013 +int pk11_destroy_dh_object(PK11_SESSION *session, CK_BBOOL uselock);
1014 +#endif
1016 +/* Local helper functions */
1017 +static int pk11_free_all_sessions(void);
1018 +static int pk11_free_session_list(PK11_OPTYPE optype);
1019 +static int pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype);
1020 +static int pk11_destroy_cipher_key_objects(PK11_SESSION *session);
1021 +static int pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
1022 +       CK_BBOOL persistent);
1023 +static const char *get_PK11_LIBNAME(void);
1024 +static void free_PK11_LIBNAME(void);
1025 +static long set_PK11_LIBNAME(const char *name);
1027 +/* Symmetric cipher and digest support functions */
1028 +static int cipher_nid_to_pk11(int nid);
1029 +static int pk11_usable_ciphers(const int **nids);
1030 +static int pk11_usable_digests(const int **nids);
1031 +static int pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
1032 +       const unsigned char *iv, int enc);
1033 +static int pk11_cipher_final(PK11_SESSION *sp);
1034 +#if OPENSSL_VERSION_NUMBER < 0x10000000L
1035 +static int pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
1036 +       const unsigned char *in, unsigned int inl);
1037 +#else
1038 +static int pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
1039 +       const unsigned char *in, size_t inl);
1040 +#endif
1041 +static int pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx);
1042 +static int pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
1043 +       const int **nids, int nid);
1044 +static int pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
1045 +       const int **nids, int nid);
1046 +static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
1047 +       const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp);
1048 +static int check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key,
1049 +       int key_len);
1050 +static int md_nid_to_pk11(int nid);
1051 +static int pk11_digest_init(EVP_MD_CTX *ctx);
1052 +static int pk11_digest_update(EVP_MD_CTX *ctx, const void *data,
1053 +       size_t count);
1054 +static int pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md);
1055 +static int pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);
1056 +static int pk11_digest_cleanup(EVP_MD_CTX *ctx);
1058 +static int pk11_choose_slots(int *any_slot_found);
1059 +static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
1060 +    CK_SLOT_ID current_slot, int *current_slot_n_cipher,
1061 +    int *local_cipher_nids);
1062 +static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
1063 +    CK_SLOT_ID current_slot, int *current_slot_n_digest,
1064 +    int *local_digest_nids);
1065 +static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR, int slot_id,
1066 +    CK_MECHANISM_TYPE mech, int *current_slot_n_cipher, int *local_cipher_nids,
1067 +    int id);
1068 +static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
1069 +    CK_MECHANISM_TYPE mech, int *current_slot_n_digest, int *local_digest_nids,
1070 +    int id);
1072 +static int pk11_init_all_locks(void);
1073 +static void pk11_free_all_locks(void);
1075 +#ifdef SOLARIS_HW_SLOT_SELECTION
1076 +static int check_hw_mechanisms(void);
1077 +static int nid_in_table(int nid, int *nid_table);
1078 +#endif /* SOLARIS_HW_SLOT_SELECTION */
1080 +/* Index for the supported ciphers */
1081 +enum pk11_cipher_id {
1082 +       PK11_DES_CBC,
1083 +       PK11_DES3_CBC,
1084 +       PK11_DES_ECB,
1085 +       PK11_DES3_ECB,
1086 +       PK11_RC4,
1087 +       PK11_AES_128_CBC,
1088 +       PK11_AES_192_CBC,
1089 +       PK11_AES_256_CBC,
1090 +       PK11_AES_128_ECB,
1091 +       PK11_AES_192_ECB,
1092 +       PK11_AES_256_ECB,
1093 +       PK11_AES_128_CTR,
1094 +       PK11_AES_192_CTR,
1095 +       PK11_AES_256_CTR,
1096 +       PK11_BLOWFISH_CBC,
1097 +       PK11_CIPHER_MAX
1100 +/* Index for the supported digests */
1101 +enum pk11_digest_id {
1102 +       PK11_MD5,
1103 +       PK11_SHA1,
1104 +       PK11_SHA224,
1105 +       PK11_SHA256,
1106 +       PK11_SHA384,
1107 +       PK11_SHA512,
1108 +       PK11_DIGEST_MAX
1111 +#define        TRY_OBJ_DESTROY(sp, obj_hdl, retval, uselock, alg_type, priv)   \
1112 +       {                                                               \
1113 +       if (uselock)                                                    \
1114 +               LOCK_OBJSTORE(alg_type);                                \
1115 +       if (pk11_active_delete(obj_hdl, alg_type) == 1)                 \
1116 +               {                                                       \
1117 +                 retval = pk11_destroy_object(sp->session, obj_hdl,    \
1118 +                 priv ? sp->priv_persistent : sp->pub_persistent);     \
1119 +               }                                                       \
1120 +       if (uselock)                                                    \
1121 +               UNLOCK_OBJSTORE(alg_type);                              \
1122 +       }
1124 +static int cipher_nids[PK11_CIPHER_MAX];
1125 +static int digest_nids[PK11_DIGEST_MAX];
1126 +static int cipher_count                = 0;
1127 +static int digest_count                = 0;
1128 +static CK_BBOOL pk11_have_rsa  = CK_FALSE;
1129 +static CK_BBOOL pk11_have_recover = CK_FALSE;
1130 +static CK_BBOOL pk11_have_dsa  = CK_FALSE;
1131 +static CK_BBOOL pk11_have_dh   = CK_FALSE;
1132 +static CK_BBOOL pk11_have_random = CK_FALSE;
1134 +typedef struct PK11_CIPHER_st
1135 +       {
1136 +       enum pk11_cipher_id     id;
1137 +       int                     nid;
1138 +       int                     iv_len;
1139 +       int                     min_key_len;
1140 +       int                     max_key_len;
1141 +       CK_KEY_TYPE             key_type;
1142 +       CK_MECHANISM_TYPE       mech_type;
1143 +       } PK11_CIPHER;
1145 +static PK11_CIPHER ciphers[] =
1146 +       {
1147 +       { PK11_DES_CBC,         NID_des_cbc,            8,       8,   8,
1148 +               CKK_DES,        CKM_DES_CBC, },
1149 +       { PK11_DES3_CBC,        NID_des_ede3_cbc,       8,      24,  24,
1150 +               CKK_DES3,       CKM_DES3_CBC, },
1151 +       { PK11_DES_ECB,         NID_des_ecb,            0,       8,   8,
1152 +               CKK_DES,        CKM_DES_ECB, },
1153 +       { PK11_DES3_ECB,        NID_des_ede3_ecb,       0,      24,  24,
1154 +               CKK_DES3,       CKM_DES3_ECB, },
1155 +       { PK11_RC4,             NID_rc4,                0,      16, 256,
1156 +               CKK_RC4,        CKM_RC4, },
1157 +       { PK11_AES_128_CBC,     NID_aes_128_cbc,        16,     16,  16,
1158 +               CKK_AES,        CKM_AES_CBC, },
1159 +       { PK11_AES_192_CBC,     NID_aes_192_cbc,        16,     24,  24,
1160 +               CKK_AES,        CKM_AES_CBC, },
1161 +       { PK11_AES_256_CBC,     NID_aes_256_cbc,        16,     32,  32,
1162 +               CKK_AES,        CKM_AES_CBC, },
1163 +       { PK11_AES_128_ECB,     NID_aes_128_ecb,        0,      16,  16,
1164 +               CKK_AES,        CKM_AES_ECB, },
1165 +       { PK11_AES_192_ECB,     NID_aes_192_ecb,        0,      24,  24,
1166 +               CKK_AES,        CKM_AES_ECB, },
1167 +       { PK11_AES_256_ECB,     NID_aes_256_ecb,        0,      32,  32,
1168 +               CKK_AES,        CKM_AES_ECB, },
1169 +       { PK11_AES_128_CTR,     NID_aes_128_ctr,        16,     16,  16,
1170 +               CKK_AES,        CKM_AES_CTR, },
1171 +       { PK11_AES_192_CTR,     NID_aes_192_ctr,        16,     24,  24,
1172 +               CKK_AES,        CKM_AES_CTR, },
1173 +       { PK11_AES_256_CTR,     NID_aes_256_ctr,        16,     32,  32,
1174 +               CKK_AES,        CKM_AES_CTR, },
1175 +       { PK11_BLOWFISH_CBC,    NID_bf_cbc,             8,      16,  16,
1176 +               CKK_BLOWFISH,   CKM_BLOWFISH_CBC, },
1177 +       };
1179 +typedef struct PK11_DIGEST_st
1180 +       {
1181 +       enum pk11_digest_id     id;
1182 +       int                     nid;
1183 +       CK_MECHANISM_TYPE       mech_type;
1184 +       } PK11_DIGEST;
1186 +static PK11_DIGEST digests[] =
1187 +       {
1188 +       {PK11_MD5,      NID_md5,        CKM_MD5, },
1189 +       {PK11_SHA1,     NID_sha1,       CKM_SHA_1, },
1190 +       {PK11_SHA224,   NID_sha224,     CKM_SHA224, },
1191 +       {PK11_SHA256,   NID_sha256,     CKM_SHA256, },
1192 +       {PK11_SHA384,   NID_sha384,     CKM_SHA384, },
1193 +       {PK11_SHA512,   NID_sha512,     CKM_SHA512, },
1194 +       {0,             NID_undef,      0xFFFF, },
1195 +       };
1198 + * Structure to be used for the cipher_data/md_data in
1199 + * EVP_CIPHER_CTX/EVP_MD_CTX structures in order to use the same pk11
1200 + * session in multiple cipher_update calls
1201 + */
1202 +typedef struct PK11_CIPHER_STATE_st
1203 +       {
1204 +       PK11_SESSION    *sp;
1205 +       } PK11_CIPHER_STATE;
1209 + * libcrypto EVP stuff - this is how we get wired to EVP so the engine gets
1210 + * called when libcrypto requests a cipher NID.
1211 + *
1212 + * Note how the PK11_CIPHER_STATE is used here.
1213 + */
1215 +/* DES CBC EVP */
1216 +static const EVP_CIPHER pk11_des_cbc =
1217 +       {
1218 +       NID_des_cbc,
1219 +       8, 8, 8,
1220 +       EVP_CIPH_CBC_MODE,
1221 +       pk11_cipher_init,
1222 +       pk11_cipher_do_cipher,
1223 +       pk11_cipher_cleanup,
1224 +       sizeof (PK11_CIPHER_STATE),
1225 +       EVP_CIPHER_set_asn1_iv,
1226 +       EVP_CIPHER_get_asn1_iv,
1227 +       NULL
1228 +       };
1230 +/* 3DES CBC EVP */
1231 +static const EVP_CIPHER pk11_3des_cbc =
1232 +       {
1233 +       NID_des_ede3_cbc,
1234 +       8, 24, 8,
1235 +       EVP_CIPH_CBC_MODE,
1236 +       pk11_cipher_init,
1237 +       pk11_cipher_do_cipher,
1238 +       pk11_cipher_cleanup,
1239 +       sizeof (PK11_CIPHER_STATE),
1240 +       EVP_CIPHER_set_asn1_iv,
1241 +       EVP_CIPHER_get_asn1_iv,
1242 +       NULL
1243 +       };
1246 + * ECB modes don't use an Initial Vector so that's why set_asn1_parameters and
1247 + * get_asn1_parameters fields are set to NULL.
1248 + */
1249 +static const EVP_CIPHER pk11_des_ecb =
1250 +       {
1251 +       NID_des_ecb,
1252 +       8, 8, 8,
1253 +       EVP_CIPH_ECB_MODE,
1254 +       pk11_cipher_init,
1255 +       pk11_cipher_do_cipher,
1256 +       pk11_cipher_cleanup,
1257 +       sizeof (PK11_CIPHER_STATE),
1258 +       NULL,
1259 +       NULL,
1260 +       NULL
1261 +       };
1263 +static const EVP_CIPHER pk11_3des_ecb =
1264 +       {
1265 +       NID_des_ede3_ecb,
1266 +       8, 24, 8,
1267 +       EVP_CIPH_ECB_MODE,
1268 +       pk11_cipher_init,
1269 +       pk11_cipher_do_cipher,
1270 +       pk11_cipher_cleanup,
1271 +       sizeof (PK11_CIPHER_STATE),
1272 +       NULL,
1273 +       NULL,
1274 +       NULL
1275 +       };
1278 +static const EVP_CIPHER pk11_aes_128_cbc =
1279 +       {
1280 +       NID_aes_128_cbc,
1281 +       16, 16, 16,
1282 +       EVP_CIPH_CBC_MODE,
1283 +       pk11_cipher_init,
1284 +       pk11_cipher_do_cipher,
1285 +       pk11_cipher_cleanup,
1286 +       sizeof (PK11_CIPHER_STATE),
1287 +       EVP_CIPHER_set_asn1_iv,
1288 +       EVP_CIPHER_get_asn1_iv,
1289 +       NULL
1290 +       };
1292 +static const EVP_CIPHER pk11_aes_192_cbc =
1293 +       {
1294 +       NID_aes_192_cbc,
1295 +       16, 24, 16,
1296 +       EVP_CIPH_CBC_MODE,
1297 +       pk11_cipher_init,
1298 +       pk11_cipher_do_cipher,
1299 +       pk11_cipher_cleanup,
1300 +       sizeof (PK11_CIPHER_STATE),
1301 +       EVP_CIPHER_set_asn1_iv,
1302 +       EVP_CIPHER_get_asn1_iv,
1303 +       NULL
1304 +       };
1306 +static const EVP_CIPHER pk11_aes_256_cbc =
1307 +       {
1308 +       NID_aes_256_cbc,
1309 +       16, 32, 16,
1310 +       EVP_CIPH_CBC_MODE,
1311 +       pk11_cipher_init,
1312 +       pk11_cipher_do_cipher,
1313 +       pk11_cipher_cleanup,
1314 +       sizeof (PK11_CIPHER_STATE),
1315 +       EVP_CIPHER_set_asn1_iv,
1316 +       EVP_CIPHER_get_asn1_iv,
1317 +       NULL
1318 +       };
1321 + * ECB modes don't use IV so that's why set_asn1_parameters and
1322 + * get_asn1_parameters are set to NULL.
1323 + */
1324 +static const EVP_CIPHER pk11_aes_128_ecb =
1325 +       {
1326 +       NID_aes_128_ecb,
1327 +       16, 16, 0,
1328 +       EVP_CIPH_ECB_MODE,
1329 +       pk11_cipher_init,
1330 +       pk11_cipher_do_cipher,
1331 +       pk11_cipher_cleanup,
1332 +       sizeof (PK11_CIPHER_STATE),
1333 +       NULL,
1334 +       NULL,
1335 +       NULL
1336 +       };
1338 +static const EVP_CIPHER pk11_aes_192_ecb =
1339 +       {
1340 +       NID_aes_192_ecb,
1341 +       16, 24, 0,
1342 +       EVP_CIPH_ECB_MODE,
1343 +       pk11_cipher_init,
1344 +       pk11_cipher_do_cipher,
1345 +       pk11_cipher_cleanup,
1346 +       sizeof (PK11_CIPHER_STATE),
1347 +       NULL,
1348 +       NULL,
1349 +       NULL
1350 +       };
1352 +static const EVP_CIPHER pk11_aes_256_ecb =
1353 +       {
1354 +       NID_aes_256_ecb,
1355 +       16, 32, 0,
1356 +       EVP_CIPH_ECB_MODE,
1357 +       pk11_cipher_init,
1358 +       pk11_cipher_do_cipher,
1359 +       pk11_cipher_cleanup,
1360 +       sizeof (PK11_CIPHER_STATE),
1361 +       NULL,
1362 +       NULL,
1363 +       NULL
1364 +       };
1366 +static const EVP_CIPHER pk11_aes_128_ctr =
1367 +       {
1368 +       NID_aes_128_ctr,
1369 +       16, 16, 16,
1370 +       EVP_CIPH_CBC_MODE,
1371 +       pk11_cipher_init,
1372 +       pk11_cipher_do_cipher,
1373 +       pk11_cipher_cleanup,
1374 +       sizeof (PK11_CIPHER_STATE),
1375 +       EVP_CIPHER_set_asn1_iv,
1376 +       EVP_CIPHER_get_asn1_iv,
1377 +       NULL
1378 +       };
1380 +static const EVP_CIPHER pk11_aes_192_ctr =
1381 +       {
1382 +       NID_aes_192_ctr,
1383 +       16, 24, 16,
1384 +       EVP_CIPH_CBC_MODE,
1385 +       pk11_cipher_init,
1386 +       pk11_cipher_do_cipher,
1387 +       pk11_cipher_cleanup,
1388 +       sizeof (PK11_CIPHER_STATE),
1389 +       EVP_CIPHER_set_asn1_iv,
1390 +       EVP_CIPHER_get_asn1_iv,
1391 +       NULL
1392 +       };
1394 +static const EVP_CIPHER pk11_aes_256_ctr =
1395 +       {
1396 +       NID_aes_256_ctr,
1397 +       16, 32, 16,
1398 +       EVP_CIPH_CBC_MODE,
1399 +       pk11_cipher_init,
1400 +       pk11_cipher_do_cipher,
1401 +       pk11_cipher_cleanup,
1402 +       sizeof (PK11_CIPHER_STATE),
1403 +       EVP_CIPHER_set_asn1_iv,
1404 +       EVP_CIPHER_get_asn1_iv,
1405 +       NULL
1406 +       };
1408 +static const EVP_CIPHER pk11_bf_cbc =
1409 +       {
1410 +       NID_bf_cbc,
1411 +       8, 16, 8,
1412 +       EVP_CIPH_VARIABLE_LENGTH,
1413 +       pk11_cipher_init,
1414 +       pk11_cipher_do_cipher,
1415 +       pk11_cipher_cleanup,
1416 +       sizeof (PK11_CIPHER_STATE),
1417 +       EVP_CIPHER_set_asn1_iv,
1418 +       EVP_CIPHER_get_asn1_iv,
1419 +       NULL
1420 +       };
1422 +static const EVP_CIPHER pk11_rc4 =
1423 +       {
1424 +       NID_rc4,
1425 +       1, 16, 0,
1426 +       EVP_CIPH_VARIABLE_LENGTH,
1427 +       pk11_cipher_init,
1428 +       pk11_cipher_do_cipher,
1429 +       pk11_cipher_cleanup,
1430 +       sizeof (PK11_CIPHER_STATE),
1431 +       NULL,
1432 +       NULL,
1433 +       NULL
1434 +       };
1436 +static const EVP_MD pk11_md5 =
1437 +       {
1438 +       NID_md5,
1439 +       NID_md5WithRSAEncryption,
1440 +       MD5_DIGEST_LENGTH,
1441 +       0,
1442 +       pk11_digest_init,
1443 +       pk11_digest_update,
1444 +       pk11_digest_final,
1445 +       pk11_digest_copy,
1446 +       pk11_digest_cleanup,
1447 +       EVP_PKEY_RSA_method,
1448 +       MD5_CBLOCK,
1449 +       sizeof (PK11_CIPHER_STATE),
1450 +       };
1452 +static const EVP_MD pk11_sha1 =
1453 +       {
1454 +       NID_sha1,
1455 +       NID_sha1WithRSAEncryption,
1456 +       SHA_DIGEST_LENGTH,
1457 +       EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
1458 +       pk11_digest_init,
1459 +       pk11_digest_update,
1460 +       pk11_digest_final,
1461 +       pk11_digest_copy,
1462 +       pk11_digest_cleanup,
1463 +       EVP_PKEY_RSA_method,
1464 +       SHA_CBLOCK,
1465 +       sizeof (PK11_CIPHER_STATE),
1466 +       };
1468 +static const EVP_MD pk11_sha224 =
1469 +       {
1470 +       NID_sha224,
1471 +       NID_sha224WithRSAEncryption,
1472 +       SHA224_DIGEST_LENGTH,
1473 +       EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
1474 +       pk11_digest_init,
1475 +       pk11_digest_update,
1476 +       pk11_digest_final,
1477 +       pk11_digest_copy,
1478 +       pk11_digest_cleanup,
1479 +       EVP_PKEY_RSA_method,
1480 +       /* SHA-224 uses the same cblock size as SHA-256 */
1481 +       SHA256_CBLOCK,
1482 +       sizeof (PK11_CIPHER_STATE),
1483 +       };
1485 +static const EVP_MD pk11_sha256 =
1486 +       {
1487 +       NID_sha256,
1488 +       NID_sha256WithRSAEncryption,
1489 +       SHA256_DIGEST_LENGTH,
1490 +       EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
1491 +       pk11_digest_init,
1492 +       pk11_digest_update,
1493 +       pk11_digest_final,
1494 +       pk11_digest_copy,
1495 +       pk11_digest_cleanup,
1496 +       EVP_PKEY_RSA_method,
1497 +       SHA256_CBLOCK,
1498 +       sizeof (PK11_CIPHER_STATE),
1499 +       };
1501 +static const EVP_MD pk11_sha384 =
1502 +       {
1503 +       NID_sha384,
1504 +       NID_sha384WithRSAEncryption,
1505 +       SHA384_DIGEST_LENGTH,
1506 +       EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
1507 +       pk11_digest_init,
1508 +       pk11_digest_update,
1509 +       pk11_digest_final,
1510 +       pk11_digest_copy,
1511 +       pk11_digest_cleanup,
1512 +       EVP_PKEY_RSA_method,
1513 +       /* SHA-384 uses the same cblock size as SHA-512 */
1514 +       SHA512_CBLOCK,
1515 +       sizeof (PK11_CIPHER_STATE),
1516 +       };
1518 +static const EVP_MD pk11_sha512 =
1519 +       {
1520 +       NID_sha512,
1521 +       NID_sha512WithRSAEncryption,
1522 +       SHA512_DIGEST_LENGTH,
1523 +       EVP_MD_FLAG_PKEY_METHOD_SIGNATURE|EVP_MD_FLAG_DIGALGID_ABSENT,
1524 +       pk11_digest_init,
1525 +       pk11_digest_update,
1526 +       pk11_digest_final,
1527 +       pk11_digest_copy,
1528 +       pk11_digest_cleanup,
1529 +       EVP_PKEY_RSA_method,
1530 +       SHA512_CBLOCK,
1531 +       sizeof (PK11_CIPHER_STATE),
1532 +       };
1535 + * Initialization function. Sets up various PKCS#11 library components.
1536 + * The definitions for control commands specific to this engine
1537 + */
1538 +#define PK11_CMD_SO_PATH               ENGINE_CMD_BASE
1539 +#define PK11_CMD_PIN                   (ENGINE_CMD_BASE+1)
1540 +#define PK11_CMD_SLOT                  (ENGINE_CMD_BASE+2)
1541 +static const ENGINE_CMD_DEFN pk11_cmd_defns[] =
1542 +       {
1543 +               {
1544 +               PK11_CMD_SO_PATH,
1545 +               "SO_PATH",
1546 +               "Specifies the path to the 'pkcs#11' shared library",
1547 +               ENGINE_CMD_FLAG_STRING
1548 +               },
1549 +               {
1550 +               PK11_CMD_PIN,
1551 +               "PIN",
1552 +               "Specifies the pin code",
1553 +               ENGINE_CMD_FLAG_STRING
1554 +               },
1555 +               {
1556 +               PK11_CMD_SLOT,
1557 +               "SLOT",
1558 +               "Specifies the slot (default is auto select)",
1559 +               ENGINE_CMD_FLAG_NUMERIC,
1560 +               },
1561 +               {0, NULL, NULL, 0}
1562 +       };
1565 +static RAND_METHOD pk11_random =
1566 +       {
1567 +       pk11_rand_seed,
1568 +       pk11_rand_bytes,
1569 +       pk11_rand_cleanup,
1570 +       pk11_rand_add,
1571 +       pk11_rand_bytes,
1572 +       pk11_rand_status
1573 +       };
1576 +/* Constants used when creating the ENGINE */
1577 +#ifdef OPENSSL_NO_HW_PK11SO
1578 +#error "can't load both crypto-accelerator and sign-only PKCS#11 engines"
1579 +#endif
1580 +static const char *engine_pk11_id = "pkcs11";
1581 +static const char *engine_pk11_name =
1582 +       "PKCS #11 engine support (crypto accelerator)";
1584 +CK_FUNCTION_LIST_PTR pFuncList = NULL;
1585 +static const char PK11_GET_FUNCTION_LIST[] = "C_GetFunctionList";
1588 + * This is a static string constant for the DSO file name and the function
1589 + * symbol names to bind to. We set it in the Configure script based on whether
1590 + * this is 32 or 64 bit build.
1591 + */
1592 +static const char def_PK11_LIBNAME[] = PK11_LIB_LOCATION;
1594 +static CK_BBOOL mytrue = TRUE;
1595 +static CK_BBOOL myfalse = FALSE;
1596 +/* Needed in hw_pk11_pub.c as well so that's why it is not static. */
1597 +CK_SLOT_ID pubkey_SLOTID = 0;
1598 +static CK_SLOT_ID rand_SLOTID = 0;
1599 +static CK_SLOT_ID SLOTID = 0;
1600 +char *pk11_pin = NULL;
1601 +static CK_BBOOL pk11_library_initialized = FALSE;
1602 +static CK_BBOOL pk11_atfork_initialized = FALSE;
1603 +static int pk11_pid = 0;
1605 +static DSO *pk11_dso = NULL;
1607 +/* allocate and initialize all locks used by the engine itself */
1608 +static int pk11_init_all_locks(void)
1609 +       {
1610 +#ifndef NOPTHREADS
1611 +       int type;
1612 +       pthread_mutexattr_t attr;
1614 +       if (pthread_mutexattr_init(&attr) != 0)
1615 +       {
1616 +               PK11err(PK11_F_INIT_ALL_LOCKS, 100);
1617 +               return (0);
1618 +       }
1620 +#ifdef DEBUG_MUTEX
1621 +       if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0)
1622 +       {
1623 +               PK11err(PK11_F_INIT_ALL_LOCKS, 101);
1624 +               return (0);
1625 +       }
1626 +#endif
1628 +       if ((token_lock = OPENSSL_malloc(sizeof (pthread_mutex_t))) == NULL)
1629 +               goto malloc_err;
1630 +       (void) pthread_mutex_init(token_lock, &attr);
1632 +#ifndef OPENSSL_NO_RSA
1633 +       find_lock[OP_RSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
1634 +       if (find_lock[OP_RSA] == NULL)
1635 +               goto malloc_err;
1636 +       (void) pthread_mutex_init(find_lock[OP_RSA], &attr);
1637 +#endif /* OPENSSL_NO_RSA */
1639 +#ifndef OPENSSL_NO_DSA
1640 +       find_lock[OP_DSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
1641 +       if (find_lock[OP_DSA] == NULL)
1642 +               goto malloc_err;
1643 +       (void) pthread_mutex_init(find_lock[OP_DSA], &attr);
1644 +#endif /* OPENSSL_NO_DSA */
1646 +#ifndef OPENSSL_NO_DH
1647 +       find_lock[OP_DH] = OPENSSL_malloc(sizeof (pthread_mutex_t));
1648 +       if (find_lock[OP_DH] == NULL)
1649 +               goto malloc_err;
1650 +       (void) pthread_mutex_init(find_lock[OP_DH], &attr);
1651 +#endif /* OPENSSL_NO_DH */
1653 +       for (type = 0; type < OP_MAX; type++)
1654 +               {
1655 +               session_cache[type].lock =
1656 +                   OPENSSL_malloc(sizeof (pthread_mutex_t));
1657 +               if (session_cache[type].lock == NULL)
1658 +                       goto malloc_err;
1659 +               (void) pthread_mutex_init(session_cache[type].lock, &attr);
1660 +               }
1662 +       return (1);
1664 +malloc_err:
1665 +       pk11_free_all_locks();
1666 +       PK11err(PK11_F_INIT_ALL_LOCKS, PK11_R_MALLOC_FAILURE);
1667 +       return (0);
1668 +#else
1669 +       return (1);
1670 +#endif
1671 +       }
1673 +static void pk11_free_all_locks(void)
1674 +       {
1675 +#ifndef NOPTHREADS
1676 +       int type;
1678 +       if (token_lock != NULL)
1679 +               {
1680 +               (void) pthread_mutex_destroy(token_lock);
1681 +               OPENSSL_free(token_lock);
1682 +               token_lock = NULL;
1683 +               }
1685 +#ifndef OPENSSL_NO_RSA
1686 +       if (find_lock[OP_RSA] != NULL)
1687 +               {
1688 +               (void) pthread_mutex_destroy(find_lock[OP_RSA]);
1689 +               OPENSSL_free(find_lock[OP_RSA]);
1690 +               find_lock[OP_RSA] = NULL;
1691 +               }
1692 +#endif /* OPENSSL_NO_RSA */
1693 +#ifndef OPENSSL_NO_DSA
1694 +       if (find_lock[OP_DSA] != NULL)
1695 +               {
1696 +               (void) pthread_mutex_destroy(find_lock[OP_DSA]);
1697 +               OPENSSL_free(find_lock[OP_DSA]);
1698 +               find_lock[OP_DSA] = NULL;
1699 +               }
1700 +#endif /* OPENSSL_NO_DSA */
1701 +#ifndef OPENSSL_NO_DH
1702 +       if (find_lock[OP_DH] != NULL)
1703 +               {
1704 +               (void) pthread_mutex_destroy(find_lock[OP_DH]);
1705 +               OPENSSL_free(find_lock[OP_DH]);
1706 +               find_lock[OP_DH] = NULL;
1707 +               }
1708 +#endif /* OPENSSL_NO_DH */
1710 +       for (type = 0; type < OP_MAX; type++)
1711 +               {
1712 +               if (session_cache[type].lock != NULL)
1713 +                       {
1714 +                       (void) pthread_mutex_destroy(session_cache[type].lock);
1715 +                       OPENSSL_free(session_cache[type].lock);
1716 +                       session_cache[type].lock = NULL;
1717 +                       }
1718 +               }
1719 +#endif
1720 +       }
1723 + * This internal function is used by ENGINE_pk11() and "dynamic" ENGINE support.
1724 + */
1725 +static int bind_pk11(ENGINE *e)
1726 +       {
1727 +#ifndef OPENSSL_NO_RSA
1728 +       const RSA_METHOD *rsa = NULL;
1729 +       RSA_METHOD *pk11_rsa = PK11_RSA();
1730 +#endif /* OPENSSL_NO_RSA */
1731 +       if (!pk11_library_initialized)
1732 +               if (!pk11_library_init(e))
1733 +                       return (0);
1735 +       if (!ENGINE_set_id(e, engine_pk11_id) ||
1736 +           !ENGINE_set_name(e, engine_pk11_name) ||
1737 +           !ENGINE_set_ciphers(e, pk11_engine_ciphers) ||
1738 +           !ENGINE_set_digests(e, pk11_engine_digests))
1739 +               return (0);
1740 +#ifndef OPENSSL_NO_RSA
1741 +       if (pk11_have_rsa == CK_TRUE)
1742 +               {
1743 +               if (!ENGINE_set_RSA(e, PK11_RSA()) ||
1744 +                   !ENGINE_set_load_privkey_function(e, pk11_load_privkey) ||
1745 +                   !ENGINE_set_load_pubkey_function(e, pk11_load_pubkey))
1746 +                       return (0);
1747 +#ifdef DEBUG_SLOT_SELECTION
1748 +               fprintf(stderr, "%s: registered RSA\n", PK11_DBG);
1749 +#endif /* DEBUG_SLOT_SELECTION */
1750 +               }
1751 +#endif /* OPENSSL_NO_RSA */
1752 +#ifndef OPENSSL_NO_DSA
1753 +       if (pk11_have_dsa == CK_TRUE)
1754 +               {
1755 +               if (!ENGINE_set_DSA(e, PK11_DSA()))
1756 +                       return (0);
1757 +#ifdef DEBUG_SLOT_SELECTION
1758 +               fprintf(stderr, "%s: registered DSA\n", PK11_DBG);
1759 +#endif /* DEBUG_SLOT_SELECTION */
1760 +               }
1761 +#endif /* OPENSSL_NO_DSA */
1762 +#ifndef OPENSSL_NO_DH
1763 +       if (pk11_have_dh == CK_TRUE)
1764 +               {
1765 +               if (!ENGINE_set_DH(e, PK11_DH()))
1766 +                       return (0);
1767 +#ifdef DEBUG_SLOT_SELECTION
1768 +               fprintf(stderr, "%s: registered DH\n", PK11_DBG);
1769 +#endif /* DEBUG_SLOT_SELECTION */
1770 +               }
1771 +#endif /* OPENSSL_NO_DH */
1772 +       if (pk11_have_random)
1773 +               {
1774 +               if (!ENGINE_set_RAND(e, &pk11_random))
1775 +                       return (0);
1776 +#ifdef DEBUG_SLOT_SELECTION
1777 +               fprintf(stderr, "%s: registered random\n", PK11_DBG);
1778 +#endif /* DEBUG_SLOT_SELECTION */
1779 +               }
1780 +       if (!ENGINE_set_init_function(e, pk11_init) ||
1781 +           !ENGINE_set_destroy_function(e, pk11_destroy) ||
1782 +           !ENGINE_set_finish_function(e, pk11_finish) ||
1783 +           !ENGINE_set_ctrl_function(e, pk11_ctrl) ||
1784 +           !ENGINE_set_cmd_defns(e, pk11_cmd_defns))
1785 +               return (0);
1788 + * Apache calls OpenSSL function RSA_blinding_on() once during startup
1789 + * which in turn calls bn_mod_exp. Since we do not implement bn_mod_exp
1790 + * here, we wire it back to the OpenSSL software implementation.
1791 + * Since it is used only once, performance is not a concern.
1792 + */
1793 +#ifndef OPENSSL_NO_RSA
1794 +       rsa = RSA_PKCS1_SSLeay();
1795 +       pk11_rsa->rsa_mod_exp = rsa->rsa_mod_exp;
1796 +       pk11_rsa->bn_mod_exp = rsa->bn_mod_exp;
1797 +       if (pk11_have_recover != CK_TRUE)
1798 +               pk11_rsa->rsa_pub_dec = rsa->rsa_pub_dec;
1799 +#endif /* OPENSSL_NO_RSA */
1801 +       /* Ensure the pk11 error handling is set up */
1802 +       ERR_load_pk11_strings();
1804 +       return (1);
1805 +       }
1807 +/* Dynamic engine support is disabled at a higher level for Solaris */
1808 +#ifdef ENGINE_DYNAMIC_SUPPORT
1809 +#error  "dynamic engine not supported"
1810 +static int bind_helper(ENGINE *e, const char *id)
1811 +       {
1812 +       if (id && (strcmp(id, engine_pk11_id) != 0))
1813 +               return (0);
1815 +       if (!bind_pk11(e))
1816 +               return (0);
1818 +       return (1);
1819 +       }
1821 +IMPLEMENT_DYNAMIC_CHECK_FN()
1822 +IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
1824 +#else
1825 +static ENGINE *engine_pk11(void)
1826 +       {
1827 +       ENGINE *ret = ENGINE_new();
1829 +       if (!ret)
1830 +               return (NULL);
1832 +       if (!bind_pk11(ret))
1833 +               {
1834 +               ENGINE_free(ret);
1835 +               return (NULL);
1836 +               }
1838 +       return (ret);
1839 +       }
1841 +void
1842 +ENGINE_load_pk11(void)
1843 +       {
1844 +       ENGINE *e_pk11 = NULL;
1846 +       /*
1847 +        * Do not use dynamic PKCS#11 library on Solaris due to
1848 +        * security reasons. We will link it in statically.
1849 +        */
1850 +       /* Attempt to load PKCS#11 library */
1851 +       if (!pk11_dso)
1852 +               pk11_dso = DSO_load(NULL, get_PK11_LIBNAME(), NULL, 0);
1854 +       if (pk11_dso == NULL)
1855 +               {
1856 +               PK11err(PK11_F_LOAD, PK11_R_DSO_FAILURE);
1857 +               return;
1858 +               }
1860 +       e_pk11 = engine_pk11();
1861 +       if (!e_pk11)
1862 +               {
1863 +               DSO_free(pk11_dso);
1864 +               pk11_dso = NULL;
1865 +               return;
1866 +               }
1868 +       /*
1869 +        * At this point, the pk11 shared library is either dynamically
1870 +        * loaded or statically linked in. So, initialize the pk11
1871 +        * library before calling ENGINE_set_default since the latter
1872 +        * needs cipher and digest algorithm information
1873 +        */
1874 +       if (!pk11_library_init(e_pk11))
1875 +               {
1876 +               DSO_free(pk11_dso);
1877 +               pk11_dso = NULL;
1878 +               ENGINE_free(e_pk11);
1879 +               return;
1880 +               }
1882 +       ENGINE_add(e_pk11);
1884 +       ENGINE_free(e_pk11);
1885 +       ERR_clear_error();
1886 +       }
1887 +#endif /* ENGINE_DYNAMIC_SUPPORT */
1890 + * These are the static string constants for the DSO file name and
1891 + * the function symbol names to bind to.
1892 + */
1893 +static const char *PK11_LIBNAME = NULL;
1895 +static const char *get_PK11_LIBNAME(void)
1896 +       {
1897 +       if (PK11_LIBNAME)
1898 +               return (PK11_LIBNAME);
1900 +       return (def_PK11_LIBNAME);
1901 +       }
1903 +static void free_PK11_LIBNAME(void)
1904 +       {
1905 +       if (PK11_LIBNAME)
1906 +               OPENSSL_free((void*)PK11_LIBNAME);
1908 +       PK11_LIBNAME = NULL;
1909 +       }
1911 +static long set_PK11_LIBNAME(const char *name)
1912 +       {
1913 +       free_PK11_LIBNAME();
1915 +       return ((PK11_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
1916 +       }
1918 +/* acquire all engine specific mutexes before fork */
1919 +static void pk11_fork_prepare(void)
1920 +       {
1921 +#ifndef NOPTHREADS
1922 +       int i;
1924 +       if (!pk11_library_initialized)
1925 +               return;
1927 +       LOCK_OBJSTORE(OP_RSA);
1928 +       LOCK_OBJSTORE(OP_DSA);
1929 +       LOCK_OBJSTORE(OP_DH);
1930 +       OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
1931 +       for (i = 0; i < OP_MAX; i++)
1932 +               {
1933 +               OPENSSL_assert(pthread_mutex_lock(session_cache[i].lock) == 0);
1934 +               }
1935 +#endif
1936 +       }
1938 +/* release all engine specific mutexes */
1939 +static void pk11_fork_parent(void)
1940 +       {
1941 +#ifndef NOPTHREADS
1942 +       int i;
1944 +       if (!pk11_library_initialized)
1945 +               return;
1947 +       for (i = OP_MAX - 1; i >= 0; i--)
1948 +               {
1949 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[i].lock) == 0);
1950 +               }
1951 +       UNLOCK_OBJSTORE(OP_DH);
1952 +       UNLOCK_OBJSTORE(OP_DSA);
1953 +       UNLOCK_OBJSTORE(OP_RSA);
1954 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
1955 +#endif
1956 +       }
1959 + * same situation as in parent - we need to unlock all locks to make them
1960 + * accessible to all threads.
1961 + */
1962 +static void pk11_fork_child(void)
1963 +       {
1964 +#ifndef NOPTHREADS
1965 +       int i;
1967 +       if (!pk11_library_initialized)
1968 +               return;
1970 +       for (i = OP_MAX - 1; i >= 0; i--)
1971 +               {
1972 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[i].lock) == 0);
1973 +               }
1974 +       UNLOCK_OBJSTORE(OP_DH);
1975 +       UNLOCK_OBJSTORE(OP_DSA);
1976 +       UNLOCK_OBJSTORE(OP_RSA);
1977 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
1978 +#endif
1979 +       }
1981 +/* Initialization function for the pk11 engine */
1982 +static int pk11_init(ENGINE *e)
1984 +       return (pk11_library_init(e));
1987 +static CK_C_INITIALIZE_ARGS pk11_init_args =
1988 +       {
1989 +       NULL_PTR,               /* CreateMutex */
1990 +       NULL_PTR,               /* DestroyMutex */
1991 +       NULL_PTR,               /* LockMutex */
1992 +       NULL_PTR,               /* UnlockMutex */
1993 +       CKF_OS_LOCKING_OK,      /* flags */
1994 +       NULL_PTR,               /* pReserved */
1995 +       };
1998 + * Initialization function. Sets up various PKCS#11 library components.
1999 + * It selects a slot based on predefined critiera. In the process, it also
2000 + * count how many ciphers and digests to support. Since the cipher and
2001 + * digest information is needed when setting default engine, this function
2002 + * needs to be called before calling ENGINE_set_default.
2003 + */
2004 +/* ARGSUSED */
2005 +static int pk11_library_init(ENGINE *e)
2006 +       {
2007 +       CK_C_GetFunctionList p;
2008 +       CK_RV rv = CKR_OK;
2009 +       CK_INFO info;
2010 +       CK_ULONG ul_state_len;
2011 +       int any_slot_found;
2012 +       int i;
2013 +#ifndef OPENSSL_SYS_WIN32
2014 +       struct sigaction sigint_act, sigterm_act, sighup_act;
2015 +#endif
2017 +       /*
2018 +        * pk11_library_initialized is set to 0 in pk11_finish() which
2019 +        * is called from ENGINE_finish(). However, if there is still
2020 +        * at least one existing functional reference to the engine
2021 +        * (see engine(3) for more information), pk11_finish() is
2022 +        * skipped. For example, this can happen if an application
2023 +        * forgets to clear one cipher context. In case of a fork()
2024 +        * when the application is finishing the engine so that it can
2025 +        * be reinitialized in the child, forgotten functional
2026 +        * reference causes pk11_library_initialized to stay 1. In
2027 +        * that case we need the PID check so that we properly
2028 +        * initialize the engine again.
2029 +        */
2030 +       if (pk11_library_initialized)
2031 +               {
2032 +               if (pk11_pid == getpid())
2033 +                       {
2034 +                       return (1);
2035 +                       }
2036 +               else
2037 +                       {
2038 +                       global_session = CK_INVALID_HANDLE;
2039 +                       /*
2040 +                        * free the locks first to prevent memory leak in case
2041 +                        * the application calls fork() without finishing the
2042 +                        * engine first.
2043 +                        */
2044 +                       pk11_free_all_locks();
2045 +                       }
2046 +               }
2048 +       if (pk11_dso == NULL)
2049 +               {
2050 +               PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
2051 +               goto err;
2052 +               }
2054 +#ifdef SOLARIS_HW_SLOT_SELECTION
2055 +       if (check_hw_mechanisms() == 0)
2056 +               goto err;
2057 +#endif /* SOLARIS_HW_SLOT_SELECTION */
2059 +       /* get the C_GetFunctionList function from the loaded library */
2060 +       p = (CK_C_GetFunctionList)DSO_bind_func(pk11_dso,
2061 +               PK11_GET_FUNCTION_LIST);
2062 +       if (!p)
2063 +               {
2064 +               PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
2065 +               goto err;
2066 +               }
2068 +       /* get the full function list from the loaded library */
2069 +       rv = p(&pFuncList);
2070 +       if (rv != CKR_OK)
2071 +               {
2072 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE, rv);
2073 +               goto err;
2074 +               }
2076 +#ifndef OPENSSL_SYS_WIN32
2077 +       /* Not all PKCS#11 library are signal safe! */
2079 +       (void) memset(&sigint_act, 0, sizeof(sigint_act));
2080 +       (void) memset(&sigterm_act, 0, sizeof(sigterm_act));
2081 +       (void) memset(&sighup_act, 0, sizeof(sighup_act));
2082 +       (void) sigaction(SIGINT, NULL, &sigint_act);
2083 +       (void) sigaction(SIGTERM, NULL, &sigterm_act);
2084 +       (void) sigaction(SIGHUP, NULL, &sighup_act);
2085 +#endif
2086 +       rv = pFuncList->C_Initialize((CK_VOID_PTR)&pk11_init_args);
2087 +#ifndef OPENSSL_SYS_WIN32
2088 +       (void) sigaction(SIGINT, &sigint_act, NULL);
2089 +       (void) sigaction(SIGTERM, &sigterm_act, NULL);
2090 +       (void) sigaction(SIGHUP, &sighup_act, NULL);
2091 +#endif
2092 +       if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
2093 +               {
2094 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_INITIALIZE, rv);
2095 +               goto err;
2096 +               }
2098 +       rv = pFuncList->C_GetInfo(&info);
2099 +       if (rv != CKR_OK)
2100 +               {
2101 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_GETINFO, rv);
2102 +               goto err;
2103 +               }
2105 +       if (pk11_choose_slots(&any_slot_found) == 0)
2106 +               goto err;
2108 +       /*
2109 +        * The library we use, set in def_PK11_LIBNAME, may not offer any
2110 +        * slot(s). In that case, we must not proceed but we must not return an
2111 +        * error. The reason is that applications that try to set up the PKCS#11
2112 +        * engine don't exit on error during the engine initialization just
2113 +        * because no slot was present.
2114 +        */
2115 +       if (any_slot_found == 0)
2116 +               return (1);
2118 +       if (global_session == CK_INVALID_HANDLE)
2119 +               {
2120 +               /* Open the global_session for the new process */
2121 +               rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
2122 +                       NULL_PTR, NULL_PTR, &global_session);
2123 +               if (rv != CKR_OK)
2124 +                       {
2125 +                       PK11err_add_data(PK11_F_LIBRARY_INIT,
2126 +                           PK11_R_OPENSESSION, rv);
2127 +                       goto err;
2128 +                       }
2129 +               }
2131 +       /*
2132 +        * Disable digest if C_GetOperationState is not supported since
2133 +        * this function is required by OpenSSL digest copy function
2134 +        */
2135 +       /* Keyper fails to return CKR_FUNCTION_NOT_SUPPORTED */
2136 +       if (pFuncList->C_GetOperationState(global_session, NULL, &ul_state_len)
2137 +                       != CKR_OK) {
2138 +#ifdef DEBUG_SLOT_SELECTION
2139 +               fprintf(stderr, "%s: C_GetOperationState() not supported, "
2140 +                   "setting digest_count to 0\n", PK11_DBG);
2141 +#endif /* DEBUG_SLOT_SELECTION */
2142 +               digest_count = 0;
2143 +       }
2145 +       pk11_library_initialized = TRUE;
2146 +       pk11_pid = getpid();
2147 +       /*
2148 +        * if initialization of the locks fails pk11_init_all_locks()
2149 +        * will do the cleanup.
2150 +        */
2151 +       if (!pk11_init_all_locks())
2152 +               goto err;
2153 +       for (i = 0; i < OP_MAX; i++)
2154 +               session_cache[i].head = NULL;
2155 +       /*
2156 +        * initialize active lists. We only use active lists
2157 +        * for asymmetric ciphers.
2158 +        */
2159 +       for (i = 0; i < OP_MAX; i++)
2160 +               active_list[i] = NULL;
2162 +#ifndef NOPTHREADS
2163 +       if (!pk11_atfork_initialized)
2164 +               {
2165 +               if (pthread_atfork(pk11_fork_prepare, pk11_fork_parent,
2166 +                   pk11_fork_child) != 0)
2167 +                       {
2168 +                       PK11err(PK11_F_LIBRARY_INIT, PK11_R_ATFORK_FAILED);
2169 +                       goto err;
2170 +                       }
2171 +               pk11_atfork_initialized = TRUE;
2172 +               }
2173 +#endif
2175 +       return (1);
2177 +err:
2178 +       return (0);
2179 +       }
2181 +/* Destructor (complements the "ENGINE_pk11()" constructor) */
2182 +/* ARGSUSED */
2183 +static int pk11_destroy(ENGINE *e)
2184 +       {
2185 +       free_PK11_LIBNAME();
2186 +       ERR_unload_pk11_strings();
2187 +       if (pk11_pin) {
2188 +               memset(pk11_pin, 0, strlen(pk11_pin));
2189 +               OPENSSL_free((void*)pk11_pin);
2190 +       }
2191 +       pk11_pin = NULL;
2192 +       return (1);
2193 +       }
2196 + * Termination function to clean up the session, the token, and the pk11
2197 + * library.
2198 + */
2199 +/* ARGSUSED */
2200 +static int pk11_finish(ENGINE *e)
2201 +       {
2202 +       int i;
2204 +       if (pk11_pin) {
2205 +               memset(pk11_pin, 0, strlen(pk11_pin));
2206 +               OPENSSL_free((void*)pk11_pin);
2207 +       }
2208 +       pk11_pin = NULL;
2210 +       if (pk11_dso == NULL)
2211 +               {
2212 +               PK11err(PK11_F_FINISH, PK11_R_NOT_LOADED);
2213 +               goto err;
2214 +               }
2216 +       OPENSSL_assert(pFuncList != NULL);
2218 +       if (pk11_free_all_sessions() == 0)
2219 +               goto err;
2221 +       /* free all active lists */
2222 +       for (i = 0; i < OP_MAX; i++)
2223 +               pk11_free_active_list(i);
2225 +       pFuncList->C_CloseSession(global_session);
2226 +       global_session = CK_INVALID_HANDLE;
2228 +       /*
2229 +        * Since we are part of a library (libcrypto.so), calling this function
2230 +        * may have side-effects.
2231 +        */
2232 +#if 0
2233 +       pFuncList->C_Finalize(NULL);
2234 +#endif
2236 +       if (!DSO_free(pk11_dso))
2237 +               {
2238 +               PK11err(PK11_F_FINISH, PK11_R_DSO_FAILURE);
2239 +               goto err;
2240 +               }
2241 +       pk11_dso = NULL;
2242 +       pFuncList = NULL;
2243 +       pk11_library_initialized = FALSE;
2244 +       pk11_pid = 0;
2245 +       /*
2246 +        * There is no way how to unregister atfork handlers (other than
2247 +        * unloading the library) so we just free the locks. For this reason
2248 +        * the atfork handlers check if the engine is initialized and bail out
2249 +        * immediately if not. This is necessary in case a process finishes
2250 +        * the engine before calling fork().
2251 +        */
2252 +       pk11_free_all_locks();
2254 +       return (1);
2256 +err:
2257 +       return (0);
2258 +       }
2260 +/* Standard engine interface function to set the dynamic library path */
2261 +/* ARGSUSED */
2262 +static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
2263 +       {
2264 +       int initialized = ((pk11_dso == NULL) ? 0 : 1);
2266 +       switch (cmd)
2267 +               {
2268 +       case PK11_CMD_SO_PATH:
2269 +               if (p == NULL)
2270 +                       {
2271 +                       PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
2272 +                       return (0);
2273 +                       }
2275 +               if (initialized)
2276 +                       {
2277 +                       PK11err(PK11_F_CTRL, PK11_R_ALREADY_LOADED);
2278 +                       return (0);
2279 +                       }
2281 +               return (set_PK11_LIBNAME((const char *)p));
2282 +       case PK11_CMD_PIN:
2283 +               if (pk11_pin) {
2284 +                       memset(pk11_pin, 0, strlen(pk11_pin));
2285 +                       OPENSSL_free((void*)pk11_pin);
2286 +               }
2287 +               pk11_pin = NULL;
2289 +               if (p == NULL)
2290 +                       {
2291 +                       PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
2292 +                       return (0);
2293 +                       }
2295 +               pk11_pin = BUF_strdup(p);
2296 +               if (pk11_pin == NULL)
2297 +                       {
2298 +                       PK11err(PK11_F_GET_SESSION, PK11_R_MALLOC_FAILURE);
2299 +                       return (0);
2300 +                       }
2301 +               return (1);
2302 +       case PK11_CMD_SLOT:
2303 +               SLOTID = (CK_SLOT_ID)i;
2304 +#ifdef DEBUG_SLOT_SELECTION
2305 +               fprintf(stderr, "%s: slot set\n", PK11_DBG);
2306 +#endif
2307 +               return (1);
2308 +       default:
2309 +               break;
2310 +               }
2312 +       PK11err(PK11_F_CTRL, PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED);
2314 +       return (0);
2315 +       }
2318 +/* Required function by the engine random interface. It does nothing here */
2319 +static void pk11_rand_cleanup(void)
2320 +       {
2321 +       return;
2322 +       }
2324 +/* ARGSUSED */
2325 +static void pk11_rand_add(const void *buf, int num, double add)
2326 +       {
2327 +       PK11_SESSION *sp;
2329 +       if ((sp = pk11_get_session(OP_RAND)) == NULL)
2330 +               return;
2332 +       /*
2333 +        * Ignore any errors (e.g. CKR_RANDOM_SEED_NOT_SUPPORTED) since
2334 +        * the calling functions do not care anyway
2335 +        */
2336 +       pFuncList->C_SeedRandom(sp->session, (unsigned char *) buf, num);
2337 +       pk11_return_session(sp, OP_RAND);
2339 +       return;
2340 +       }
2342 +static void pk11_rand_seed(const void *buf, int num)
2343 +       {
2344 +       pk11_rand_add(buf, num, 0);
2345 +       }
2347 +static int pk11_rand_bytes(unsigned char *buf, int num)
2348 +       {
2349 +       CK_RV rv;
2350 +       PK11_SESSION *sp;
2352 +       if ((sp = pk11_get_session(OP_RAND)) == NULL)
2353 +               return (0);
2355 +       rv = pFuncList->C_GenerateRandom(sp->session, buf, num);
2356 +       if (rv != CKR_OK)
2357 +               {
2358 +               PK11err_add_data(PK11_F_RAND_BYTES, PK11_R_GENERATERANDOM, rv);
2359 +               pk11_return_session(sp, OP_RAND);
2360 +               return (0);
2361 +               }
2363 +       pk11_return_session(sp, OP_RAND);
2364 +       return (1);
2365 +       }
2367 +/* Required function by the engine random interface. It does nothing here */
2368 +static int pk11_rand_status(void)
2369 +       {
2370 +       return (1);
2371 +       }
2373 +/* Free all BIGNUM structures from PK11_SESSION. */
2374 +static void pk11_free_nums(PK11_SESSION *sp, PK11_OPTYPE optype)
2375 +       {
2376 +       switch (optype)
2377 +               {
2378 +#ifndef        OPENSSL_NO_RSA
2379 +               case OP_RSA:
2380 +                       if (sp->opdata_rsa_n_num != NULL)
2381 +                               {
2382 +                               BN_free(sp->opdata_rsa_n_num);
2383 +                               sp->opdata_rsa_n_num = NULL;
2384 +                               }
2385 +                       if (sp->opdata_rsa_e_num != NULL)
2386 +                               {
2387 +                               BN_free(sp->opdata_rsa_e_num);
2388 +                               sp->opdata_rsa_e_num = NULL;
2389 +                               }
2390 +                       if (sp->opdata_rsa_pn_num != NULL)
2391 +                               {
2392 +                               BN_free(sp->opdata_rsa_pn_num);
2393 +                               sp->opdata_rsa_pn_num = NULL;
2394 +                               }
2395 +                       if (sp->opdata_rsa_pe_num != NULL)
2396 +                               {
2397 +                               BN_free(sp->opdata_rsa_pe_num);
2398 +                               sp->opdata_rsa_pe_num = NULL;
2399 +                               }
2400 +                       if (sp->opdata_rsa_d_num != NULL)
2401 +                               {
2402 +                               BN_free(sp->opdata_rsa_d_num);
2403 +                               sp->opdata_rsa_d_num = NULL;
2404 +                               }
2405 +                       break;
2406 +#endif
2407 +#ifndef        OPENSSL_NO_DSA
2408 +               case OP_DSA:
2409 +                       if (sp->opdata_dsa_pub_num != NULL)
2410 +                               {
2411 +                               BN_free(sp->opdata_dsa_pub_num);
2412 +                               sp->opdata_dsa_pub_num = NULL;
2413 +                               }
2414 +                       if (sp->opdata_dsa_priv_num != NULL)
2415 +                               {
2416 +                               BN_free(sp->opdata_dsa_priv_num);
2417 +                               sp->opdata_dsa_priv_num = NULL;
2418 +                               }
2419 +                       break;
2420 +#endif
2421 +#ifndef        OPENSSL_NO_DH
2422 +               case OP_DH:
2423 +                       if (sp->opdata_dh_priv_num != NULL)
2424 +                               {
2425 +                               BN_free(sp->opdata_dh_priv_num);
2426 +                               sp->opdata_dh_priv_num = NULL;
2427 +                               }
2428 +                       break;
2429 +#endif
2430 +               default:
2431 +                       break;
2432 +               }
2433 +       }
2436 + * Get new PK11_SESSION structure ready for use. Every process must have
2437 + * its own freelist of PK11_SESSION structures so handle fork() here
2438 + * by destroying the old and creating new freelist.
2439 + * The returned PK11_SESSION structure is disconnected from the freelist.
2440 + */
2441 +PK11_SESSION *
2442 +pk11_get_session(PK11_OPTYPE optype)
2443 +       {
2444 +       PK11_SESSION *sp = NULL, *sp1, *freelist;
2445 +#ifndef NOPTHREADS
2446 +       pthread_mutex_t *freelist_lock = NULL;
2447 +#endif
2448 +       static pid_t pid = 0;
2449 +       pid_t new_pid;
2450 +       CK_RV rv;
2452 +       switch (optype)
2453 +               {
2454 +               case OP_RSA:
2455 +               case OP_DSA:
2456 +               case OP_DH:
2457 +               case OP_RAND:
2458 +               case OP_DIGEST:
2459 +               case OP_CIPHER:
2460 +#ifndef NOPTHREADS
2461 +                       freelist_lock = session_cache[optype].lock;
2462 +#endif
2463 +                       break;
2464 +               default:
2465 +                       PK11err(PK11_F_GET_SESSION,
2466 +                               PK11_R_INVALID_OPERATION_TYPE);
2467 +                       return (NULL);
2468 +               }
2469 +#ifndef NOPTHREADS
2470 +       OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
2471 +#else
2472 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
2473 +#endif
2475 +       /*
2476 +        * Will use it to find out if we forked. We cannot use the PID field in
2477 +        * the session structure because we could get a newly allocated session
2478 +        * here, with no PID information.
2479 +        */
2480 +       if (pid == 0)
2481 +               pid = getpid();
2483 +       freelist = session_cache[optype].head;
2484 +       sp = freelist;
2486 +       /*
2487 +        * If the free list is empty, allocate new unitialized (filled
2488 +        * with zeroes) PK11_SESSION structure otherwise return first
2489 +        * structure from the freelist.
2490 +        */
2491 +       if (sp == NULL)
2492 +               {
2493 +               if ((sp = OPENSSL_malloc(sizeof (PK11_SESSION))) == NULL)
2494 +                       {
2495 +                       PK11err(PK11_F_GET_SESSION,
2496 +                               PK11_R_MALLOC_FAILURE);
2497 +                       goto err;
2498 +                       }
2499 +               (void) memset(sp, 0, sizeof (PK11_SESSION));
2501 +               /*
2502 +                * It is a new session so it will look like a cache miss to the
2503 +                * code below. So, we must not try to to destroy its members so
2504 +                * mark them as unused.
2505 +                */
2506 +               sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
2507 +               sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
2508 +               }
2509 +       else
2510 +               {
2511 +               freelist = sp->next;
2512 +               }
2514 +       /*
2515 +        * Check whether we have forked. In that case, we must get rid of all
2516 +        * inherited sessions and start allocating new ones.
2517 +        */
2518 +       if (pid != (new_pid = getpid()))
2519 +               {
2520 +               pid = new_pid;
2522 +               /*
2523 +                * We are a new process and thus need to free any inherited
2524 +                * PK11_SESSION objects aside from the first session (sp) which
2525 +                * is the only PK11_SESSION structure we will reuse (for the
2526 +                * head of the list).
2527 +                */
2528 +               while ((sp1 = freelist) != NULL)
2529 +                       {
2530 +                       freelist = sp1->next;
2531 +                       /*
2532 +                        * NOTE: we do not want to call pk11_free_all_sessions()
2533 +                        * here because it would close underlying PKCS#11
2534 +                        * sessions and destroy all objects.
2535 +                        */
2536 +                       pk11_free_nums(sp1, optype);
2537 +                       OPENSSL_free(sp1);
2538 +                       }
2540 +               /* we have to free the active list as well. */
2541 +               pk11_free_active_list(optype);
2543 +               /* Initialize the process */
2544 +               rv = pFuncList->C_Initialize((CK_VOID_PTR)&pk11_init_args);
2545 +               if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
2546 +                       {
2547 +                       PK11err_add_data(PK11_F_GET_SESSION, PK11_R_INITIALIZE,
2548 +                           rv);
2549 +                       OPENSSL_free(sp);
2550 +                       sp = NULL;
2551 +                       goto err;
2552 +                       }
2554 +               /*
2555 +                * Choose slot here since the slot table is different on this
2556 +                * process. If we are here then we must have found at least one
2557 +                * usable slot before so we don't need to check any_slot_found.
2558 +                * See pk11_library_init()'s usage of this function for more
2559 +                * information.
2560 +                */
2561 +#ifdef SOLARIS_HW_SLOT_SELECTION
2562 +               if (check_hw_mechanisms() == 0)
2563 +                       goto err;
2564 +#endif /* SOLARIS_HW_SLOT_SELECTION */
2565 +               if (pk11_choose_slots(NULL) == 0)
2566 +                       goto err;
2568 +               /* Open the global_session for the new process */
2569 +               rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
2570 +                       NULL_PTR, NULL_PTR, &global_session);
2571 +               if (rv != CKR_OK)
2572 +                       {
2573 +                       PK11err_add_data(PK11_F_GET_SESSION, PK11_R_OPENSESSION,
2574 +                           rv);
2575 +                       OPENSSL_free(sp);
2576 +                       sp = NULL;
2577 +                       goto err;
2578 +                       }
2580 +               /*
2581 +                * It is an inherited session from our parent so it needs
2582 +                * re-initialization.
2583 +                */
2584 +               if (pk11_setup_session(sp, optype) == 0)
2585 +                       {
2586 +                       OPENSSL_free(sp);
2587 +                       sp = NULL;
2588 +                       goto err;
2589 +                       }
2590 +               if (pk11_token_relogin(sp->session) == 0) 
2591 +                       {
2592 +                       /*
2593 +                        * We will keep the session in the cache list and let
2594 +                        * the caller cope with the situation.
2595 +                        */
2596 +                       freelist = sp;
2597 +                       sp = NULL;
2598 +                       goto err;
2599 +                       }
2600 +               }
2602 +       if (sp->pid == 0)
2603 +               {
2604 +               /* It is a new session and needs initialization. */
2605 +               if (pk11_setup_session(sp, optype) == 0)
2606 +                       {
2607 +                       OPENSSL_free(sp);
2608 +                       sp = NULL;
2609 +                       }
2610 +               }
2612 +       /* set new head for the list of PK11_SESSION objects */
2613 +       session_cache[optype].head = freelist;
2615 +err:
2616 +       if (sp != NULL)
2617 +               sp->next = NULL;
2619 +#ifndef NOPTHREADS
2620 +       OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
2621 +#else
2622 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
2623 +#endif
2625 +       return (sp);
2626 +       }
2629 +void
2630 +pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype)
2631 +       {
2632 +#ifndef NOPTHREADS
2633 +       pthread_mutex_t *freelist_lock;
2634 +#endif
2635 +       PK11_SESSION *freelist;
2637 +       /*
2638 +        * If this is a session from the parent it will be taken care of and
2639 +        * freed in pk11_get_session() as part of the post-fork clean up the
2640 +        * next time we will ask for a new session.
2641 +        */
2642 +       if (sp == NULL || sp->pid != getpid())
2643 +               return;
2645 +       switch (optype)
2646 +               {
2647 +               case OP_RSA:
2648 +               case OP_DSA:
2649 +               case OP_DH:
2650 +               case OP_RAND:
2651 +               case OP_DIGEST:
2652 +               case OP_CIPHER:
2653 +#ifndef NOPTHREADS
2654 +                       freelist_lock = session_cache[optype].lock;
2655 +#endif
2656 +                       break;
2657 +               default:
2658 +                       PK11err(PK11_F_RETURN_SESSION,
2659 +                               PK11_R_INVALID_OPERATION_TYPE);
2660 +                       return;
2661 +               }
2663 +#ifndef NOPTHREADS
2664 +       OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
2665 +#else
2666 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
2667 +#endif
2668 +       freelist = session_cache[optype].head;
2669 +       sp->next = freelist;
2670 +       session_cache[optype].head = sp;
2671 +#ifndef NOPTHREADS
2672 +       OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
2673 +#else
2674 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
2675 +#endif
2676 +       }
2679 +/* Destroy all objects. This function is called when the engine is finished */
2680 +static int pk11_free_all_sessions()
2681 +       {
2682 +       int ret = 1;
2683 +       int type;
2685 +#ifndef OPENSSL_NO_RSA
2686 +       (void) pk11_destroy_rsa_key_objects(NULL);
2687 +#endif /* OPENSSL_NO_RSA */
2688 +#ifndef OPENSSL_NO_DSA
2689 +       (void) pk11_destroy_dsa_key_objects(NULL);
2690 +#endif /* OPENSSL_NO_DSA */
2691 +#ifndef OPENSSL_NO_DH
2692 +       (void) pk11_destroy_dh_key_objects(NULL);
2693 +#endif /* OPENSSL_NO_DH */
2694 +       (void) pk11_destroy_cipher_key_objects(NULL);
2696 +       /*
2697 +        * We try to release as much as we can but any error means that we will
2698 +        * return 0 on exit.
2699 +        */
2700 +       for (type = 0; type < OP_MAX; type++)
2701 +               {
2702 +               if (pk11_free_session_list(type) == 0)
2703 +                       ret = 0;
2704 +               }
2706 +       return (ret);
2707 +       }
2710 + * Destroy session structures from the linked list specified. Free as many
2711 + * sessions as possible but any failure in C_CloseSession() means that we
2712 + * return an error on return.
2713 + */
2714 +static int pk11_free_session_list(PK11_OPTYPE optype)
2715 +       {
2716 +       CK_RV rv;
2717 +       PK11_SESSION *sp = NULL;
2718 +       PK11_SESSION *freelist = NULL;
2719 +       pid_t mypid = getpid();
2720 +#ifndef NOPTHREADS
2721 +       pthread_mutex_t *freelist_lock;
2722 +#endif
2723 +       int ret = 1;
2725 +       switch (optype)
2726 +               {
2727 +               case OP_RSA:
2728 +               case OP_DSA:
2729 +               case OP_DH:
2730 +               case OP_RAND:
2731 +               case OP_DIGEST:
2732 +               case OP_CIPHER:
2733 +#ifndef NOPTHREADS
2734 +                       freelist_lock = session_cache[optype].lock;
2735 +#endif
2736 +                       break;
2737 +               default:
2738 +                       PK11err(PK11_F_FREE_ALL_SESSIONS,
2739 +                               PK11_R_INVALID_OPERATION_TYPE);
2740 +                       return (0);
2741 +               }
2743 +#ifndef NOPTHREADS
2744 +       OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
2745 +#else
2746 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
2747 +#endif
2748 +       freelist = session_cache[optype].head;
2749 +       while ((sp = freelist) != NULL)
2750 +               {
2751 +               if (sp->session != CK_INVALID_HANDLE && sp->pid == mypid)
2752 +                       {
2753 +                       rv = pFuncList->C_CloseSession(sp->session);
2754 +                       if (rv != CKR_OK)
2755 +                               {
2756 +                               PK11err_add_data(PK11_F_FREE_ALL_SESSIONS,
2757 +                                       PK11_R_CLOSESESSION, rv);
2758 +                               ret = 0;
2759 +                               }
2760 +                       }
2761 +               freelist = sp->next;
2762 +               pk11_free_nums(sp, optype);
2763 +               OPENSSL_free(sp);
2764 +               }
2766 +#ifndef NOPTHREADS
2767 +       OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
2768 +#else
2769 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
2770 +#endif
2771 +       return (ret);
2772 +       }
2775 +static int
2776 +pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype)
2777 +       {
2778 +       CK_RV rv;
2779 +       CK_SLOT_ID myslot;
2781 +       switch (optype)
2782 +               {
2783 +               case OP_RSA:
2784 +               case OP_DSA:
2785 +               case OP_DH:
2786 +                       myslot = pubkey_SLOTID;
2787 +                       break;
2788 +               case OP_RAND:
2789 +                       myslot = rand_SLOTID;
2790 +                       break;
2791 +               case OP_DIGEST:
2792 +               case OP_CIPHER:
2793 +                       myslot = SLOTID;
2794 +                       break;
2795 +               default:
2796 +                       PK11err(PK11_F_SETUP_SESSION,
2797 +                           PK11_R_INVALID_OPERATION_TYPE);
2798 +                       return (0);
2799 +               }
2801 +       sp->session = CK_INVALID_HANDLE;
2802 +#ifdef DEBUG_SLOT_SELECTION
2803 +       fprintf(stderr, "%s: myslot=%d optype=%d\n", PK11_DBG, myslot, optype);
2804 +#endif /* DEBUG_SLOT_SELECTION */
2805 +       rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
2806 +               NULL_PTR, NULL_PTR, &sp->session);
2807 +       if (rv == CKR_CRYPTOKI_NOT_INITIALIZED)
2808 +               {
2809 +               /*
2810 +                * We are probably a child process so force the
2811 +                * reinitialize of the session
2812 +                */
2813 +               pk11_library_initialized = FALSE;
2814 +               if (!pk11_library_init(NULL))
2815 +                       return (0);
2816 +               rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
2817 +                       NULL_PTR, NULL_PTR, &sp->session);
2818 +               }
2819 +       if (rv != CKR_OK)
2820 +               {
2821 +               PK11err_add_data(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION, rv);
2822 +               return (0);
2823 +               }
2825 +       sp->pid = getpid();
2827 +       switch (optype)
2828 +               {
2829 +#ifndef OPENSSL_NO_RSA
2830 +               case OP_RSA:
2831 +                       sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
2832 +                       sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
2833 +                       sp->opdata_rsa_pub = NULL;
2834 +                       sp->opdata_rsa_n_num = NULL;
2835 +                       sp->opdata_rsa_e_num = NULL;
2836 +                       sp->opdata_rsa_priv = NULL;
2837 +                       sp->opdata_rsa_pn_num = NULL;
2838 +                       sp->opdata_rsa_pe_num = NULL;
2839 +                       sp->opdata_rsa_d_num = NULL;
2840 +                       break;
2841 +#endif /* OPENSSL_NO_RSA */
2842 +#ifndef OPENSSL_NO_DSA
2843 +               case OP_DSA:
2844 +                       sp->opdata_dsa_pub_key = CK_INVALID_HANDLE;
2845 +                       sp->opdata_dsa_priv_key = CK_INVALID_HANDLE;
2846 +                       sp->opdata_dsa_pub = NULL;
2847 +                       sp->opdata_dsa_pub_num = NULL;
2848 +                       sp->opdata_dsa_priv = NULL;
2849 +                       sp->opdata_dsa_priv_num = NULL;
2850 +                       break;
2851 +#endif /* OPENSSL_NO_DSA */
2852 +#ifndef OPENSSL_NO_DH
2853 +               case OP_DH:
2854 +                       sp->opdata_dh_key = CK_INVALID_HANDLE;
2855 +                       sp->opdata_dh = NULL;
2856 +                       sp->opdata_dh_priv_num = NULL;
2857 +                       break;
2858 +#endif /* OPENSSL_NO_DH */
2859 +               case OP_CIPHER:
2860 +                       sp->opdata_cipher_key = CK_INVALID_HANDLE;
2861 +                       sp->opdata_encrypt = -1;
2862 +                       break;
2863 +               default:
2864 +                       break;
2865 +               }
2867 +       /*
2868 +        * We always initialize the session as containing a non-persistent
2869 +        * object. The key load functions set it to persistent if that is so.
2870 +        */
2871 +       sp->pub_persistent = CK_FALSE;
2872 +       sp->priv_persistent = CK_FALSE;
2873 +       return (1);
2874 +       }
2876 +#ifndef OPENSSL_NO_RSA
2877 +/* Destroy RSA public key from single session. */
2878 +int
2879 +pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
2880 +       {
2881 +       int ret = 0;
2883 +       if (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE)
2884 +               {
2885 +               TRY_OBJ_DESTROY(sp, sp->opdata_rsa_pub_key,
2886 +                   ret, uselock, OP_RSA, CK_FALSE);
2887 +               sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
2888 +               sp->opdata_rsa_pub = NULL;
2889 +               if (sp->opdata_rsa_n_num != NULL)
2890 +                       {
2891 +                       BN_free(sp->opdata_rsa_n_num);
2892 +                       sp->opdata_rsa_n_num = NULL;
2893 +                       }
2894 +               if (sp->opdata_rsa_e_num != NULL)
2895 +                       {
2896 +                       BN_free(sp->opdata_rsa_e_num);
2897 +                       sp->opdata_rsa_e_num = NULL;
2898 +                       }
2899 +               }
2901 +       return (ret);
2902 +       }
2904 +/* Destroy RSA private key from single session. */
2905 +int
2906 +pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
2907 +       {
2908 +       int ret = 0;
2910 +       if (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE)
2911 +               {
2912 +               TRY_OBJ_DESTROY(sp, sp->opdata_rsa_priv_key,
2913 +                   ret, uselock, OP_RSA, CK_TRUE);
2914 +               sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
2915 +               sp->opdata_rsa_priv = NULL;
2916 +               if (sp->opdata_rsa_d_num != NULL)
2917 +                       {
2918 +                       BN_free(sp->opdata_rsa_d_num);
2919 +                       sp->opdata_rsa_d_num = NULL;
2920 +                       }
2922 +               /*
2923 +                * For the RSA key by reference code, public components 'n'/'e'
2924 +                * are the key components we use to check for the cache hit. We
2925 +                * must free those as well.
2926 +                */
2927 +               if (sp->opdata_rsa_pn_num != NULL)
2928 +                       {
2929 +                       BN_free(sp->opdata_rsa_pn_num);
2930 +                       sp->opdata_rsa_pn_num = NULL;
2931 +                       }
2932 +               if (sp->opdata_rsa_pe_num != NULL)
2933 +                       {
2934 +                       BN_free(sp->opdata_rsa_pe_num);
2935 +                       sp->opdata_rsa_pe_num = NULL;
2936 +                       }
2937 +               }
2939 +       return (ret);
2940 +       }
2943 + * Destroy RSA key object wrapper. If session is NULL, try to destroy all
2944 + * objects in the free list.
2945 + */
2946 +int
2947 +pk11_destroy_rsa_key_objects(PK11_SESSION *session)
2948 +       {
2949 +       int ret = 1;
2950 +       PK11_SESSION *sp = NULL;
2951 +       PK11_SESSION *local_free_session;
2952 +       CK_BBOOL uselock = TRUE;
2954 +       if (session != NULL)
2955 +               local_free_session = session;
2956 +       else
2957 +               {
2958 +#ifndef NOPTHREADS
2959 +               OPENSSL_assert(pthread_mutex_lock(session_cache[OP_RSA].lock) == 0);
2960 +#else
2961 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
2962 +#endif
2963 +               local_free_session = session_cache[OP_RSA].head;
2964 +               uselock = FALSE;
2965 +               }
2967 +       /*
2968 +        * go through the list of sessions and delete key objects
2969 +        */
2970 +       while ((sp = local_free_session) != NULL)
2971 +               {
2972 +               local_free_session = sp->next;
2974 +               /*
2975 +                * Do not terminate list traversal if one of the
2976 +                * destroy operations fails.
2977 +                */
2978 +               if (pk11_destroy_rsa_object_pub(sp, uselock) == 0)
2979 +                       {
2980 +                       ret = 0;
2981 +                       continue;
2982 +                       }
2983 +               if (pk11_destroy_rsa_object_priv(sp, uselock) == 0)
2984 +                       {
2985 +                       ret = 0;
2986 +                       continue;
2987 +                       }
2988 +               }
2990 +#ifndef NOPTHREADS
2991 +       if (session == NULL)
2992 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[OP_RSA].lock) == 0);
2993 +#else
2994 +       if (session == NULL)
2995 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
2996 +#endif
2998 +       return (ret);
2999 +       }
3000 +#endif /* OPENSSL_NO_RSA */
3002 +#ifndef OPENSSL_NO_DSA
3003 +/* Destroy DSA public key from single session. */
3004 +int
3005 +pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
3006 +       {
3007 +       int ret = 0;
3009 +       if (sp->opdata_dsa_pub_key != CK_INVALID_HANDLE)
3010 +               {
3011 +               TRY_OBJ_DESTROY(sp, sp->opdata_dsa_pub_key,
3012 +                   ret, uselock, OP_DSA, CK_FALSE);
3013 +               sp->opdata_dsa_pub_key = CK_INVALID_HANDLE;
3014 +               sp->opdata_dsa_pub = NULL;
3015 +               if (sp->opdata_dsa_pub_num != NULL)
3016 +                       {
3017 +                       BN_free(sp->opdata_dsa_pub_num);
3018 +                       sp->opdata_dsa_pub_num = NULL;
3019 +                       }
3020 +               }
3022 +       return (ret);
3023 +       }
3025 +/* Destroy DSA private key from single session. */
3026 +int
3027 +pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
3028 +       {
3029 +       int ret = 0;
3031 +       if (sp->opdata_dsa_priv_key != CK_INVALID_HANDLE)
3032 +               {
3033 +               TRY_OBJ_DESTROY(sp, sp->opdata_dsa_priv_key,
3034 +                   ret, uselock, OP_DSA, CK_TRUE);
3035 +               sp->opdata_dsa_priv_key = CK_INVALID_HANDLE;
3036 +               sp->opdata_dsa_priv = NULL;
3037 +               if (sp->opdata_dsa_priv_num != NULL)
3038 +                       {
3039 +                       BN_free(sp->opdata_dsa_priv_num);
3040 +                       sp->opdata_dsa_priv_num = NULL;
3041 +                       }
3042 +               }
3044 +       return (ret);
3045 +       }
3048 + * Destroy DSA key object wrapper. If session is NULL, try to destroy all
3049 + * objects in the free list.
3050 + */
3051 +int
3052 +pk11_destroy_dsa_key_objects(PK11_SESSION *session)
3053 +       {
3054 +       int ret = 1;
3055 +       PK11_SESSION *sp = NULL;
3056 +       PK11_SESSION *local_free_session;
3057 +       CK_BBOOL uselock = TRUE;
3059 +       if (session != NULL)
3060 +               local_free_session = session;
3061 +       else
3062 +               {
3063 +#ifndef NOPTHREADS
3064 +               OPENSSL_assert(pthread_mutex_lock(session_cache[OP_DSA].lock) == 0);
3065 +#else
3066 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
3067 +#endif
3068 +               local_free_session = session_cache[OP_DSA].head;
3069 +               uselock = FALSE;
3070 +               }
3072 +       /*
3073 +        * go through the list of sessions and delete key objects
3074 +        */
3075 +       while ((sp = local_free_session) != NULL)
3076 +               {
3077 +               local_free_session = sp->next;
3079 +               /*
3080 +                * Do not terminate list traversal if one of the
3081 +                * destroy operations fails.
3082 +                */
3083 +               if (pk11_destroy_dsa_object_pub(sp, uselock) == 0)
3084 +                       {
3085 +                       ret = 0;
3086 +                       continue;
3087 +                       }
3088 +               if (pk11_destroy_dsa_object_priv(sp, uselock) == 0)
3089 +                       {
3090 +                       ret = 0;
3091 +                       continue;
3092 +                       }
3093 +               }
3095 +#ifndef NOPTHREADS
3096 +       if (session == NULL)
3097 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[OP_DSA].lock) == 0);
3098 +#else
3099 +       if (session == NULL)
3100 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
3101 +#endif
3103 +       return (ret);
3104 +       }
3105 +#endif /* OPENSSL_NO_DSA */
3107 +#ifndef OPENSSL_NO_DH
3108 +/* Destroy DH key from single session. */
3109 +int
3110 +pk11_destroy_dh_object(PK11_SESSION *sp, CK_BBOOL uselock)
3111 +       {
3112 +       int ret = 0;
3114 +       if (sp->opdata_dh_key != CK_INVALID_HANDLE)
3115 +               {
3116 +               TRY_OBJ_DESTROY(sp, sp->opdata_dh_key,
3117 +                   ret, uselock, OP_DH, CK_TRUE);
3118 +               sp->opdata_dh_key = CK_INVALID_HANDLE;
3119 +               sp->opdata_dh = NULL;
3120 +               if (sp->opdata_dh_priv_num != NULL)
3121 +                       {
3122 +                       BN_free(sp->opdata_dh_priv_num);
3123 +                       sp->opdata_dh_priv_num = NULL;
3124 +                       }
3125 +               }
3127 +       return (ret);
3128 +       }
3131 + * Destroy DH key object wrapper.
3132 + *
3133 + * arg0: pointer to PKCS#11 engine session structure
3134 + *       if session is NULL, try to destroy all objects in the free list
3135 + */
3136 +int
3137 +pk11_destroy_dh_key_objects(PK11_SESSION *session)
3138 +       {
3139 +       int ret = 1;
3140 +       PK11_SESSION *sp = NULL;
3141 +       PK11_SESSION *local_free_session;
3142 +       CK_BBOOL uselock = TRUE;
3144 +       if (session != NULL)
3145 +               local_free_session = session;
3146 +       else
3147 +               {
3148 +#ifndef NOPTHREADS
3149 +               OPENSSL_assert(pthread_mutex_lock(session_cache[OP_DH].lock) == 0);
3150 +#else
3151 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
3152 +#endif
3153 +               local_free_session = session_cache[OP_DH].head;
3154 +               uselock = FALSE;
3155 +               }
3157 +       while ((sp = local_free_session) != NULL)
3158 +               {
3159 +               local_free_session = sp->next;
3161 +               /*
3162 +                * Do not terminate list traversal if one of the
3163 +                * destroy operations fails.
3164 +                */
3165 +               if (pk11_destroy_dh_object(sp, uselock) == 0)
3166 +                       {
3167 +                       ret = 0;
3168 +                       continue;
3169 +                       }
3170 +               }
3172 +#ifndef NOPTHREADS
3173 +       if (session == NULL)
3174 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[OP_DH].lock) == 0);
3175 +#else
3176 +       if (session == NULL)
3177 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
3178 +#endif
3180 +       return (ret);
3181 +       }
3182 +#endif /* OPENSSL_NO_DH */
3184 +static int
3185 +pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
3186 +       CK_BBOOL persistent)
3187 +       {
3188 +       CK_RV rv;
3190 +       /*
3191 +        * We never try to destroy persistent objects which are the objects
3192 +        * stored in the keystore. Also, we always use read-only sessions so
3193 +        * C_DestroyObject() would be returning CKR_SESSION_READ_ONLY here.
3194 +        */
3195 +       if (persistent == CK_TRUE)
3196 +               return (1);
3198 +       rv = pFuncList->C_DestroyObject(session, oh);
3199 +       if (rv != CKR_OK)
3200 +               {
3201 +               PK11err_add_data(PK11_F_DESTROY_OBJECT, PK11_R_DESTROYOBJECT,
3202 +                   rv);
3203 +               return (0);
3204 +               }
3206 +       return (1);
3207 +       }
3210 +/* Symmetric ciphers and digests support functions */
3212 +static int
3213 +cipher_nid_to_pk11(int nid)
3214 +       {
3215 +       int i;
3217 +       for (i = 0; i < PK11_CIPHER_MAX; i++)
3218 +               if (ciphers[i].nid == nid)
3219 +                       return (ciphers[i].id);
3220 +       return (-1);
3221 +       }
3223 +static int
3224 +pk11_usable_ciphers(const int **nids)
3225 +       {
3226 +       if (cipher_count > 0)
3227 +               *nids = cipher_nids;
3228 +       else
3229 +               *nids = NULL;
3230 +       return (cipher_count);
3231 +       }
3233 +static int
3234 +pk11_usable_digests(const int **nids)
3235 +       {
3236 +       if (digest_count > 0)
3237 +               *nids = digest_nids;
3238 +       else
3239 +               *nids = NULL;
3240 +       return (digest_count);
3241 +       }
3244 + * Init context for encryption or decryption using a symmetric key.
3245 + */
3246 +static int pk11_init_symmetric(EVP_CIPHER_CTX *ctx, PK11_CIPHER *pcipher,
3247 +       PK11_SESSION *sp, CK_MECHANISM_PTR pmech)
3248 +       {
3249 +       CK_RV rv;
3250 +       CK_AES_CTR_PARAMS ctr_params;
3252 +       /*
3253 +        * We expect pmech->mechanism to be already set and
3254 +        * pParameter/ulParameterLen initialized to NULL/0 before
3255 +        * pk11_init_symetric() is called.
3256 +        */
3257 +       OPENSSL_assert(pmech->mechanism != 0);
3258 +       OPENSSL_assert(pmech->pParameter == NULL);
3259 +       OPENSSL_assert(pmech->ulParameterLen == 0);
3261 +       if (ctx->cipher->nid == NID_aes_128_ctr ||
3262 +           ctx->cipher->nid == NID_aes_192_ctr ||
3263 +           ctx->cipher->nid == NID_aes_256_ctr)
3264 +               {
3265 +               pmech->pParameter = (void *)(&ctr_params);
3266 +               pmech->ulParameterLen = sizeof (ctr_params);
3267 +               /*
3268 +                * For now, we are limited to the fixed length of the counter,
3269 +                * it covers the whole counter block. That's what RFC 4344
3270 +                * needs. For more information on internal structure of the
3271 +                * counter block, see RFC 3686. If needed in the future, we can
3272 +                * add code so that the counter length can be set via
3273 +                * ENGINE_ctrl() function.
3274 +                */
3275 +               ctr_params.ulCounterBits = AES_BLOCK_SIZE * 8;
3276 +               OPENSSL_assert(pcipher->iv_len == AES_BLOCK_SIZE);
3277 +               (void) memcpy(ctr_params.cb, ctx->iv, AES_BLOCK_SIZE);
3278 +               }
3279 +       else
3280 +               {
3281 +               if (pcipher->iv_len > 0)
3282 +                       {
3283 +                       pmech->pParameter = (void *)ctx->iv;
3284 +                       pmech->ulParameterLen = pcipher->iv_len;
3285 +                       }
3286 +               }
3288 +       /* if we get here, the encryption needs to be reinitialized */
3289 +       if (ctx->encrypt)
3290 +               rv = pFuncList->C_EncryptInit(sp->session, pmech,
3291 +                       sp->opdata_cipher_key);
3292 +       else
3293 +               rv = pFuncList->C_DecryptInit(sp->session, pmech,
3294 +                       sp->opdata_cipher_key);
3296 +       if (rv != CKR_OK)
3297 +               {
3298 +               PK11err_add_data(PK11_F_CIPHER_INIT, ctx->encrypt ?
3299 +                   PK11_R_ENCRYPTINIT : PK11_R_DECRYPTINIT, rv);
3300 +               pk11_return_session(sp, OP_CIPHER);
3301 +               return (0);
3302 +               }
3304 +       return (1);
3305 +       }
3307 +/* ARGSUSED */
3308 +static int
3309 +pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
3310 +    const unsigned char *iv, int enc)
3311 +       {
3312 +       CK_MECHANISM mech;
3313 +       int index;
3314 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
3315 +       PK11_SESSION *sp;
3316 +       PK11_CIPHER *p_ciph_table_row;
3318 +       state->sp = NULL;
3320 +       index = cipher_nid_to_pk11(ctx->cipher->nid);
3321 +       if (index < 0 || index >= PK11_CIPHER_MAX)
3322 +               return (0);
3324 +       p_ciph_table_row = &ciphers[index];
3325 +       /*
3326 +        * iv_len in the ctx->cipher structure is the maximum IV length for the
3327 +        * current cipher and it must be less or equal to the IV length in our
3328 +        * ciphers table. The key length must be in the allowed interval. From
3329 +        * all cipher modes that the PKCS#11 engine supports only RC4 allows a
3330 +        * key length to be in some range, all other NIDs have a precise key
3331 +        * length. Every application can define its own EVP functions so this
3332 +        * code serves as a sanity check.
3333 +        *
3334 +        * Note that the reason why the IV length in ctx->cipher might be
3335 +        * greater than the actual length is that OpenSSL uses BLOCK_CIPHER_defs
3336 +        * macro to define functions that return EVP structures for all DES
3337 +        * modes. So, even ECB modes get 8 byte IV.
3338 +        */
3339 +       if (ctx->cipher->iv_len < p_ciph_table_row->iv_len ||
3340 +           ctx->key_len < p_ciph_table_row->min_key_len ||
3341 +           ctx->key_len > p_ciph_table_row->max_key_len) {
3342 +               PK11err(PK11_F_CIPHER_INIT, PK11_R_KEY_OR_IV_LEN_PROBLEM);
3343 +               return (0);
3344 +       }
3346 +       if ((sp = pk11_get_session(OP_CIPHER)) == NULL)
3347 +               return (0);
3349 +       /* if applicable, the mechanism parameter is used for IV */
3350 +       mech.mechanism = p_ciph_table_row->mech_type;
3351 +       mech.pParameter = NULL;
3352 +       mech.ulParameterLen = 0;
3354 +       /* The key object is destroyed here if it is not the current key. */
3355 +       (void) check_new_cipher_key(sp, key, ctx->key_len);
3357 +       /*
3358 +        * If the key is the same and the encryption is also the same, then
3359 +        * just reuse it. However, we must not forget to reinitialize the
3360 +        * context that was finalized in pk11_cipher_cleanup().
3361 +        */
3362 +       if (sp->opdata_cipher_key != CK_INVALID_HANDLE &&
3363 +           sp->opdata_encrypt == ctx->encrypt)
3364 +               {
3365 +               state->sp = sp;
3366 +               if (pk11_init_symmetric(ctx, p_ciph_table_row, sp, &mech) == 0)
3367 +                       return (0);
3369 +               return (1);
3370 +               }
3372 +       /*
3373 +        * Check if the key has been invalidated. If so, a new key object
3374 +        * needs to be created.
3375 +        */
3376 +       if (sp->opdata_cipher_key == CK_INVALID_HANDLE)
3377 +               {
3378 +               sp->opdata_cipher_key = pk11_get_cipher_key(
3379 +                       ctx, key, p_ciph_table_row->key_type, sp);
3380 +               }
3382 +       if (sp->opdata_encrypt != ctx->encrypt && sp->opdata_encrypt != -1)
3383 +               {
3384 +               /*
3385 +                * The previous encryption/decryption is different. Need to
3386 +                * terminate the previous * active encryption/decryption here.
3387 +                */
3388 +               if (!pk11_cipher_final(sp))
3389 +                       {
3390 +                       pk11_return_session(sp, OP_CIPHER);
3391 +                       return (0);
3392 +                       }
3393 +               }
3395 +       if (sp->opdata_cipher_key == CK_INVALID_HANDLE)
3396 +               {
3397 +               pk11_return_session(sp, OP_CIPHER);
3398 +               return (0);
3399 +               }
3401 +       /* now initialize the context with a new key */
3402 +       if (pk11_init_symmetric(ctx, p_ciph_table_row, sp, &mech) == 0)
3403 +               return (0);
3405 +       sp->opdata_encrypt = ctx->encrypt;
3406 +       state->sp = sp;
3408 +       return (1);
3409 +       }
3412 + * When reusing the same key in an encryption/decryption session for a
3413 + * decryption/encryption session, we need to close the active session
3414 + * and recreate a new one. Note that the key is in the global session so
3415 + * that it needs not be recreated.
3416 + *
3417 + * It is more appropriate to use C_En/DecryptFinish here. At the time of this
3418 + * development, these two functions in the PKCS#11 libraries used return
3419 + * unexpected errors when passing in 0 length output. It may be a good
3420 + * idea to try them again if performance is a problem here and fix
3421 + * C_En/DecryptFinial if there are bugs there causing the problem.
3422 + */
3423 +static int
3424 +pk11_cipher_final(PK11_SESSION *sp)
3425 +       {
3426 +       CK_RV rv;
3428 +       rv = pFuncList->C_CloseSession(sp->session);
3429 +       if (rv != CKR_OK)
3430 +               {
3431 +               PK11err_add_data(PK11_F_CIPHER_FINAL, PK11_R_CLOSESESSION, rv);
3432 +               return (0);
3433 +               }
3435 +       rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
3436 +               NULL_PTR, NULL_PTR, &sp->session);
3437 +       if (rv != CKR_OK)
3438 +               {
3439 +               PK11err_add_data(PK11_F_CIPHER_FINAL, PK11_R_OPENSESSION, rv);
3440 +               return (0);
3441 +               }
3443 +       return (1);
3444 +       }
3447 + * An engine interface function. The calling function allocates sufficient
3448 + * memory for the output buffer "out" to hold the results.
3449 + */
3450 +#if OPENSSL_VERSION_NUMBER < 0x10000000L
3451 +static int
3452 +pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
3453 +       const unsigned char *in, unsigned int inl)
3454 +#else
3455 +static int
3456 +pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
3457 +       const unsigned char *in, size_t inl)
3458 +#endif
3459 +       {
3460 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
3461 +       PK11_SESSION *sp;
3462 +       CK_RV rv;
3463 +       unsigned long outl = inl;
3465 +       if (state == NULL || state->sp == NULL)
3466 +               return (0);
3468 +       sp = (PK11_SESSION *) state->sp;
3470 +       if (!inl)
3471 +               return (1);
3473 +       /* RC4 is the only stream cipher we support */
3474 +       if (ctx->cipher->nid != NID_rc4 && (inl % ctx->cipher->block_size) != 0)
3475 +               return (0);
3477 +       if (ctx->encrypt)
3478 +               {
3479 +               rv = pFuncList->C_EncryptUpdate(sp->session,
3480 +                       (unsigned char *)in, inl, out, &outl);
3482 +               if (rv != CKR_OK)
3483 +                       {
3484 +                       PK11err_add_data(PK11_F_CIPHER_DO_CIPHER,
3485 +                           PK11_R_ENCRYPTUPDATE, rv);
3486 +                       return (0);
3487 +                       }
3488 +               }
3489 +       else
3490 +               {
3491 +               rv = pFuncList->C_DecryptUpdate(sp->session,
3492 +                       (unsigned char *)in, inl, out, &outl);
3494 +               if (rv != CKR_OK)
3495 +                       {
3496 +                       PK11err_add_data(PK11_F_CIPHER_DO_CIPHER,
3497 +                           PK11_R_DECRYPTUPDATE, rv);
3498 +                       return (0);
3499 +                       }
3500 +               }
3502 +       /*
3503 +        * For DES_CBC, DES3_CBC, AES_CBC, and RC4, the output size is always
3504 +        * the same size of input.
3505 +        * The application has guaranteed to call the block ciphers with
3506 +        * correctly aligned buffers.
3507 +        */
3508 +       if (inl != outl)
3509 +               return (0);
3511 +       return (1);
3512 +       }
3515 + * Return the session to the pool. Calling C_EncryptFinal() and C_DecryptFinal()
3516 + * here is the right thing because in EVP_DecryptFinal_ex(), engine's
3517 + * do_cipher() is not even called, and in EVP_EncryptFinal_ex() it is called but
3518 + * the engine can't find out that it's the finalizing call. We wouldn't
3519 + * necessarily have to finalize the context here since reinitializing it with
3520 + * C_(Encrypt|Decrypt)Init() should be fine but for the sake of correctness,
3521 + * let's do it. Some implementations might leak memory if the previously used
3522 + * context is initialized without finalizing it first.
3523 + */
3524 +static int
3525 +pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx)
3526 +       {
3527 +       CK_RV rv;
3528 +       CK_ULONG len = EVP_MAX_BLOCK_LENGTH;
3529 +       CK_BYTE buf[EVP_MAX_BLOCK_LENGTH];
3530 +       PK11_CIPHER_STATE *state = ctx->cipher_data;
3532 +       if (state != NULL && state->sp != NULL)
3533 +               {
3534 +               /*
3535 +                * We are not interested in the data here, we just need to get
3536 +                * rid of the context.
3537 +                */
3538 +               if (ctx->encrypt)
3539 +                       rv = pFuncList->C_EncryptFinal(
3540 +                           state->sp->session, buf, &len);
3541 +               else
3542 +                       rv = pFuncList->C_DecryptFinal(
3543 +                           state->sp->session, buf, &len);
3545 +               if (rv != CKR_OK)
3546 +                       {
3547 +                       PK11err_add_data(PK11_F_CIPHER_CLEANUP, ctx->encrypt ?
3548 +                           PK11_R_ENCRYPTFINAL : PK11_R_DECRYPTFINAL, rv);
3549 +                       pk11_return_session(state->sp, OP_CIPHER);
3550 +                       return (0);
3551 +                       }
3553 +               pk11_return_session(state->sp, OP_CIPHER);
3554 +               state->sp = NULL;
3555 +               }
3557 +       return (1);
3558 +       }
3561 + * Registered by the ENGINE when used to find out how to deal with
3562 + * a particular NID in the ENGINE. This says what we'll do at the
3563 + * top level - note, that list is restricted by what we answer with
3564 + */
3565 +/* ARGSUSED */
3566 +static int
3567 +pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
3568 +       const int **nids, int nid)
3569 +       {
3570 +       if (!cipher)
3571 +               return (pk11_usable_ciphers(nids));
3573 +       switch (nid)
3574 +               {
3575 +               case NID_des_ede3_cbc:
3576 +                       *cipher = &pk11_3des_cbc;
3577 +                       break;
3578 +               case NID_des_cbc:
3579 +                       *cipher = &pk11_des_cbc;
3580 +                       break;
3581 +               case NID_des_ede3_ecb:
3582 +                       *cipher = &pk11_3des_ecb;
3583 +                       break;
3584 +               case NID_des_ecb:
3585 +                       *cipher = &pk11_des_ecb;
3586 +                       break;
3587 +               case NID_aes_128_cbc:
3588 +                       *cipher = &pk11_aes_128_cbc;
3589 +                       break;
3590 +               case NID_aes_192_cbc:
3591 +                       *cipher = &pk11_aes_192_cbc;
3592 +                       break;
3593 +               case NID_aes_256_cbc:
3594 +                       *cipher = &pk11_aes_256_cbc;
3595 +                       break;
3596 +               case NID_aes_128_ecb:
3597 +                       *cipher = &pk11_aes_128_ecb;
3598 +                       break;
3599 +               case NID_aes_192_ecb:
3600 +                       *cipher = &pk11_aes_192_ecb;
3601 +                       break;
3602 +               case NID_aes_256_ecb:
3603 +                       *cipher = &pk11_aes_256_ecb;
3604 +                       break;
3605 +               case NID_bf_cbc:
3606 +                       *cipher = &pk11_bf_cbc;
3607 +                       break;
3608 +               case NID_rc4:
3609 +                       *cipher = &pk11_rc4;
3610 +                       break;
3611 +               case NID_aes_128_ctr:
3612 +                       *cipher = &pk11_aes_128_ctr;
3613 +                       break;
3614 +               case NID_aes_192_ctr:
3615 +                       *cipher = &pk11_aes_192_ctr;
3616 +                       break;
3617 +               case NID_aes_256_ctr:
3618 +                       *cipher = &pk11_aes_256_ctr;
3619 +                       break;
3620 +               default:
3621 +                       *cipher = NULL;
3622 +                       break;
3623 +               }
3624 +       return (*cipher != NULL);
3625 +       }
3627 +/* ARGSUSED */
3628 +static int
3629 +pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
3630 +       const int **nids, int nid)
3631 +       {
3632 +       if (!digest)
3633 +               return (pk11_usable_digests(nids));
3635 +       switch (nid)
3636 +               {
3637 +               case NID_md5:
3638 +                       *digest = &pk11_md5;
3639 +                       break;
3640 +               case NID_sha1:
3641 +                       *digest = &pk11_sha1;
3642 +                       break;
3643 +               case NID_sha224:
3644 +                       *digest = &pk11_sha224;
3645 +                       break;
3646 +               case NID_sha256:
3647 +                       *digest = &pk11_sha256;
3648 +                       break;
3649 +               case NID_sha384:
3650 +                       *digest = &pk11_sha384;
3651 +                       break;
3652 +               case NID_sha512:
3653 +                       *digest = &pk11_sha512;
3654 +                       break;
3655 +               default:
3656 +                       *digest = NULL;
3657 +                       break;
3658 +               }
3659 +       return (*digest != NULL);
3660 +       }
3663 +/* Create a secret key object in a PKCS#11 session */
3664 +static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
3665 +       const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp)
3666 +       {
3667 +       CK_RV rv;
3668 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
3669 +       CK_OBJECT_CLASS obj_key = CKO_SECRET_KEY;
3670 +       CK_ULONG ul_key_attr_count = 6;
3671 +       unsigned char key_buf[PK11_KEY_LEN_MAX];
3673 +       CK_ATTRIBUTE  a_key_template[] =
3674 +               {
3675 +               {CKA_CLASS, (void*) NULL, sizeof (CK_OBJECT_CLASS)},
3676 +               {CKA_KEY_TYPE, (void*) NULL, sizeof (CK_KEY_TYPE)},
3677 +               {CKA_TOKEN, &myfalse, sizeof (myfalse)},
3678 +               {CKA_ENCRYPT, &mytrue, sizeof (mytrue)},
3679 +               {CKA_DECRYPT, &mytrue, sizeof (mytrue)},
3680 +               {CKA_VALUE, (void*) NULL, 0},
3681 +               };
3683 +       /*
3684 +        * Create secret key object in global_session. All other sessions
3685 +        * can use the key handles. Here is why:
3686 +        * OpenSSL will call EncryptInit and EncryptUpdate using a secret key.
3687 +        * It may then call DecryptInit and DecryptUpdate using the same key.
3688 +        * To use the same key object, we need to call EncryptFinal with
3689 +        * a 0 length message. Currently, this does not work for 3DES
3690 +        * mechanism. To get around this problem, we close the session and
3691 +        * then create a new session to use the same key object. When a session
3692 +        * is closed, all the object handles will be invalid. Thus, create key
3693 +        * objects in a global session, an individual session may be closed to
3694 +        * terminate the active operation.
3695 +        */
3696 +       CK_SESSION_HANDLE session = global_session;
3697 +       a_key_template[0].pValue = &obj_key;
3698 +       a_key_template[1].pValue = &key_type;
3699 +       if (ctx->key_len > PK11_KEY_LEN_MAX)
3700 +               {
3701 +               a_key_template[5].pValue = (void *) key;
3702 +               }
3703 +       else
3704 +               {
3705 +               memset(key_buf, 0, PK11_KEY_LEN_MAX);
3706 +               memcpy(key_buf, key, ctx->key_len);
3707 +               if ((key_type == CKK_DES) ||
3708 +                   (key_type == CKK_DES2) ||
3709 +                   (key_type == CKK_DES3))
3710 +                       DES_fixup_key_parity((DES_cblock *) &key_buf[0]);
3711 +               if ((key_type == CKK_DES2) ||
3712 +                   (key_type == CKK_DES3))
3713 +                       DES_fixup_key_parity((DES_cblock *) &key_buf[8]);
3714 +               if (key_type == CKK_DES3)
3715 +                       DES_fixup_key_parity((DES_cblock *) &key_buf[16]);
3716 +               a_key_template[5].pValue = (void *) key_buf;
3717 +               }
3718 +       a_key_template[5].ulValueLen = (unsigned long) ctx->key_len;
3720 +       rv = pFuncList->C_CreateObject(session,
3721 +               a_key_template, ul_key_attr_count, &h_key);
3722 +       if (rv != CKR_OK)
3723 +               {
3724 +               memset(key_buf, 0, PK11_KEY_LEN_MAX);
3725 +               PK11err_add_data(PK11_F_GET_CIPHER_KEY, PK11_R_CREATEOBJECT,
3726 +                   rv);
3727 +               goto err;
3728 +               }
3730 +       /*
3731 +        * Save the key information used in this session.
3732 +        * The max can be saved is PK11_KEY_LEN_MAX.
3733 +        */
3734 +       if (ctx->key_len > PK11_KEY_LEN_MAX)
3735 +               {
3736 +               sp->opdata_key_len = PK11_KEY_LEN_MAX;
3737 +               (void) memcpy(sp->opdata_key, key, sp->opdata_key_len);
3738 +               }
3739 +       else
3740 +               {
3741 +               sp->opdata_key_len = ctx->key_len;
3742 +               (void) memcpy(sp->opdata_key, key_buf, sp->opdata_key_len);
3743 +               }
3744 +       memset(key_buf, 0, PK11_KEY_LEN_MAX);
3745 +err:
3747 +       return (h_key);
3748 +       }
3750 +static int
3751 +md_nid_to_pk11(int nid)
3752 +       {
3753 +       int i;
3755 +       for (i = 0; i < PK11_DIGEST_MAX; i++)
3756 +               if (digests[i].nid == nid)
3757 +                       return (digests[i].id);
3758 +       return (-1);
3759 +       }
3761 +static int
3762 +pk11_digest_init(EVP_MD_CTX *ctx)
3763 +       {
3764 +       CK_RV rv;
3765 +       CK_MECHANISM mech;
3766 +       int index;
3767 +       PK11_SESSION *sp;
3768 +       PK11_DIGEST *pdp;
3769 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
3771 +       state->sp = NULL;
3773 +       index = md_nid_to_pk11(ctx->digest->type);
3774 +       if (index < 0 || index >= PK11_DIGEST_MAX)
3775 +               return (0);
3777 +       pdp = &digests[index];
3778 +       if ((sp = pk11_get_session(OP_DIGEST)) == NULL)
3779 +               return (0);
3781 +       /* at present, no parameter is needed for supported digests */
3782 +       mech.mechanism = pdp->mech_type;
3783 +       mech.pParameter = NULL;
3784 +       mech.ulParameterLen = 0;
3786 +       rv = pFuncList->C_DigestInit(sp->session, &mech);
3788 +       if (rv != CKR_OK)
3789 +               {
3790 +               PK11err_add_data(PK11_F_DIGEST_INIT, PK11_R_DIGESTINIT, rv);
3791 +               pk11_return_session(sp, OP_DIGEST);
3792 +               return (0);
3793 +               }
3795 +       state->sp = sp;
3797 +       return (1);
3798 +       }
3800 +static int
3801 +pk11_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
3802 +       {
3803 +       CK_RV rv;
3804 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
3806 +       /* 0 length message will cause a failure in C_DigestFinal */
3807 +       if (count == 0)
3808 +               return (1);
3810 +       if (state == NULL || state->sp == NULL)
3811 +               return (0);
3813 +       rv = pFuncList->C_DigestUpdate(state->sp->session, (CK_BYTE *) data,
3814 +               count);
3816 +       if (rv != CKR_OK)
3817 +               {
3818 +               PK11err_add_data(PK11_F_DIGEST_UPDATE, PK11_R_DIGESTUPDATE, rv);
3819 +               pk11_return_session(state->sp, OP_DIGEST);
3820 +               state->sp = NULL;
3821 +               return (0);
3822 +               }
3824 +       return (1);
3825 +       }
3827 +static int
3828 +pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
3829 +       {
3830 +       CK_RV rv;
3831 +       unsigned long len;
3832 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
3833 +       len = ctx->digest->md_size;
3835 +       if (state == NULL || state->sp == NULL)
3836 +               return (0);
3838 +       rv = pFuncList->C_DigestFinal(state->sp->session, md, &len);
3840 +       if (rv != CKR_OK)
3841 +               {
3842 +               PK11err_add_data(PK11_F_DIGEST_FINAL, PK11_R_DIGESTFINAL, rv);
3843 +               pk11_return_session(state->sp, OP_DIGEST);
3844 +               state->sp = NULL;
3845 +               return (0);
3846 +               }
3848 +       if (ctx->digest->md_size != len)
3849 +               return (0);
3851 +       /*
3852 +        * Final is called and digest is returned, so return the session
3853 +        * to the pool
3854 +        */
3855 +       pk11_return_session(state->sp, OP_DIGEST);
3856 +       state->sp = NULL;
3858 +       return (1);
3859 +       }
3861 +static int
3862 +pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
3863 +       {
3864 +       CK_RV rv;
3865 +       int ret = 0;
3866 +       PK11_CIPHER_STATE *state, *state_to;
3867 +       CK_BYTE_PTR pstate = NULL;
3868 +       CK_ULONG ul_state_len;
3870 +       /* The copy-from state */
3871 +       state = (PK11_CIPHER_STATE *) from->md_data;
3872 +       if (state == NULL || state->sp == NULL)
3873 +               goto err;
3875 +       /* Initialize the copy-to state */
3876 +       if (!pk11_digest_init(to))
3877 +               goto err;
3878 +       state_to = (PK11_CIPHER_STATE *) to->md_data;
3880 +       /* Get the size of the operation state of the copy-from session */
3881 +       rv = pFuncList->C_GetOperationState(state->sp->session, NULL,
3882 +               &ul_state_len);
3884 +       if (rv != CKR_OK)
3885 +               {
3886 +               PK11err_add_data(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE,
3887 +                   rv);
3888 +               goto err;
3889 +               }
3890 +       if (ul_state_len == 0)
3891 +               {
3892 +               goto err;
3893 +               }
3895 +       pstate = OPENSSL_malloc(ul_state_len);
3896 +       if (pstate == NULL)
3897 +               {
3898 +               PK11err(PK11_F_DIGEST_COPY, PK11_R_MALLOC_FAILURE);
3899 +               goto err;
3900 +               }
3902 +       /* Get the operation state of the copy-from session */
3903 +       rv = pFuncList->C_GetOperationState(state->sp->session, pstate,
3904 +               &ul_state_len);
3906 +       if (rv != CKR_OK)
3907 +               {
3908 +               PK11err_add_data(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE,
3909 +                   rv);
3910 +               goto err;
3911 +               }
3913 +       /* Set the operation state of the copy-to session */
3914 +       rv = pFuncList->C_SetOperationState(state_to->sp->session, pstate,
3915 +               ul_state_len, 0, 0);
3917 +       if (rv != CKR_OK)
3918 +               {
3919 +               PK11err_add_data(PK11_F_DIGEST_COPY,
3920 +                   PK11_R_SET_OPERATION_STATE, rv);
3921 +               goto err;
3922 +               }
3924 +       ret = 1;
3925 +err:
3926 +       if (pstate != NULL)
3927 +               OPENSSL_free(pstate);
3929 +       return (ret);
3930 +       }
3932 +/* Return any pending session state to the pool */
3933 +static int
3934 +pk11_digest_cleanup(EVP_MD_CTX *ctx)
3935 +       {
3936 +       PK11_CIPHER_STATE *state = ctx->md_data;
3937 +       unsigned char buf[EVP_MAX_MD_SIZE];
3939 +       if (state != NULL && state->sp != NULL)
3940 +               {
3941 +               /*
3942 +                * If state->sp is not NULL then pk11_digest_final() has not
3943 +                * been called yet. We must call it now to free any memory
3944 +                * that might have been allocated in the token when
3945 +                * pk11_digest_init() was called. pk11_digest_final()
3946 +                * will return the session to the cache.
3947 +                */
3948 +               if (!pk11_digest_final(ctx, buf))
3949 +                       return (0);
3950 +               }
3952 +       return (1);
3953 +       }
3956 + * Check if the new key is the same as the key object in the session. If the key
3957 + * is the same, no need to create a new key object. Otherwise, the old key
3958 + * object needs to be destroyed and a new one will be created. Return 1 for
3959 + * cache hit, 0 for cache miss. Note that we must check the key length first
3960 + * otherwise we could end up reusing a different, longer key with the same
3961 + * prefix.
3962 + */
3963 +static int check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key,
3964 +       int key_len)
3965 +       {
3966 +       if (sp->opdata_key_len != key_len ||
3967 +           memcmp(sp->opdata_key, key, key_len) != 0)
3968 +               {
3969 +               (void) pk11_destroy_cipher_key_objects(sp);
3970 +               return (0);
3971 +               }
3972 +       return (1);
3973 +       }
3975 +/* Destroy one or more secret key objects. */
3976 +static int pk11_destroy_cipher_key_objects(PK11_SESSION *session)
3977 +       {
3978 +       int ret = 0;
3979 +       PK11_SESSION *sp = NULL;
3980 +       PK11_SESSION *local_free_session;
3982 +       if (session != NULL)
3983 +               local_free_session = session;
3984 +       else
3985 +               {
3986 +#ifndef NOPTHREADS
3987 +               OPENSSL_assert(pthread_mutex_lock(session_cache[OP_CIPHER].lock) == 0);
3988 +#else
3989 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
3990 +#endif
3991 +               local_free_session = session_cache[OP_CIPHER].head;
3992 +               }
3994 +       while ((sp = local_free_session) != NULL)
3995 +               {
3996 +               local_free_session = sp->next;
3998 +               if (sp->opdata_cipher_key != CK_INVALID_HANDLE)
3999 +                       {
4000 +                       /*
4001 +                        * The secret key object is created in the
4002 +                        * global_session. See pk11_get_cipher_key().
4003 +                        */
4004 +                       if (pk11_destroy_object(global_session,
4005 +                               sp->opdata_cipher_key, CK_FALSE) == 0)
4006 +                               goto err;
4007 +                       sp->opdata_cipher_key = CK_INVALID_HANDLE;
4008 +                       }
4009 +               }
4010 +       ret = 1;
4011 +err:
4013 +#ifndef NOPTHREADS
4014 +       if (session == NULL)
4015 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[OP_CIPHER].lock) == 0);
4016 +#else
4017 +       if (session == NULL)
4018 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
4019 +#endif
4021 +       return (ret);
4022 +       }
4026 + * Public key mechanisms optionally supported
4027 + *
4028 + * CKM_RSA_X_509
4029 + * CKM_RSA_PKCS
4030 + * CKM_DSA
4031 + *
4032 + * The first slot that supports at least one of those mechanisms is chosen as a
4033 + * public key slot.
4034 + *
4035 + * Symmetric ciphers optionally supported
4036 + *
4037 + * CKM_DES3_CBC
4038 + * CKM_DES_CBC
4039 + * CKM_AES_CBC
4040 + * CKM_DES3_ECB
4041 + * CKM_DES_ECB
4042 + * CKM_AES_ECB
4043 + * CKM_AES_CTR
4044 + * CKM_RC4
4045 + * CKM_BLOWFISH_CBC
4046 + *
4047 + * Digests optionally supported
4048 + *
4049 + * CKM_MD5
4050 + * CKM_SHA_1
4051 + * CKM_SHA224
4052 + * CKM_SHA256
4053 + * CKM_SHA384
4054 + * CKM_SHA512
4055 + *
4056 + * The output of this function is a set of global variables indicating which
4057 + * mechanisms from RSA, DSA, DH and RAND are present, and also two arrays of
4058 + * mechanisms, one for symmetric ciphers and one for digests. Also, 3 global
4059 + * variables carry information about which slot was chosen for (a) public key
4060 + * mechanisms, (b) random operations, and (c) symmetric ciphers and digests.
4061 + */
4062 +static int
4063 +pk11_choose_slots(int *any_slot_found)
4064 +       {
4065 +       CK_SLOT_ID_PTR pSlotList = NULL_PTR;
4066 +       CK_ULONG ulSlotCount = 0;
4067 +       CK_MECHANISM_INFO mech_info;
4068 +       CK_TOKEN_INFO token_info;
4069 +       unsigned int i;
4070 +       CK_RV rv;
4071 +       CK_SLOT_ID best_slot_sofar = 0;
4072 +       CK_BBOOL found_candidate_slot = CK_FALSE;
4073 +       int slot_n_cipher = 0;
4074 +       int slot_n_digest = 0;
4075 +       CK_SLOT_ID current_slot = 0;
4076 +       int current_slot_n_cipher = 0;
4077 +       int current_slot_n_digest = 0;
4079 +       int local_cipher_nids[PK11_CIPHER_MAX];
4080 +       int local_digest_nids[PK11_DIGEST_MAX];
4082 +       /* let's initialize the output parameter */
4083 +       if (any_slot_found != NULL)
4084 +               *any_slot_found = 0;
4086 +       /* Get slot list for memory allocation */
4087 +       rv = pFuncList->C_GetSlotList(CK_FALSE, NULL_PTR, &ulSlotCount);
4089 +       if (rv != CKR_OK)
4090 +               {
4091 +               PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
4092 +               return (0);
4093 +               }
4095 +       /* it's not an error if we didn't find any providers */
4096 +       if (ulSlotCount == 0)
4097 +               {
4098 +#ifdef DEBUG_SLOT_SELECTION
4099 +               fprintf(stderr, "%s: no crypto providers found\n", PK11_DBG);
4100 +#endif /* DEBUG_SLOT_SELECTION */
4101 +               return (1);
4102 +               }
4104 +       pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
4106 +       if (pSlotList == NULL)
4107 +               {
4108 +               PK11err(PK11_F_CHOOSE_SLOT, PK11_R_MALLOC_FAILURE);
4109 +               return (0);
4110 +               }
4112 +       /* Get the slot list for processing */
4113 +       rv = pFuncList->C_GetSlotList(CK_FALSE, pSlotList, &ulSlotCount);
4114 +       if (rv != CKR_OK)
4115 +               {
4116 +               PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
4117 +               OPENSSL_free(pSlotList);
4118 +               return (0);
4119 +               }
4121 +#ifdef DEBUG_SLOT_SELECTION
4122 +       fprintf(stderr, "%s: provider: %s\n", PK11_DBG, def_PK11_LIBNAME);
4123 +       fprintf(stderr, "%s: number of slots: %d\n", PK11_DBG, ulSlotCount);
4125 +       fprintf(stderr, "%s: == checking rand slots ==\n", PK11_DBG);
4126 +#endif /* DEBUG_SLOT_SELECTION */
4127 +       for (i = 0; i < ulSlotCount; i++)
4128 +               {
4129 +               current_slot = pSlotList[i];
4131 +#ifdef DEBUG_SLOT_SELECTION
4132 +       fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
4133 +#endif /* DEBUG_SLOT_SELECTION */
4134 +               /* Check if slot has random support. */
4135 +               rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
4136 +               if (rv != CKR_OK)
4137 +                       continue;
4139 +#ifdef DEBUG_SLOT_SELECTION
4140 +       fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
4141 +#endif /* DEBUG_SLOT_SELECTION */
4143 +               if (token_info.flags & CKF_RNG)
4144 +                       {
4145 +#ifdef DEBUG_SLOT_SELECTION
4146 +       fprintf(stderr, "%s: this token has CKF_RNG flag\n", PK11_DBG);
4147 +#endif /* DEBUG_SLOT_SELECTION */
4148 +                       pk11_have_random = CK_TRUE;
4149 +                       rand_SLOTID = current_slot;
4150 +                       break;
4151 +                       }
4152 +               }
4154 +#ifdef DEBUG_SLOT_SELECTION
4155 +       fprintf(stderr, "%s: == checking pubkey slots ==\n", PK11_DBG);
4156 +#endif /* DEBUG_SLOT_SELECTION */
4158 +       pubkey_SLOTID = pSlotList[0];
4159 +       for (i = 0; i < ulSlotCount; i++)
4160 +               {
4161 +               CK_BBOOL slot_has_rsa = CK_FALSE;
4162 +               CK_BBOOL slot_has_recover = CK_FALSE;
4163 +               CK_BBOOL slot_has_dsa = CK_FALSE;
4164 +               CK_BBOOL slot_has_dh = CK_FALSE;
4165 +               current_slot = pSlotList[i];
4167 +#ifdef DEBUG_SLOT_SELECTION
4168 +       fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
4169 +#endif /* DEBUG_SLOT_SELECTION */
4170 +               rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
4171 +               if (rv != CKR_OK)
4172 +                       continue;
4174 +#ifdef DEBUG_SLOT_SELECTION
4175 +       fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
4176 +#endif /* DEBUG_SLOT_SELECTION */
4178 +#ifndef OPENSSL_NO_RSA
4179 +               /*
4180 +                * Check if this slot is capable of signing and
4181 +                * verifying with CKM_RSA_PKCS.
4182 +                */
4183 +               rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS,
4184 +                       &mech_info);
4186 +               if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
4187 +                               (mech_info.flags & CKF_VERIFY)))
4188 +                       {
4189 +                       /*
4190 +                        * Check if this slot is capable of encryption,
4191 +                        * decryption, sign, and verify with CKM_RSA_X_509.
4192 +                        */
4193 +                       rv = pFuncList->C_GetMechanismInfo(current_slot,
4194 +                           CKM_RSA_X_509, &mech_info);
4196 +                       if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
4197 +                           (mech_info.flags & CKF_VERIFY) &&
4198 +                           (mech_info.flags & CKF_ENCRYPT) &&
4199 +                           (mech_info.flags & CKF_DECRYPT)))
4200 +                               {
4201 +                               slot_has_rsa = CK_TRUE;
4202 +                               if (mech_info.flags & CKF_VERIFY_RECOVER)
4203 +                                       {
4204 +                                       slot_has_recover = CK_TRUE;
4205 +                                       }
4206 +                               }
4207 +                       }
4208 +#endif /* OPENSSL_NO_RSA */
4210 +#ifndef OPENSSL_NO_DSA
4211 +               /*
4212 +                * Check if this slot is capable of signing and
4213 +                * verifying with CKM_DSA.
4214 +                */
4215 +               rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_DSA,
4216 +                       &mech_info);
4217 +               if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
4218 +                   (mech_info.flags & CKF_VERIFY)))
4219 +                       {
4220 +                       slot_has_dsa = CK_TRUE;
4221 +                       }
4223 +#endif /* OPENSSL_NO_DSA */
4225 +#ifndef OPENSSL_NO_DH
4226 +               /*
4227 +                * Check if this slot is capable of DH key generataion and
4228 +                * derivation.
4229 +                */
4230 +               rv = pFuncList->C_GetMechanismInfo(current_slot,
4231 +                   CKM_DH_PKCS_KEY_PAIR_GEN, &mech_info);
4233 +               if (rv == CKR_OK && (mech_info.flags & CKF_GENERATE_KEY_PAIR))
4234 +                       {
4235 +                       rv = pFuncList->C_GetMechanismInfo(current_slot,
4236 +                               CKM_DH_PKCS_DERIVE, &mech_info);
4237 +                       if (rv == CKR_OK && (mech_info.flags & CKF_DERIVE))
4238 +                               {
4239 +                               slot_has_dh = CK_TRUE;
4240 +                               }
4241 +                       }
4242 +#endif /* OPENSSL_NO_DH */
4244 +               if (!found_candidate_slot &&
4245 +                   (slot_has_rsa || slot_has_dsa || slot_has_dh))
4246 +                       {
4247 +#ifdef DEBUG_SLOT_SELECTION
4248 +                       fprintf(stderr,
4249 +                           "%s: potential slot: %d\n", PK11_DBG, current_slot);
4250 +#endif /* DEBUG_SLOT_SELECTION */
4251 +                       best_slot_sofar = current_slot;
4252 +                       pk11_have_rsa = slot_has_rsa;
4253 +                       pk11_have_recover = slot_has_recover;
4254 +                       pk11_have_dsa = slot_has_dsa;
4255 +                       pk11_have_dh = slot_has_dh;
4256 +                       found_candidate_slot = CK_TRUE;
4257 +                       /*
4258 +                        * Cache the flags for later use. We might
4259 +                        * need those if RSA keys by reference feature
4260 +                        * is used.
4261 +                        */
4262 +                       pubkey_token_flags = token_info.flags;
4263 +#ifdef DEBUG_SLOT_SELECTION
4264 +                       fprintf(stderr,
4265 +                           "%s: setting found_candidate_slot to CK_TRUE\n",
4266 +                           PK11_DBG);
4267 +                       fprintf(stderr,
4268 +                           "%s: best so far slot: %d\n", PK11_DBG,
4269 +                           best_slot_sofar);
4270 +                       fprintf(stderr, "%s: pubkey flags changed to "
4271 +                           "%lu.\n", PK11_DBG, pubkey_token_flags);
4272 +                       }
4273 +               else
4274 +                       {
4275 +                       fprintf(stderr,
4276 +                           "%s: no rsa/dsa/dh\n", PK11_DBG);
4277 +                       }
4278 +#else
4279 +                       } /* if */
4280 +#endif /* DEBUG_SLOT_SELECTION */
4281 +               } /* for */
4283 +       if (found_candidate_slot == CK_TRUE)
4284 +               {
4285 +               pubkey_SLOTID = best_slot_sofar;
4286 +               }
4288 +       found_candidate_slot = CK_FALSE;
4289 +       best_slot_sofar = 0;
4291 +#ifdef DEBUG_SLOT_SELECTION
4292 +       fprintf(stderr, "%s: == checking cipher/digest ==\n", PK11_DBG);
4293 +#endif /* DEBUG_SLOT_SELECTION */
4295 +       SLOTID = pSlotList[0];
4296 +       for (i = 0; i < ulSlotCount; i++)
4297 +               {
4298 +#ifdef DEBUG_SLOT_SELECTION
4299 +       fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
4300 +#endif /* DEBUG_SLOT_SELECTION */
4302 +               current_slot = pSlotList[i];
4303 +               current_slot_n_cipher = 0;
4304 +               current_slot_n_digest = 0;
4305 +               (void) memset(local_cipher_nids, 0, sizeof (local_cipher_nids));
4306 +               (void) memset(local_digest_nids, 0, sizeof (local_digest_nids));
4308 +               pk11_find_symmetric_ciphers(pFuncList, current_slot,
4309 +                   &current_slot_n_cipher, local_cipher_nids);
4311 +               pk11_find_digests(pFuncList, current_slot,
4312 +                   &current_slot_n_digest, local_digest_nids);
4314 +#ifdef DEBUG_SLOT_SELECTION
4315 +               fprintf(stderr, "%s: current_slot_n_cipher %d\n", PK11_DBG,
4316 +                       current_slot_n_cipher);
4317 +               fprintf(stderr, "%s: current_slot_n_digest %d\n", PK11_DBG,
4318 +                       current_slot_n_digest);
4319 +               fprintf(stderr, "%s: best so far cipher/digest slot: %d\n",
4320 +                       PK11_DBG, best_slot_sofar);
4321 +#endif /* DEBUG_SLOT_SELECTION */
4323 +               /*
4324 +                * If the current slot supports more ciphers/digests than
4325 +                * the previous best one we change the current best to this one,
4326 +                * otherwise leave it where it is.
4327 +                */
4328 +               if ((current_slot_n_cipher + current_slot_n_digest) >
4329 +                   (slot_n_cipher + slot_n_digest))
4330 +                       {
4331 +#ifdef DEBUG_SLOT_SELECTION
4332 +                       fprintf(stderr,
4333 +                               "%s: changing best so far slot to %d\n",
4334 +                               PK11_DBG, current_slot);
4335 +#endif /* DEBUG_SLOT_SELECTION */
4336 +                       best_slot_sofar = SLOTID = current_slot;
4337 +                       cipher_count = slot_n_cipher = current_slot_n_cipher;
4338 +                       digest_count = slot_n_digest = current_slot_n_digest;
4339 +                       (void) memcpy(cipher_nids, local_cipher_nids,
4340 +                           sizeof (local_cipher_nids));
4341 +                       (void) memcpy(digest_nids, local_digest_nids, 
4342 +                           sizeof (local_digest_nids));
4343 +                       }
4344 +               }
4346 +#ifdef DEBUG_SLOT_SELECTION
4347 +       fprintf(stderr,
4348 +           "%s: chosen pubkey slot: %d\n", PK11_DBG, pubkey_SLOTID);
4349 +       fprintf(stderr,
4350 +           "%s: chosen rand slot: %d\n", PK11_DBG, rand_SLOTID);
4351 +       fprintf(stderr,
4352 +           "%s: chosen cipher/digest slot: %d\n", PK11_DBG, SLOTID);
4353 +       fprintf(stderr,
4354 +           "%s: pk11_have_rsa %d\n", PK11_DBG, pk11_have_rsa);
4355 +       fprintf(stderr,
4356 +           "%s: pk11_have_recover %d\n", PK11_DBG, pk11_have_recover);
4357 +       fprintf(stderr,
4358 +           "%s: pk11_have_dsa %d\n", PK11_DBG, pk11_have_dsa);
4359 +       fprintf(stderr,
4360 +           "%s: pk11_have_dh %d\n", PK11_DBG, pk11_have_dh);
4361 +       fprintf(stderr,
4362 +           "%s: pk11_have_random %d\n", PK11_DBG, pk11_have_random);
4363 +       fprintf(stderr,
4364 +           "%s: cipher_count %d\n", PK11_DBG, cipher_count);
4365 +       fprintf(stderr,
4366 +           "%s: digest_count %d\n", PK11_DBG, digest_count);
4367 +#endif /* DEBUG_SLOT_SELECTION */
4369 +       if (pSlotList != NULL)
4370 +               OPENSSL_free(pSlotList);
4372 +#ifdef SOLARIS_HW_SLOT_SELECTION
4373 +       OPENSSL_free(hw_cnids);
4374 +       OPENSSL_free(hw_dnids);
4375 +#endif /* SOLARIS_HW_SLOT_SELECTION */
4377 +       if (any_slot_found != NULL)
4378 +               *any_slot_found = 1;
4379 +       return (1);
4380 +       }
4382 +static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR pflist,
4383 +    int slot_id, CK_MECHANISM_TYPE mech, int *current_slot_n_cipher,
4384 +    int *local_cipher_nids, int id)
4385 +       {
4386 +       CK_MECHANISM_INFO mech_info;
4387 +       CK_RV rv;
4389 +#ifdef DEBUG_SLOT_SELECTION
4390 +       fprintf(stderr, "%s: checking mech: %x", PK11_DBG, mech);
4391 +#endif /* DEBUG_SLOT_SELECTION */
4392 +       rv = pflist->C_GetMechanismInfo(slot_id, mech, &mech_info);
4394 +       if (rv != CKR_OK)
4395 +               {
4396 +#ifdef DEBUG_SLOT_SELECTION
4397 +               fprintf(stderr, " not found\n");
4398 +#endif /* DEBUG_SLOT_SELECTION */
4399 +               return;
4400 +               }
4402 +       if ((mech_info.flags & CKF_ENCRYPT) &&
4403 +           (mech_info.flags & CKF_DECRYPT))
4404 +               {
4405 +#ifdef SOLARIS_HW_SLOT_SELECTION
4406 +               if (nid_in_table(ciphers[id].nid, hw_cnids))
4407 +#endif /* SOLARIS_HW_SLOT_SELECTION */
4408 +                       {
4409 +#ifdef DEBUG_SLOT_SELECTION
4410 +               fprintf(stderr, " usable\n");
4411 +#endif /* DEBUG_SLOT_SELECTION */
4412 +                       local_cipher_nids[(*current_slot_n_cipher)++] =
4413 +                           ciphers[id].nid;
4414 +                       }
4415 +#ifdef SOLARIS_HW_SLOT_SELECTION
4416 +#ifdef DEBUG_SLOT_SELECTION
4417 +               else
4418 +                       {
4419 +               fprintf(stderr, " rejected, software implementation only\n");
4420 +                       }
4421 +#endif /* DEBUG_SLOT_SELECTION */
4422 +#endif /* SOLARIS_HW_SLOT_SELECTION */
4423 +               }
4424 +#ifdef DEBUG_SLOT_SELECTION
4425 +       else
4426 +               {
4427 +               fprintf(stderr, " unusable\n");
4428 +               }
4429 +#endif /* DEBUG_SLOT_SELECTION */
4431 +       return;
4432 +       }
4434 +static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
4435 +    CK_MECHANISM_TYPE mech, int *current_slot_n_digest, int *local_digest_nids,
4436 +    int id)
4437 +       {
4438 +       CK_MECHANISM_INFO mech_info;
4439 +       CK_RV rv;
4441 +#ifdef DEBUG_SLOT_SELECTION
4442 +       fprintf(stderr, "%s: checking mech: %x", PK11_DBG, mech);
4443 +#endif /* DEBUG_SLOT_SELECTION */
4444 +       rv = pflist->C_GetMechanismInfo(slot_id, mech, &mech_info);
4446 +       if (rv != CKR_OK)
4447 +               {
4448 +#ifdef DEBUG_SLOT_SELECTION
4449 +               fprintf(stderr, " not found\n");
4450 +#endif /* DEBUG_SLOT_SELECTION */
4451 +               return;
4452 +               }
4454 +       if (mech_info.flags & CKF_DIGEST)
4455 +               {
4456 +#ifdef SOLARIS_HW_SLOT_SELECTION
4457 +               if (nid_in_table(digests[id].nid, hw_dnids))
4458 +#endif /* SOLARIS_HW_SLOT_SELECTION */
4459 +                       {
4460 +#ifdef DEBUG_SLOT_SELECTION
4461 +               fprintf(stderr, " usable\n");
4462 +#endif /* DEBUG_SLOT_SELECTION */
4463 +                       local_digest_nids[(*current_slot_n_digest)++] =
4464 +                           digests[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 +/* Find what symmetric ciphers this slot supports. */
4486 +static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
4487 +    CK_SLOT_ID current_slot, int *current_slot_n_cipher, int *local_cipher_nids)
4488 +       {
4489 +       int i;
4491 +       for (i = 0; i < PK11_CIPHER_MAX; ++i)
4492 +               {
4493 +               pk11_get_symmetric_cipher(pflist, current_slot,
4494 +                   ciphers[i].mech_type, current_slot_n_cipher,
4495 +                   local_cipher_nids, ciphers[i].id);
4496 +               }
4497 +       }
4499 +/* Find what digest algorithms this slot supports. */
4500 +static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
4501 +    CK_SLOT_ID current_slot, int *current_slot_n_digest, int *local_digest_nids)
4502 +       {
4503 +       int i;
4505 +       for (i = 0; i < PK11_DIGEST_MAX; ++i)
4506 +               {
4507 +               pk11_get_digest(pflist, current_slot, digests[i].mech_type,
4508 +                   current_slot_n_digest, local_digest_nids, digests[i].id);
4509 +               }
4510 +       }
4512 +#ifdef SOLARIS_HW_SLOT_SELECTION
4514 + * It would be great if we could use pkcs11_kernel directly since this library
4515 + * offers hardware slots only. That's the easiest way to achieve the situation
4516 + * where we use the hardware accelerators when present and OpenSSL native code
4517 + * otherwise. That presumes the fact that OpenSSL native code is faster than the
4518 + * code in the soft token. It's a logical assumption - Crypto Framework has some
4519 + * inherent overhead so going there for the software implementation of a
4520 + * mechanism should be logically slower in contrast to the OpenSSL native code,
4521 + * presuming that both implementations are of similar speed. For example, the
4522 + * soft token for AES is roughly three times slower than OpenSSL for 64 byte
4523 + * blocks and still 20% slower for 8KB blocks. So, if we want to ship products
4524 + * that use the PKCS#11 engine by default, we must somehow avoid that regression
4525 + * on machines without hardware acceleration. That's why switching to the
4526 + * pkcs11_kernel library seems like a very good idea.
4527 + *
4528 + * The problem is that OpenSSL built with SunStudio is roughly 2x slower for
4529 + * asymmetric operations (RSA/DSA/DH) than the soft token built with the same
4530 + * compiler. That means that if we switched to pkcs11_kernel from the libpkcs11
4531 + * library, we would have had a performance regression on machines without
4532 + * hardware acceleration for asymmetric operations for all applications that use
4533 + * the PKCS#11 engine. There is one such application - Apache web server since
4534 + * it's shipped configured to use the PKCS#11 engine by default. Having said
4535 + * that, we can't switch to the pkcs11_kernel library now and have to come with
4536 + * a solution that, on non-accelerated machines, uses the OpenSSL native code
4537 + * for all symmetric ciphers and digests while it uses the soft token for
4538 + * asymmetric operations.
4539 + *
4540 + * This is the idea: dlopen() pkcs11_kernel directly and find out what
4541 + * mechanisms are there. We don't care about duplications (more slots can
4542 + * support the same mechanism), we just want to know what mechanisms can be
4543 + * possibly supported in hardware on that particular machine. As said before,
4544 + * pkcs11_kernel will show you hardware providers only.
4545 + *
4546 + * Then, we rely on the fact that since we use libpkcs11 library we will find
4547 + * the metaslot. When we go through the metaslot's mechanisms for symmetric
4548 + * ciphers and digests, we check that any found mechanism is in the table
4549 + * created using the pkcs11_kernel library. So, as a result we have two arrays
4550 + * of mechanisms that were advertised as supported in hardware which was the
4551 + * goal of that whole excercise. Thus, we can use libpkcs11 but avoid soft token
4552 + * code for symmetric ciphers and digests. See pk11_choose_slots() for more
4553 + * information.
4554 + *
4555 + * This is Solaris specific code, if SOLARIS_HW_SLOT_SELECTION is not defined
4556 + * the code won't be used.
4557 + */
4558 +#if defined(__sparcv9) || defined(__x86_64) || defined(__amd64)
4559 +static const char pkcs11_kernel[] = "/usr/lib/security/64/pkcs11_kernel.so.1";
4560 +#else
4561 +static const char pkcs11_kernel[] = "/usr/lib/security/pkcs11_kernel.so.1";
4562 +#endif
4565 + * Check hardware capabilities of the machines. The output are two lists,
4566 + * hw_cnids and hw_dnids, that contain hardware mechanisms found in all hardware
4567 + * providers together. They are not sorted and may contain duplicate mechanisms.
4568 + */
4569 +static int check_hw_mechanisms(void)
4570 +       {
4571 +       int i;
4572 +       CK_RV rv;
4573 +       void *handle;
4574 +       CK_C_GetFunctionList p;
4575 +       CK_TOKEN_INFO token_info;
4576 +       CK_ULONG ulSlotCount = 0;
4577 +       int n_cipher = 0, n_digest = 0;
4578 +       CK_FUNCTION_LIST_PTR pflist = NULL;
4579 +       CK_SLOT_ID_PTR pSlotList = NULL_PTR;
4580 +       int *tmp_hw_cnids = NULL, *tmp_hw_dnids = NULL;
4581 +       int hw_ctable_size, hw_dtable_size;
4583 +#ifdef DEBUG_SLOT_SELECTION
4584 +       fprintf(stderr, "%s: SOLARIS_HW_SLOT_SELECTION code running\n",
4585 +           PK11_DBG);
4586 +#endif
4587 +       if ((handle = dlopen(pkcs11_kernel, RTLD_LAZY)) == NULL)
4588 +               {
4589 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
4590 +               goto err;
4591 +               }
4593 +       if ((p = (CK_C_GetFunctionList)dlsym(handle,
4594 +           PK11_GET_FUNCTION_LIST)) == NULL)
4595 +               {
4596 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
4597 +               goto err;
4598 +               }
4600 +       /* get the full function list from the loaded library */
4601 +       if (p(&pflist) != CKR_OK)
4602 +               {
4603 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
4604 +               goto err;
4605 +               }
4607 +       rv = pflist->C_Initialize((CK_VOID_PTR)&pk11_init_args);
4608 +       if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
4609 +               {
4610 +               PK11err_add_data(PK11_F_CHECK_HW_MECHANISMS,
4611 +                   PK11_R_INITIALIZE, rv);
4612 +               goto err;
4613 +               }
4615 +       if (pflist->C_GetSlotList(0, NULL_PTR, &ulSlotCount) != CKR_OK)
4616 +               {
4617 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_GETSLOTLIST);
4618 +               goto err;
4619 +               }
4621 +       /* no slots, set the hw mechanism tables as empty */
4622 +       if (ulSlotCount == 0)
4623 +               {
4624 +#ifdef DEBUG_SLOT_SELECTION
4625 +       fprintf(stderr, "%s: no hardware mechanisms found\n", PK11_DBG);
4626 +#endif
4627 +               hw_cnids = OPENSSL_malloc(sizeof (int));
4628 +               hw_dnids = OPENSSL_malloc(sizeof (int));
4629 +               if (hw_cnids == NULL || hw_dnids == NULL)
4630 +                       {
4631 +                       PK11err(PK11_F_CHECK_HW_MECHANISMS,
4632 +                           PK11_R_MALLOC_FAILURE);
4633 +                       return (0);
4634 +                       }
4635 +               /* this means empty tables */
4636 +               hw_cnids[0] = NID_undef;
4637 +               hw_dnids[0] = NID_undef;
4638 +               return (1);
4639 +               }
4641 +       pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
4642 +       if (pSlotList == NULL)
4643 +               {
4644 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_MALLOC_FAILURE);
4645 +               goto err;
4646 +               }
4648 +       /* Get the slot list for processing */
4649 +       if (pflist->C_GetSlotList(0, pSlotList, &ulSlotCount) != CKR_OK)
4650 +               {
4651 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_GETSLOTLIST);
4652 +               goto err;
4653 +               }
4655 +       /*
4656 +        * We don't care about duplicit mechanisms in multiple slots and also
4657 +        * reserve one slot for the terminal NID_undef which we use to stop the
4658 +        * search.
4659 +        */
4660 +       hw_ctable_size = ulSlotCount * PK11_CIPHER_MAX + 1;
4661 +       hw_dtable_size = ulSlotCount * PK11_DIGEST_MAX + 1;
4662 +       tmp_hw_cnids = OPENSSL_malloc(hw_ctable_size * sizeof (int));
4663 +       tmp_hw_dnids = OPENSSL_malloc(hw_dtable_size * sizeof (int));
4664 +       if (tmp_hw_cnids == NULL || tmp_hw_dnids == NULL)
4665 +               {
4666 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_MALLOC_FAILURE);
4667 +               goto err;
4668 +               }
4670 +       /*
4671 +        * Do not use memset since we should not rely on the fact that NID_undef
4672 +        * is zero now.
4673 +        */
4674 +       for (i = 0; i < hw_ctable_size; ++i)
4675 +               tmp_hw_cnids[i] = NID_undef;
4676 +       for (i = 0; i < hw_dtable_size; ++i)
4677 +               tmp_hw_dnids[i] = NID_undef;
4679 +#ifdef DEBUG_SLOT_SELECTION
4680 +       fprintf(stderr, "%s: provider: %s\n", PK11_DBG, pkcs11_kernel);
4681 +       fprintf(stderr, "%s: found %d hardware slots\n", PK11_DBG, ulSlotCount);
4682 +       fprintf(stderr, "%s: now looking for mechs supported in hw\n",
4683 +           PK11_DBG);
4684 +#endif /* DEBUG_SLOT_SELECTION */
4686 +       for (i = 0; i < ulSlotCount; i++)
4687 +               {
4688 +               if (pflist->C_GetTokenInfo(pSlotList[i], &token_info) != CKR_OK)
4689 +                       continue;
4691 +#ifdef DEBUG_SLOT_SELECTION
4692 +       fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
4693 +#endif /* DEBUG_SLOT_SELECTION */
4695 +               /*
4696 +                * We are filling the hw mech tables here. Global tables are
4697 +                * still NULL so all mechanisms are put into tmp tables.
4698 +                */
4699 +               pk11_find_symmetric_ciphers(pflist, pSlotList[i],
4700 +                   &n_cipher, tmp_hw_cnids);
4701 +               pk11_find_digests(pflist, pSlotList[i],
4702 +                   &n_digest, tmp_hw_dnids);
4703 +               }
4705 +       /*
4706 +        * Since we are part of a library (libcrypto.so), calling this function
4707 +        * may have side-effects. Also, C_Finalize() is triggered by
4708 +        * dlclose(3C).
4709 +        */
4710 +#if 0
4711 +       pflist->C_Finalize(NULL);
4712 +#endif
4713 +       OPENSSL_free(pSlotList);
4714 +       (void) dlclose(handle);
4715 +       hw_cnids = tmp_hw_cnids;
4716 +       hw_dnids = tmp_hw_dnids;
4718 +#ifdef DEBUG_SLOT_SELECTION
4719 +       fprintf(stderr, "%s: hw mechs check complete\n", PK11_DBG);
4720 +#endif /* DEBUG_SLOT_SELECTION */
4721 +       return (1);
4723 +err:
4724 +       if (pSlotList != NULL)
4725 +               OPENSSL_free(pSlotList);
4726 +       if (tmp_hw_cnids != NULL)
4727 +               OPENSSL_free(tmp_hw_cnids);
4728 +       if (tmp_hw_dnids != NULL)
4729 +               OPENSSL_free(tmp_hw_dnids);
4731 +       return (0);
4732 +       }
4735 + * Check presence of a NID in the table of NIDs. The table may be NULL (i.e.,
4736 + * non-existent).
4737 + */
4738 +static int nid_in_table(int nid, int *nid_table)
4739 +       {
4740 +       int i = 0;
4742 +       /*
4743 +        * a special case. NULL means that we are initializing a new
4744 +        * table.
4745 +        */
4746 +       if (nid_table == NULL)
4747 +               return (1);
4749 +       /*
4750 +        * the table is never full, there is always at least one
4751 +        * NID_undef.
4752 +        */
4753 +       while (nid_table[i] != NID_undef)
4754 +               {
4755 +               if (nid_table[i++] == nid)
4756 +                       {
4757 +#ifdef DEBUG_SLOT_SELECTION
4758 +       fprintf(stderr, " (NID %d in hw table, idx %d)", nid, i);
4759 +#endif /* DEBUG_SLOT_SELECTION */
4760 +                       return (1);
4761 +                       }
4762 +               }
4764 +       return (0);
4765 +       }
4766 +#endif /* SOLARIS_HW_SLOT_SELECTION */
4768 +#endif /* OPENSSL_NO_HW_PK11CA */
4769 +#endif /* OPENSSL_NO_HW_PK11 */
4770 +#endif /* OPENSSL_NO_HW */
4771 Index: openssl/crypto/engine/hw_pk11_err.c
4772 diff -u /dev/null openssl/crypto/engine/hw_pk11_err.c:1.5
4773 --- /dev/null   Fri Jan  2 14:59:08 2015
4774 +++ openssl/crypto/engine/hw_pk11_err.c Tue Jun 14 00:43:26 2011
4775 @@ -0,0 +1,288 @@
4777 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
4778 + * Use is subject to license terms.
4779 + */
4781 +/* crypto/engine/hw_pk11_err.c */
4783 + * This product includes software developed by the OpenSSL Project for
4784 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
4785 + *
4786 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
4787 + * Afchine Madjlessi.
4788 + */
4790 + * ====================================================================
4791 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
4792 + *
4793 + * Redistribution and use in source and binary forms, with or without
4794 + * modification, are permitted provided that the following conditions
4795 + * are met:
4796 + *
4797 + * 1. Redistributions of source code must retain the above copyright
4798 + *    notice, this list of conditions and the following disclaimer.
4799 + *
4800 + * 2. Redistributions in binary form must reproduce the above copyright
4801 + *    notice, this list of conditions and the following disclaimer in
4802 + *    the documentation and/or other materials provided with the
4803 + *    distribution.
4804 + *
4805 + * 3. All advertising materials mentioning features or use of this
4806 + *    software must display the following acknowledgment:
4807 + *    "This product includes software developed by the OpenSSL Project
4808 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
4809 + *
4810 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
4811 + *    endorse or promote products derived from this software without
4812 + *    prior written permission. For written permission, please contact
4813 + *    licensing@OpenSSL.org.
4814 + *
4815 + * 5. Products derived from this software may not be called "OpenSSL"
4816 + *    nor may "OpenSSL" appear in their names without prior written
4817 + *    permission of the OpenSSL Project.
4818 + *
4819 + * 6. Redistributions of any form whatsoever must retain the following
4820 + *    acknowledgment:
4821 + *    "This product includes software developed by the OpenSSL Project
4822 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
4823 + *
4824 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
4825 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4826 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
4827 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
4828 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4829 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
4830 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
4831 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4832 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4833 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
4834 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
4835 + * OF THE POSSIBILITY OF SUCH DAMAGE.
4836 + * ====================================================================
4837 + *
4838 + * This product includes cryptographic software written by Eric Young
4839 + * (eay@cryptsoft.com).  This product includes software written by Tim
4840 + * Hudson (tjh@cryptsoft.com).
4841 + *
4842 + */
4844 +#include <stdio.h>
4845 +#include <openssl/err.h>
4846 +#include "hw_pk11_err.h"
4848 +/* BEGIN ERROR CODES */
4849 +#ifndef OPENSSL_NO_ERR
4850 +static ERR_STRING_DATA pk11_str_functs[]=
4852 +{ ERR_PACK(0, PK11_F_INIT, 0),                 "PK11_INIT"},
4853 +{ ERR_PACK(0, PK11_F_FINISH, 0),               "PK11_FINISH"},
4854 +{ ERR_PACK(0, PK11_F_DESTROY, 0),              "PK11_DESTROY"},
4855 +{ ERR_PACK(0, PK11_F_CTRL, 0),                 "PK11_CTRL"},
4856 +{ ERR_PACK(0, PK11_F_RSA_INIT, 0),             "PK11_RSA_INIT"},
4857 +{ ERR_PACK(0, PK11_F_RSA_FINISH, 0),           "PK11_RSA_FINISH"},
4858 +{ ERR_PACK(0, PK11_F_GET_PUB_RSA_KEY, 0),      "PK11_GET_PUB_RSA_KEY"},
4859 +{ ERR_PACK(0, PK11_F_GET_PRIV_RSA_KEY, 0),     "PK11_GET_PRIV_RSA_KEY"},
4860 +{ ERR_PACK(0, PK11_F_RSA_GEN_KEY, 0),          "PK11_RSA_GEN_KEY"},
4861 +{ ERR_PACK(0, PK11_F_RSA_PUB_ENC, 0),          "PK11_RSA_PUB_ENC"},
4862 +{ ERR_PACK(0, PK11_F_RSA_PRIV_ENC, 0),         "PK11_RSA_PRIV_ENC"},
4863 +{ ERR_PACK(0, PK11_F_RSA_PUB_DEC, 0),          "PK11_RSA_PUB_DEC"},
4864 +{ ERR_PACK(0, PK11_F_RSA_PRIV_DEC, 0),         "PK11_RSA_PRIV_DEC"},
4865 +{ ERR_PACK(0, PK11_F_RSA_SIGN, 0),             "PK11_RSA_SIGN"},
4866 +{ ERR_PACK(0, PK11_F_RSA_VERIFY, 0),           "PK11_RSA_VERIFY"},
4867 +{ ERR_PACK(0, PK11_F_RAND_ADD, 0),             "PK11_RAND_ADD"},
4868 +{ ERR_PACK(0, PK11_F_RAND_BYTES, 0),           "PK11_RAND_BYTES"},
4869 +{ ERR_PACK(0, PK11_F_GET_SESSION, 0),          "PK11_GET_SESSION"},
4870 +{ ERR_PACK(0, PK11_F_FREE_SESSION, 0),         "PK11_FREE_SESSION"},
4871 +{ ERR_PACK(0, PK11_F_LOAD_PUBKEY, 0),          "PK11_LOAD_PUBKEY"},
4872 +{ ERR_PACK(0, PK11_F_LOAD_PRIVKEY, 0),         "PK11_LOAD_PRIV_KEY"},
4873 +{ ERR_PACK(0, PK11_F_RSA_PUB_ENC_LOW, 0),      "PK11_RSA_PUB_ENC_LOW"},
4874 +{ ERR_PACK(0, PK11_F_RSA_PRIV_ENC_LOW, 0),     "PK11_RSA_PRIV_ENC_LOW"},
4875 +{ ERR_PACK(0, PK11_F_RSA_PUB_DEC_LOW, 0),      "PK11_RSA_PUB_DEC_LOW"},
4876 +{ ERR_PACK(0, PK11_F_RSA_PRIV_DEC_LOW, 0),     "PK11_RSA_PRIV_DEC_LOW"},
4877 +{ ERR_PACK(0, PK11_F_DSA_SIGN, 0),             "PK11_DSA_SIGN"},
4878 +{ ERR_PACK(0, PK11_F_DSA_VERIFY, 0),           "PK11_DSA_VERIFY"},
4879 +{ ERR_PACK(0, PK11_F_DSA_INIT, 0),             "PK11_DSA_INIT"},
4880 +{ ERR_PACK(0, PK11_F_DSA_FINISH, 0),           "PK11_DSA_FINISH"},
4881 +{ ERR_PACK(0, PK11_F_GET_PUB_DSA_KEY, 0),      "PK11_GET_PUB_DSA_KEY"},
4882 +{ ERR_PACK(0, PK11_F_GET_PRIV_DSA_KEY, 0),     "PK11_GET_PRIV_DSA_KEY"},
4883 +{ ERR_PACK(0, PK11_F_DH_INIT, 0),              "PK11_DH_INIT"},
4884 +{ ERR_PACK(0, PK11_F_DH_FINISH, 0),            "PK11_DH_FINISH"},
4885 +{ ERR_PACK(0, PK11_F_MOD_EXP_DH, 0),           "PK11_MOD_EXP_DH"},
4886 +{ ERR_PACK(0, PK11_F_GET_DH_KEY, 0),           "PK11_GET_DH_KEY"},
4887 +{ ERR_PACK(0, PK11_F_FREE_ALL_SESSIONS, 0),    "PK11_FREE_ALL_SESSIONS"},
4888 +{ ERR_PACK(0, PK11_F_SETUP_SESSION, 0),                "PK11_SETUP_SESSION"},
4889 +{ ERR_PACK(0, PK11_F_DESTROY_OBJECT, 0),       "PK11_DESTROY_OBJECT"},
4890 +{ ERR_PACK(0, PK11_F_CIPHER_INIT, 0),          "PK11_CIPHER_INIT"},
4891 +{ ERR_PACK(0, PK11_F_CIPHER_DO_CIPHER, 0),     "PK11_CIPHER_DO_CIPHER"},
4892 +{ ERR_PACK(0, PK11_F_GET_CIPHER_KEY, 0),       "PK11_GET_CIPHER_KEY"},
4893 +{ ERR_PACK(0, PK11_F_DIGEST_INIT, 0),          "PK11_DIGEST_INIT"},
4894 +{ ERR_PACK(0, PK11_F_DIGEST_UPDATE, 0),                "PK11_DIGEST_UPDATE"},
4895 +{ ERR_PACK(0, PK11_F_DIGEST_FINAL, 0),         "PK11_DIGEST_FINAL"},
4896 +{ ERR_PACK(0, PK11_F_CHOOSE_SLOT, 0),          "PK11_CHOOSE_SLOT"},
4897 +{ ERR_PACK(0, PK11_F_CIPHER_FINAL, 0),         "PK11_CIPHER_FINAL"},
4898 +{ ERR_PACK(0, PK11_F_LIBRARY_INIT, 0),         "PK11_LIBRARY_INIT"},
4899 +{ ERR_PACK(0, PK11_F_LOAD, 0),                 "ENGINE_LOAD_PK11"},
4900 +{ ERR_PACK(0, PK11_F_DH_GEN_KEY, 0),           "PK11_DH_GEN_KEY"},
4901 +{ ERR_PACK(0, PK11_F_DH_COMP_KEY, 0),          "PK11_DH_COMP_KEY"},
4902 +{ ERR_PACK(0, PK11_F_DIGEST_COPY, 0),          "PK11_DIGEST_COPY"},
4903 +{ ERR_PACK(0, PK11_F_CIPHER_CLEANUP, 0),       "PK11_CIPHER_CLEANUP"},
4904 +{ ERR_PACK(0, PK11_F_ACTIVE_ADD, 0),           "PK11_ACTIVE_ADD"},
4905 +{ ERR_PACK(0, PK11_F_ACTIVE_DELETE, 0),                "PK11_ACTIVE_DELETE"},
4906 +{ ERR_PACK(0, PK11_F_CHECK_HW_MECHANISMS, 0),  "PK11_CHECK_HW_MECHANISMS"},
4907 +{ ERR_PACK(0, PK11_F_INIT_SYMMETRIC, 0),       "PK11_INIT_SYMMETRIC"},
4908 +{ ERR_PACK(0, PK11_F_ADD_AES_CTR_NIDS, 0),     "PK11_ADD_AES_CTR_NIDS"},
4909 +{ ERR_PACK(0, PK11_F_INIT_ALL_LOCKS, 0),       "PK11_INIT_ALL_LOCKS"},
4910 +{ ERR_PACK(0, PK11_F_RETURN_SESSION, 0),       "PK11_RETURN_SESSION"},
4911 +{ ERR_PACK(0, PK11_F_GET_PIN, 0),              "PK11_GET_PIN"},
4912 +{ ERR_PACK(0, PK11_F_FIND_ONE_OBJECT, 0),      "PK11_FIND_ONE_OBJECT"},
4913 +{ ERR_PACK(0, PK11_F_CHECK_TOKEN_ATTRS, 0),    "PK11_CHECK_TOKEN_ATTRS"},
4914 +{ ERR_PACK(0, PK11_F_CACHE_PIN, 0),            "PK11_CACHE_PIN"},
4915 +{ ERR_PACK(0, PK11_F_MLOCK_PIN_IN_MEMORY, 0),  "PK11_MLOCK_PIN_IN_MEMORY"},
4916 +{ ERR_PACK(0, PK11_F_TOKEN_LOGIN, 0),          "PK11_TOKEN_LOGIN"},
4917 +{ ERR_PACK(0, PK11_F_TOKEN_RELOGIN, 0),                "PK11_TOKEN_RELOGIN"},
4918 +{ ERR_PACK(0, PK11_F_RUN_ASKPASS, 0),          "PK11_F_RUN_ASKPASS"},
4919 +{ 0, NULL}
4922 +static ERR_STRING_DATA pk11_str_reasons[]=
4924 +{ PK11_R_ALREADY_LOADED,               "PKCS#11 DSO already loaded"},
4925 +{ PK11_R_DSO_FAILURE,                  "unable to load PKCS#11 DSO"},
4926 +{ PK11_R_NOT_LOADED,                   "PKCS#11 DSO not loaded"},
4927 +{ PK11_R_PASSED_NULL_PARAMETER,                "null parameter passed"},
4928 +{ PK11_R_COMMAND_NOT_IMPLEMENTED,      "command not implemented"},
4929 +{ PK11_R_INITIALIZE,                   "C_Initialize failed"},
4930 +{ PK11_R_FINALIZE,                     "C_Finalize failed"},
4931 +{ PK11_R_GETINFO,                      "C_GetInfo faile"},
4932 +{ PK11_R_GETSLOTLIST,                  "C_GetSlotList failed"},
4933 +{ PK11_R_NO_MODULUS_OR_NO_EXPONENT,    "no modulus or no exponent"},
4934 +{ PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID,        "attr sensitive or invalid"},
4935 +{ PK11_R_GETATTRIBUTVALUE,             "C_GetAttributeValue failed"},
4936 +{ PK11_R_NO_MODULUS,                   "no modulus"},
4937 +{ PK11_R_NO_EXPONENT,                  "no exponent"},
4938 +{ PK11_R_FINDOBJECTSINIT,              "C_FindObjectsInit failed"},
4939 +{ PK11_R_FINDOBJECTS,                  "C_FindObjects failed"},
4940 +{ PK11_R_FINDOBJECTSFINAL,             "C_FindObjectsFinal failed"},
4941 +{ PK11_R_CREATEOBJECT,                 "C_CreateObject failed"},
4942 +{ PK11_R_DESTROYOBJECT,                        "C_DestroyObject failed"},
4943 +{ PK11_R_OPENSESSION,                  "C_OpenSession failed"},
4944 +{ PK11_R_CLOSESESSION,                 "C_CloseSession failed"},
4945 +{ PK11_R_ENCRYPTINIT,                  "C_EncryptInit failed"},
4946 +{ PK11_R_ENCRYPT,                      "C_Encrypt failed"},
4947 +{ PK11_R_SIGNINIT,                     "C_SignInit failed"},
4948 +{ PK11_R_SIGN,                         "C_Sign failed"},
4949 +{ PK11_R_DECRYPTINIT,                  "C_DecryptInit failed"},
4950 +{ PK11_R_DECRYPT,                      "C_Decrypt failed"},
4951 +{ PK11_R_VERIFYINIT,                   "C_VerifyRecover failed"},
4952 +{ PK11_R_VERIFY,                       "C_Verify failed"},
4953 +{ PK11_R_VERIFYRECOVERINIT,            "C_VerifyRecoverInit failed"},
4954 +{ PK11_R_VERIFYRECOVER,                        "C_VerifyRecover failed"},
4955 +{ PK11_R_GEN_KEY,                      "C_GenerateKeyPair failed"},
4956 +{ PK11_R_SEEDRANDOM,                   "C_SeedRandom failed"},
4957 +{ PK11_R_GENERATERANDOM,               "C_GenerateRandom failed"},
4958 +{ PK11_R_INVALID_MESSAGE_LENGTH,       "invalid message length"},
4959 +{ PK11_R_UNKNOWN_ALGORITHM_TYPE,       "unknown algorithm type"},
4960 +{ PK11_R_UNKNOWN_ASN1_OBJECT_ID,       "unknown asn1 onject id"},
4961 +{ PK11_R_UNKNOWN_PADDING_TYPE,         "unknown padding type"},
4962 +{ PK11_R_PADDING_CHECK_FAILED,         "padding check failed"},
4963 +{ PK11_R_DIGEST_TOO_BIG,               "digest too big"},
4964 +{ PK11_R_MALLOC_FAILURE,               "malloc failure"},
4965 +{ PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED, "ctl command not implemented"},
4966 +{ PK11_R_DATA_GREATER_THAN_MOD_LEN,    "data is bigger than mod"},
4967 +{ PK11_R_DATA_TOO_LARGE_FOR_MODULUS,   "data is too larger for mod"},
4968 +{ PK11_R_MISSING_KEY_COMPONENT,                "a dsa component is missing"},
4969 +{ PK11_R_INVALID_SIGNATURE_LENGTH,     "invalid signature length"},
4970 +{ PK11_R_INVALID_DSA_SIGNATURE_R,      "missing r in dsa verify"},
4971 +{ PK11_R_INVALID_DSA_SIGNATURE_S,      "missing s in dsa verify"},
4972 +{ PK11_R_INCONSISTENT_KEY,             "inconsistent key type"},
4973 +{ PK11_R_ENCRYPTUPDATE,                        "C_EncryptUpdate failed"},
4974 +{ PK11_R_DECRYPTUPDATE,                        "C_DecryptUpdate failed"},
4975 +{ PK11_R_DIGESTINIT,                   "C_DigestInit failed"},
4976 +{ PK11_R_DIGESTUPDATE,                 "C_DigestUpdate failed"},
4977 +{ PK11_R_DIGESTFINAL,                  "C_DigestFinal failed"},
4978 +{ PK11_R_ENCRYPTFINAL,                 "C_EncryptFinal failed"},
4979 +{ PK11_R_DECRYPTFINAL,                 "C_DecryptFinal failed"},
4980 +{ PK11_R_NO_PRNG_SUPPORT,              "Slot does not support PRNG"},
4981 +{ PK11_R_GETTOKENINFO,                 "C_GetTokenInfo failed"},
4982 +{ PK11_R_DERIVEKEY,                    "C_DeriveKey failed"},
4983 +{ PK11_R_GET_OPERATION_STATE,          "C_GetOperationState failed"},
4984 +{ PK11_R_SET_OPERATION_STATE,          "C_SetOperationState failed"},
4985 +{ PK11_R_INVALID_HANDLE,               "invalid PKCS#11 object handle"},
4986 +{ PK11_R_KEY_OR_IV_LEN_PROBLEM,                "IV or key length incorrect"},
4987 +{ PK11_R_INVALID_OPERATION_TYPE,       "invalid operation type"},
4988 +{ PK11_R_ADD_NID_FAILED,               "failed to add NID" },
4989 +{ PK11_R_ATFORK_FAILED,                        "atfork() failed" },
4990 +{ PK11_R_TOKEN_LOGIN_FAILED,           "C_Login() failed on token" },
4991 +{ PK11_R_MORE_THAN_ONE_OBJECT_FOUND,   "more than one object found" },
4992 +{ PK11_R_INVALID_PKCS11_URI,           "pkcs11 URI provided is invalid" },
4993 +{ PK11_R_COULD_NOT_READ_PIN,           "could not read PIN from terminal" },
4994 +{ PK11_R_PIN_NOT_READ_FROM_COMMAND,    "PIN not read from external command" },
4995 +{ PK11_R_COULD_NOT_OPEN_COMMAND,       "could not popen() dialog command" },
4996 +{ PK11_R_PIPE_FAILED,                  "pipe() failed" },
4997 +{ PK11_R_BAD_PASSPHRASE_SPEC,          "bad passphrasedialog specification" },
4998 +{ PK11_R_TOKEN_NOT_INITIALIZED,                "token not initialized" },
4999 +{ PK11_R_TOKEN_PIN_NOT_SET,            "token PIN required but not set" },
5000 +{ PK11_R_TOKEN_PIN_NOT_PROVIDED,       "token PIN required but not provided" },
5001 +{ PK11_R_MISSING_OBJECT_LABEL,         "missing mandatory 'object' keyword" },
5002 +{ PK11_R_TOKEN_ATTRS_DO_NOT_MATCH,     "token attrs provided do not match" },
5003 +{ PK11_R_PRIV_KEY_NOT_FOUND,           "private key not found in keystore" },
5004 +{ PK11_R_NO_OBJECT_FOUND,              "specified object not found" },
5005 +{ PK11_R_PIN_CACHING_POLICY_INVALID,   "PIN set but caching policy invalid" },
5006 +{ PK11_R_SYSCONF_FAILED,               "sysconf() failed" },
5007 +{ PK11_R_MMAP_FAILED,                  "mmap() failed" },
5008 +{ PK11_R_PRIV_PROC_LOCK_MEMORY_MISSING,        "PROC_LOCK_MEMORY privilege missing" },
5009 +{ PK11_R_MLOCK_FAILED,                 "mlock() failed" },
5010 +{ PK11_R_FORK_FAILED,                  "fork() failed" },
5011 +{ 0,   NULL}
5013 +#endif /* OPENSSL_NO_ERR */
5015 +static int pk11_lib_error_code = 0;
5016 +static int pk11_error_init = 1;
5018 +static void
5019 +ERR_load_pk11_strings(void)
5020 +       {
5021 +       if (pk11_lib_error_code == 0)
5022 +               pk11_lib_error_code = ERR_get_next_error_library();
5024 +       if (pk11_error_init)
5025 +               {
5026 +               pk11_error_init = 0;
5027 +#ifndef OPENSSL_NO_ERR
5028 +               ERR_load_strings(pk11_lib_error_code, pk11_str_functs);
5029 +               ERR_load_strings(pk11_lib_error_code, pk11_str_reasons);
5030 +#endif
5031 +               }
5034 +static void
5035 +ERR_unload_pk11_strings(void)
5036 +       {
5037 +       if (pk11_error_init == 0)
5038 +               {
5039 +#ifndef OPENSSL_NO_ERR
5040 +               ERR_unload_strings(pk11_lib_error_code, pk11_str_functs);
5041 +               ERR_unload_strings(pk11_lib_error_code, pk11_str_reasons);
5042 +#endif
5043 +               pk11_error_init = 1;
5044 +               }
5047 +void
5048 +ERR_pk11_error(int function, int reason, char *file, int line)
5050 +       if (pk11_lib_error_code == 0)
5051 +               pk11_lib_error_code = ERR_get_next_error_library();
5052 +       ERR_PUT_error(pk11_lib_error_code, function, reason, file, line);
5055 +void
5056 +PK11err_add_data(int function, int reason, CK_RV rv)
5058 +       char tmp_buf[20];
5060 +       PK11err(function, reason);
5061 +       (void) BIO_snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
5062 +       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
5064 Index: openssl/crypto/engine/hw_pk11_err.h
5065 diff -u /dev/null openssl/crypto/engine/hw_pk11_err.h:1.13
5066 --- /dev/null   Fri Jan  2 14:59:08 2015
5067 +++ openssl/crypto/engine/hw_pk11_err.h Fri Oct  4 14:04:20 2013
5068 @@ -0,0 +1,440 @@
5070 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
5071 + * Use is subject to license terms.
5072 + */
5075 + * This product includes software developed by the OpenSSL Project for
5076 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
5077 + *
5078 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
5079 + * Afchine Madjlessi.
5080 + */
5082 + * ====================================================================
5083 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
5084 + *
5085 + * Redistribution and use in source and binary forms, with or without
5086 + * modification, are permitted provided that the following conditions
5087 + * are met:
5088 + *
5089 + * 1. Redistributions of source code must retain the above copyright
5090 + *    notice, this list of conditions and the following disclaimer.
5091 + *
5092 + * 2. Redistributions in binary form must reproduce the above copyright
5093 + *    notice, this list of conditions and the following disclaimer in
5094 + *    the documentation and/or other materials provided with the
5095 + *    distribution.
5096 + *
5097 + * 3. All advertising materials mentioning features or use of this
5098 + *    software must display the following acknowledgment:
5099 + *    "This product includes software developed by the OpenSSL Project
5100 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
5101 + *
5102 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
5103 + *    endorse or promote products derived from this software without
5104 + *    prior written permission. For written permission, please contact
5105 + *    licensing@OpenSSL.org.
5106 + *
5107 + * 5. Products derived from this software may not be called "OpenSSL"
5108 + *    nor may "OpenSSL" appear in their names without prior written
5109 + *    permission of the OpenSSL Project.
5110 + *
5111 + * 6. Redistributions of any form whatsoever must retain the following
5112 + *    acknowledgment:
5113 + *    "This product includes software developed by the OpenSSL Project
5114 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
5115 + *
5116 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
5117 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5118 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
5119 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
5120 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
5121 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
5122 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5123 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5124 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
5125 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
5126 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
5127 + * OF THE POSSIBILITY OF SUCH DAMAGE.
5128 + * ====================================================================
5129 + *
5130 + * This product includes cryptographic software written by Eric Young
5131 + * (eay@cryptsoft.com).  This product includes software written by Tim
5132 + * Hudson (tjh@cryptsoft.com).
5133 + *
5134 + */
5136 +#ifndef        HW_PK11_ERR_H
5137 +#define        HW_PK11_ERR_H
5139 +void ERR_pk11_error(int function, int reason, char *file, int line);
5140 +void PK11err_add_data(int function, int reason, CK_RV rv);
5141 +#define        PK11err(f, r)   ERR_pk11_error((f), (r), __FILE__, __LINE__)
5143 +/* Error codes for the PK11 functions. */
5145 +/* Function codes. */
5147 +#define        PK11_F_INIT                             100
5148 +#define        PK11_F_FINISH                           101
5149 +#define        PK11_F_DESTROY                          102
5150 +#define        PK11_F_CTRL                             103
5151 +#define        PK11_F_RSA_INIT                         104
5152 +#define        PK11_F_RSA_FINISH                       105
5153 +#define        PK11_F_GET_PUB_RSA_KEY                  106
5154 +#define        PK11_F_GET_PRIV_RSA_KEY                 107
5155 +#define        PK11_F_RSA_GEN_KEY                      108
5156 +#define        PK11_F_RSA_PUB_ENC                      109
5157 +#define        PK11_F_RSA_PRIV_ENC                     110
5158 +#define        PK11_F_RSA_PUB_DEC                      111
5159 +#define        PK11_F_RSA_PRIV_DEC                     112
5160 +#define        PK11_F_RSA_SIGN                         113
5161 +#define        PK11_F_RSA_VERIFY                       114
5162 +#define        PK11_F_RAND_ADD                         115
5163 +#define        PK11_F_RAND_BYTES                       116
5164 +#define        PK11_F_GET_SESSION                      117
5165 +#define        PK11_F_FREE_SESSION                     118
5166 +#define        PK11_F_LOAD_PUBKEY                      119
5167 +#define        PK11_F_LOAD_PRIVKEY                     120
5168 +#define        PK11_F_RSA_PUB_ENC_LOW                  121
5169 +#define        PK11_F_RSA_PRIV_ENC_LOW                 122
5170 +#define        PK11_F_RSA_PUB_DEC_LOW                  123
5171 +#define        PK11_F_RSA_PRIV_DEC_LOW                 124
5172 +#define        PK11_F_DSA_SIGN                         125
5173 +#define        PK11_F_DSA_VERIFY                       126
5174 +#define        PK11_F_DSA_INIT                         127
5175 +#define        PK11_F_DSA_FINISH                       128
5176 +#define        PK11_F_GET_PUB_DSA_KEY                  129
5177 +#define        PK11_F_GET_PRIV_DSA_KEY                 130
5178 +#define        PK11_F_DH_INIT                          131
5179 +#define        PK11_F_DH_FINISH                        132
5180 +#define        PK11_F_MOD_EXP_DH                       133
5181 +#define        PK11_F_GET_DH_KEY                       134
5182 +#define        PK11_F_FREE_ALL_SESSIONS                135
5183 +#define        PK11_F_SETUP_SESSION                    136
5184 +#define        PK11_F_DESTROY_OBJECT                   137
5185 +#define        PK11_F_CIPHER_INIT                      138
5186 +#define        PK11_F_CIPHER_DO_CIPHER                 139
5187 +#define        PK11_F_GET_CIPHER_KEY                   140
5188 +#define        PK11_F_DIGEST_INIT                      141
5189 +#define        PK11_F_DIGEST_UPDATE                    142
5190 +#define        PK11_F_DIGEST_FINAL                     143
5191 +#define        PK11_F_CHOOSE_SLOT                      144
5192 +#define        PK11_F_CIPHER_FINAL                     145
5193 +#define        PK11_F_LIBRARY_INIT                     146
5194 +#define        PK11_F_LOAD                             147
5195 +#define        PK11_F_DH_GEN_KEY                       148
5196 +#define        PK11_F_DH_COMP_KEY                      149
5197 +#define        PK11_F_DIGEST_COPY                      150
5198 +#define        PK11_F_CIPHER_CLEANUP                   151
5199 +#define        PK11_F_ACTIVE_ADD                       152
5200 +#define        PK11_F_ACTIVE_DELETE                    153
5201 +#define        PK11_F_CHECK_HW_MECHANISMS              154
5202 +#define        PK11_F_INIT_SYMMETRIC                   155
5203 +#define        PK11_F_ADD_AES_CTR_NIDS                 156
5204 +#define        PK11_F_INIT_ALL_LOCKS                   157
5205 +#define        PK11_F_RETURN_SESSION                   158
5206 +#define        PK11_F_GET_PIN                          159
5207 +#define        PK11_F_FIND_ONE_OBJECT                  160
5208 +#define        PK11_F_CHECK_TOKEN_ATTRS                161
5209 +#define        PK11_F_CACHE_PIN                        162
5210 +#define        PK11_F_MLOCK_PIN_IN_MEMORY              163
5211 +#define        PK11_F_TOKEN_LOGIN                      164
5212 +#define        PK11_F_TOKEN_RELOGIN                    165
5213 +#define        PK11_F_RUN_ASKPASS                      166
5215 +/* Reason codes. */
5216 +#define        PK11_R_ALREADY_LOADED                   100
5217 +#define        PK11_R_DSO_FAILURE                      101
5218 +#define        PK11_R_NOT_LOADED                       102
5219 +#define        PK11_R_PASSED_NULL_PARAMETER            103
5220 +#define        PK11_R_COMMAND_NOT_IMPLEMENTED          104
5221 +#define        PK11_R_INITIALIZE                       105
5222 +#define        PK11_R_FINALIZE                         106
5223 +#define        PK11_R_GETINFO                          107
5224 +#define        PK11_R_GETSLOTLIST                      108
5225 +#define        PK11_R_NO_MODULUS_OR_NO_EXPONENT        109
5226 +#define        PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID    110
5227 +#define        PK11_R_GETATTRIBUTVALUE                 111
5228 +#define        PK11_R_NO_MODULUS                       112
5229 +#define        PK11_R_NO_EXPONENT                      113
5230 +#define        PK11_R_FINDOBJECTSINIT                  114
5231 +#define        PK11_R_FINDOBJECTS                      115
5232 +#define        PK11_R_FINDOBJECTSFINAL                 116
5233 +#define        PK11_R_CREATEOBJECT                     118
5234 +#define        PK11_R_DESTROYOBJECT                    119
5235 +#define        PK11_R_OPENSESSION                      120
5236 +#define        PK11_R_CLOSESESSION                     121
5237 +#define        PK11_R_ENCRYPTINIT                      122
5238 +#define        PK11_R_ENCRYPT                          123
5239 +#define        PK11_R_SIGNINIT                         124
5240 +#define        PK11_R_SIGN                             125
5241 +#define        PK11_R_DECRYPTINIT                      126
5242 +#define        PK11_R_DECRYPT                          127
5243 +#define        PK11_R_VERIFYINIT                       128
5244 +#define        PK11_R_VERIFY                           129
5245 +#define        PK11_R_VERIFYRECOVERINIT                130
5246 +#define        PK11_R_VERIFYRECOVER                    131
5247 +#define        PK11_R_GEN_KEY                          132
5248 +#define        PK11_R_SEEDRANDOM                       133
5249 +#define        PK11_R_GENERATERANDOM                   134
5250 +#define        PK11_R_INVALID_MESSAGE_LENGTH           135
5251 +#define        PK11_R_UNKNOWN_ALGORITHM_TYPE           136
5252 +#define        PK11_R_UNKNOWN_ASN1_OBJECT_ID           137
5253 +#define        PK11_R_UNKNOWN_PADDING_TYPE             138
5254 +#define        PK11_R_PADDING_CHECK_FAILED             139
5255 +#define        PK11_R_DIGEST_TOO_BIG                   140
5256 +#define        PK11_R_MALLOC_FAILURE                   141
5257 +#define        PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED     142
5258 +#define        PK11_R_DATA_GREATER_THAN_MOD_LEN        143
5259 +#define        PK11_R_DATA_TOO_LARGE_FOR_MODULUS       144
5260 +#define        PK11_R_MISSING_KEY_COMPONENT            145
5261 +#define        PK11_R_INVALID_SIGNATURE_LENGTH         146
5262 +#define        PK11_R_INVALID_DSA_SIGNATURE_R          147
5263 +#define        PK11_R_INVALID_DSA_SIGNATURE_S          148
5264 +#define        PK11_R_INCONSISTENT_KEY                 149
5265 +#define        PK11_R_ENCRYPTUPDATE                    150
5266 +#define        PK11_R_DECRYPTUPDATE                    151
5267 +#define        PK11_R_DIGESTINIT                       152
5268 +#define        PK11_R_DIGESTUPDATE                     153
5269 +#define        PK11_R_DIGESTFINAL                      154
5270 +#define        PK11_R_ENCRYPTFINAL                     155
5271 +#define        PK11_R_DECRYPTFINAL                     156
5272 +#define        PK11_R_NO_PRNG_SUPPORT                  157
5273 +#define        PK11_R_GETTOKENINFO                     158
5274 +#define        PK11_R_DERIVEKEY                        159
5275 +#define        PK11_R_GET_OPERATION_STATE              160
5276 +#define        PK11_R_SET_OPERATION_STATE              161
5277 +#define        PK11_R_INVALID_HANDLE                   162
5278 +#define        PK11_R_KEY_OR_IV_LEN_PROBLEM            163
5279 +#define        PK11_R_INVALID_OPERATION_TYPE           164
5280 +#define        PK11_R_ADD_NID_FAILED                   165
5281 +#define        PK11_R_ATFORK_FAILED                    166
5283 +#define        PK11_R_TOKEN_LOGIN_FAILED               167
5284 +#define        PK11_R_MORE_THAN_ONE_OBJECT_FOUND       168
5285 +#define        PK11_R_INVALID_PKCS11_URI               169
5286 +#define        PK11_R_COULD_NOT_READ_PIN               170
5287 +#define        PK11_R_COULD_NOT_OPEN_COMMAND           171
5288 +#define        PK11_R_PIPE_FAILED                      172
5289 +#define        PK11_R_PIN_NOT_READ_FROM_COMMAND        173
5290 +#define        PK11_R_BAD_PASSPHRASE_SPEC              174
5291 +#define        PK11_R_TOKEN_NOT_INITIALIZED            175
5292 +#define        PK11_R_TOKEN_PIN_NOT_SET                176
5293 +#define        PK11_R_TOKEN_PIN_NOT_PROVIDED           177
5294 +#define        PK11_R_MISSING_OBJECT_LABEL             178
5295 +#define        PK11_R_TOKEN_ATTRS_DO_NOT_MATCH         179
5296 +#define        PK11_R_PRIV_KEY_NOT_FOUND               180
5297 +#define        PK11_R_NO_OBJECT_FOUND                  181
5298 +#define        PK11_R_PIN_CACHING_POLICY_INVALID       182
5299 +#define        PK11_R_SYSCONF_FAILED                   183
5300 +#define        PK11_R_MMAP_FAILED                      183
5301 +#define        PK11_R_PRIV_PROC_LOCK_MEMORY_MISSING    184
5302 +#define        PK11_R_MLOCK_FAILED                     185
5303 +#define        PK11_R_FORK_FAILED                      186
5305 +/* max byte length of a symetric key we support */
5306 +#define        PK11_KEY_LEN_MAX                        32
5308 +#ifdef NOPTHREADS
5310 + * CRYPTO_LOCK_PK11_ENGINE lock is primarily used for the protection of the
5311 + * free_session list and active_list but generally serves as a global
5312 + * per-process lock for the whole engine.
5313 + *
5314 + * We reuse CRYPTO_LOCK_EC lock (which is defined in OpenSSL for EC method) as
5315 + * the global engine lock. This is not optimal w.r.t. performance but
5316 + * it's safe.
5317 + */
5318 +#define CRYPTO_LOCK_PK11_ENGINE        CRYPTO_LOCK_EC
5319 +#endif
5322 + * This structure encapsulates all reusable information for a PKCS#11
5323 + * session. A list of these objects is created on behalf of the
5324 + * calling application using an on-demand method. Each operation
5325 + * type (see PK11_OPTYPE below) has its own per-process list.
5326 + * Each of the lists is basically a cache for faster PKCS#11 object
5327 + * access to avoid expensive C_Find{,Init,Final}Object() calls.
5328 + *
5329 + * When a new request comes in, an object will be taken from the list
5330 + * (if there is one) or a new one is created to handle the request
5331 + * (if the list is empty). See pk11_get_session() on how it is done.
5332 + */
5333 +typedef struct PK11_st_SESSION
5334 +       {
5335 +       struct PK11_st_SESSION  *next;
5336 +       CK_SESSION_HANDLE       session;        /* PK11 session handle */
5337 +       pid_t                   pid;            /* Current process ID */
5338 +       CK_BBOOL                pub_persistent; /* is pub key in keystore? */
5339 +       CK_BBOOL                priv_persistent;/* is priv key in keystore? */
5340 +       union
5341 +               {
5342 +#ifndef OPENSSL_NO_RSA
5343 +               struct
5344 +                       {
5345 +                       CK_OBJECT_HANDLE        rsa_pub_key; /* pub handle */
5346 +                       CK_OBJECT_HANDLE        rsa_priv_key; /* priv handle */
5347 +                       RSA                     *rsa_pub; /* pub key addr */
5348 +                       BIGNUM                  *rsa_n_num; /* pub modulus */
5349 +                       BIGNUM                  *rsa_e_num; /* pub exponent */
5350 +                       RSA                     *rsa_priv; /* priv key addr */
5351 +                       BIGNUM                  *rsa_pn_num; /* pub modulus */
5352 +                       BIGNUM                  *rsa_pe_num; /* pub exponent */
5353 +                       BIGNUM                  *rsa_d_num; /* priv exponent */
5354 +                       } u_RSA;
5355 +#endif /* OPENSSL_NO_RSA */
5356 +#ifndef OPENSSL_NO_DSA
5357 +               struct
5358 +                       {
5359 +                       CK_OBJECT_HANDLE        dsa_pub_key; /* pub handle */
5360 +                       CK_OBJECT_HANDLE        dsa_priv_key; /* priv handle */
5361 +                       DSA                     *dsa_pub; /* pub key addr */
5362 +                       BIGNUM                  *dsa_pub_num; /* pub key */
5363 +                       DSA                     *dsa_priv; /* priv key addr */
5364 +                       BIGNUM                  *dsa_priv_num; /* priv key */
5365 +                       } u_DSA;
5366 +#endif /* OPENSSL_NO_DSA */
5367 +#ifndef OPENSSL_NO_DH
5368 +               struct
5369 +                       {
5370 +                       CK_OBJECT_HANDLE        dh_key; /* key handle */
5371 +                       DH                      *dh; /* dh key addr */
5372 +                       BIGNUM                  *dh_priv_num; /* priv dh key */
5373 +                       } u_DH;
5374 +#endif /* OPENSSL_NO_DH */
5375 +               struct
5376 +                       {
5377 +                       CK_OBJECT_HANDLE        cipher_key; /* key handle */
5378 +                       unsigned char           key[PK11_KEY_LEN_MAX];
5379 +                       int                     key_len; /* priv key len */
5380 +                       int                     encrypt; /* 1/0 enc/decr */
5381 +                       } u_cipher;
5382 +               } opdata_u;
5383 +       } PK11_SESSION;
5385 +#define        opdata_rsa_pub_key      opdata_u.u_RSA.rsa_pub_key
5386 +#define        opdata_rsa_priv_key     opdata_u.u_RSA.rsa_priv_key
5387 +#define        opdata_rsa_pub          opdata_u.u_RSA.rsa_pub
5388 +#define        opdata_rsa_priv         opdata_u.u_RSA.rsa_priv
5389 +#define        opdata_rsa_n_num        opdata_u.u_RSA.rsa_n_num
5390 +#define        opdata_rsa_e_num        opdata_u.u_RSA.rsa_e_num
5391 +#define        opdata_rsa_pn_num       opdata_u.u_RSA.rsa_pn_num
5392 +#define        opdata_rsa_pe_num       opdata_u.u_RSA.rsa_pe_num
5393 +#define        opdata_rsa_d_num        opdata_u.u_RSA.rsa_d_num
5394 +#define        opdata_dsa_pub_key      opdata_u.u_DSA.dsa_pub_key
5395 +#define        opdata_dsa_priv_key     opdata_u.u_DSA.dsa_priv_key
5396 +#define        opdata_dsa_pub          opdata_u.u_DSA.dsa_pub
5397 +#define        opdata_dsa_pub_num      opdata_u.u_DSA.dsa_pub_num
5398 +#define        opdata_dsa_priv         opdata_u.u_DSA.dsa_priv
5399 +#define        opdata_dsa_priv_num     opdata_u.u_DSA.dsa_priv_num
5400 +#define        opdata_dh_key           opdata_u.u_DH.dh_key
5401 +#define        opdata_dh               opdata_u.u_DH.dh
5402 +#define        opdata_dh_priv_num      opdata_u.u_DH.dh_priv_num
5403 +#define        opdata_cipher_key       opdata_u.u_cipher.cipher_key
5404 +#define        opdata_key              opdata_u.u_cipher.key
5405 +#define        opdata_key_len          opdata_u.u_cipher.key_len
5406 +#define        opdata_encrypt          opdata_u.u_cipher.encrypt
5409 + * We have 3 different groups of operation types:
5410 + *   1) asymmetric operations
5411 + *   2) random operations
5412 + *   3) symmetric and digest operations
5413 + *
5414 + * This division into groups stems from the fact that it's common that hardware
5415 + * providers may support operations from one group only. For example, hardware
5416 + * providers on UltraSPARC T2, n2rng(7d), ncp(7d), and n2cp(7d), each support
5417 + * only a single group of operations.
5418 + *
5419 + * For every group a different slot can be chosen. That means that we must have
5420 + * at least 3 different lists of cached PKCS#11 sessions since sessions from
5421 + * different groups may be initialized in different slots.
5422 + *
5423 + * To provide locking granularity in multithreaded environment, the groups are
5424 + * further splitted into types with each type having a separate session cache.
5425 + */
5426 +typedef enum PK11_OPTYPE_ENUM
5427 +       {
5428 +       OP_RAND,
5429 +       OP_RSA,
5430 +       OP_DSA,
5431 +       OP_DH,
5432 +       OP_CIPHER,
5433 +       OP_DIGEST,
5434 +       OP_MAX
5435 +       } PK11_OPTYPE;
5438 + * This structure contains the heads of the lists forming the object caches
5439 + * and locks associated with the lists.
5440 + */
5441 +typedef struct PK11_st_CACHE
5442 +       {
5443 +       PK11_SESSION *head;
5444 +#ifndef NOPTHREADS
5445 +       pthread_mutex_t *lock;
5446 +#endif
5447 +       } PK11_CACHE;
5449 +/* structure for tracking handles of asymmetric key objects */
5450 +typedef struct PK11_active_st
5451 +       {
5452 +       CK_OBJECT_HANDLE h;
5453 +       unsigned int refcnt;
5454 +       struct PK11_active_st *prev;
5455 +       struct PK11_active_st *next;
5456 +       } PK11_active;
5458 +#ifndef NOPTHREADS
5459 +extern pthread_mutex_t *find_lock[];
5460 +#endif
5461 +extern PK11_active *active_list[];
5463 + * These variables are specific for the RSA keys by reference code. See
5464 + * hw_pk11_pub.c for explanation.
5465 + */
5466 +extern CK_FLAGS pubkey_token_flags;
5468 +#ifndef NOPTHREADS
5469 +#define        LOCK_OBJSTORE(alg_type) \
5470 +       OPENSSL_assert(pthread_mutex_lock(find_lock[alg_type]) == 0)
5471 +#define        UNLOCK_OBJSTORE(alg_type)       \
5472 +       OPENSSL_assert(pthread_mutex_unlock(find_lock[alg_type]) == 0)
5473 +#else
5474 +#define        LOCK_OBJSTORE(alg_type) \
5475 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE)
5476 +#define        UNLOCK_OBJSTORE(alg_type)       \
5477 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE)
5478 +#endif
5480 +extern PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
5481 +extern void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
5482 +extern int pk11_token_relogin(CK_SESSION_HANDLE session);
5484 +#ifndef OPENSSL_NO_RSA
5485 +extern int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
5486 +extern int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
5487 +extern int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
5488 +extern EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *pubkey_file,
5489 +       UI_METHOD *ui_method, void *callback_data);
5490 +extern EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
5491 +       UI_METHOD *ui_method, void *callback_data);
5492 +extern RSA_METHOD *PK11_RSA(void);
5493 +#endif /* OPENSSL_NO_RSA */
5494 +#ifndef OPENSSL_NO_DSA
5495 +extern int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
5496 +extern int pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
5497 +extern int pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
5498 +extern DSA_METHOD *PK11_DSA(void);
5499 +#endif /* OPENSSL_NO_DSA */
5500 +#ifndef OPENSSL_NO_DH
5501 +extern int pk11_destroy_dh_key_objects(PK11_SESSION *session);
5502 +extern int pk11_destroy_dh_object(PK11_SESSION *sp, CK_BBOOL uselock);
5503 +extern DH_METHOD *PK11_DH(void);
5504 +#endif /* OPENSSL_NO_DH */
5506 +extern CK_FUNCTION_LIST_PTR pFuncList;
5508 +#endif /* HW_PK11_ERR_H */
5509 Index: openssl/crypto/engine/hw_pk11_pub.c
5510 diff -u /dev/null openssl/crypto/engine/hw_pk11_pub.c:1.42
5511 --- /dev/null   Fri Jan  2 14:59:08 2015
5512 +++ openssl/crypto/engine/hw_pk11_pub.c Fri Oct  4 14:27:06 2013
5513 @@ -0,0 +1,3556 @@
5515 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
5516 + * Use is subject to license terms.
5517 + */
5519 +/* crypto/engine/hw_pk11_pub.c */
5521 + * This product includes software developed by the OpenSSL Project for
5522 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
5523 + *
5524 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
5525 + * Afchine Madjlessi.
5526 + */
5528 + * ====================================================================
5529 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
5530 + *
5531 + * Redistribution and use in source and binary forms, with or without
5532 + * modification, are permitted provided that the following conditions
5533 + * are met:
5534 + *
5535 + * 1. Redistributions of source code must retain the above copyright
5536 + *    notice, this list of conditions and the following disclaimer.
5537 + *
5538 + * 2. Redistributions in binary form must reproduce the above copyright
5539 + *    notice, this list of conditions and the following disclaimer in
5540 + *    the documentation and/or other materials provided with the
5541 + *    distribution.
5542 + *
5543 + * 3. All advertising materials mentioning features or use of this
5544 + *    software must display the following acknowledgment:
5545 + *    "This product includes software developed by the OpenSSL Project
5546 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
5547 + *
5548 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
5549 + *    endorse or promote products derived from this software without
5550 + *    prior written permission. For written permission, please contact
5551 + *    licensing@OpenSSL.org.
5552 + *
5553 + * 5. Products derived from this software may not be called "OpenSSL"
5554 + *    nor may "OpenSSL" appear in their names without prior written
5555 + *    permission of the OpenSSL Project.
5556 + *
5557 + * 6. Redistributions of any form whatsoever must retain the following
5558 + *    acknowledgment:
5559 + *    "This product includes software developed by the OpenSSL Project
5560 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
5561 + *
5562 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
5563 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5564 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
5565 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
5566 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
5567 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
5568 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5569 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5570 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
5571 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
5572 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
5573 + * OF THE POSSIBILITY OF SUCH DAMAGE.
5574 + * ====================================================================
5575 + *
5576 + * This product includes cryptographic software written by Eric Young
5577 + * (eay@cryptsoft.com).  This product includes software written by Tim
5578 + * Hudson (tjh@cryptsoft.com).
5579 + *
5580 + */
5582 +#include <stdio.h>
5583 +#include <stdlib.h>
5584 +#include <string.h>
5585 +#include <sys/types.h>
5587 +#include <openssl/e_os2.h>
5588 +#include <openssl/crypto.h>
5589 +#include <cryptlib.h>
5590 +#include <openssl/engine.h>
5591 +#include <openssl/dso.h>
5592 +#include <openssl/err.h>
5593 +#include <openssl/bn.h>
5594 +#include <openssl/pem.h>
5595 +#ifndef OPENSSL_NO_RSA
5596 +#include <openssl/rsa.h>
5597 +#endif /* OPENSSL_NO_RSA */
5598 +#ifndef OPENSSL_NO_DSA
5599 +#include <openssl/dsa.h>
5600 +#endif /* OPENSSL_NO_DSA */
5601 +#ifndef OPENSSL_NO_DH
5602 +#include <openssl/dh.h>
5603 +#endif /* OPENSSL_NO_DH */
5604 +#include <openssl/rand.h>
5605 +#include <openssl/objects.h>
5606 +#include <openssl/x509.h>
5608 +#ifdef OPENSSL_SYS_WIN32
5609 +#define NOPTHREADS
5610 +typedef int pid_t;
5611 +#define HAVE_GETPASSPHRASE
5612 +static char *getpassphrase(const char *prompt);
5613 +#ifndef NULL_PTR
5614 +#define NULL_PTR NULL
5615 +#endif
5616 +#define CK_DEFINE_FUNCTION(returnType, name) \
5617 +       returnType __declspec(dllexport) name
5618 +#define CK_DECLARE_FUNCTION(returnType, name) \
5619 +       returnType __declspec(dllimport) name
5620 +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
5621 +       returnType __declspec(dllimport) (* name)
5622 +#else
5623 +#include <unistd.h>
5624 +#endif
5626 +#ifndef NOPTHREADS
5627 +#include <pthread.h>
5628 +#endif
5630 +#ifndef OPENSSL_NO_HW
5631 +#ifndef OPENSSL_NO_HW_PK11
5632 +#ifndef OPENSSL_NO_HW_PK11CA
5634 +#ifdef OPENSSL_SYS_WIN32
5635 +#pragma pack(push, cryptoki, 1)
5636 +#include "cryptoki.h"
5637 +#include "pkcs11.h"
5638 +#pragma pack(pop, cryptoki)
5639 +#else
5640 +#include "cryptoki.h"
5641 +#include "pkcs11.h"
5642 +#endif
5643 +#include "hw_pk11ca.h"
5644 +#include "hw_pk11_err.h"
5646 +static CK_BBOOL pk11_login_done = CK_FALSE;
5647 +extern CK_SLOT_ID pubkey_SLOTID;
5648 +#ifndef NOPTHREADS
5649 +extern pthread_mutex_t *token_lock;
5650 +#endif
5652 +#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun)))
5653 +#define getpassphrase(x)       getpass(x)
5654 +#endif
5656 +#ifndef OPENSSL_NO_RSA
5657 +/* RSA stuff */
5658 +static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
5659 +       unsigned char *to, RSA *rsa, int padding);
5660 +static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
5661 +       unsigned char *to, RSA *rsa, int padding);
5662 +static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
5663 +       unsigned char *to, RSA *rsa, int padding);
5664 +static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
5665 +       unsigned char *to, RSA *rsa, int padding);
5666 +static int pk11_RSA_init(RSA *rsa);
5667 +static int pk11_RSA_finish(RSA *rsa);
5668 +static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
5669 +       unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
5670 +#if OPENSSL_VERSION_NUMBER < 0x10000000L
5671 +static int pk11_RSA_verify(int dtype, const unsigned char *m,
5672 +       unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
5673 +       const RSA *rsa);
5674 +#else
5675 +static int pk11_RSA_verify(int dtype, const unsigned char *m,
5676 +       unsigned int m_len, const unsigned char *sigbuf, unsigned int siglen,
5677 +       const RSA *rsa);
5678 +#endif
5679 +EVP_PKEY *pk11_load_privkey(ENGINE*, const char *privkey_file,
5680 +       UI_METHOD *ui_method, void *callback_data);
5681 +EVP_PKEY *pk11_load_pubkey(ENGINE*, const char *pubkey_file,
5682 +       UI_METHOD *ui_method, void *callback_data);
5684 +static int pk11_RSA_public_encrypt_low(int flen, const unsigned char *from,
5685 +       unsigned char *to, RSA *rsa);
5686 +static int pk11_RSA_private_encrypt_low(int flen, const unsigned char *from,
5687 +       unsigned char *to, RSA *rsa);
5688 +static int pk11_RSA_public_decrypt_low(int flen, const unsigned char *from,
5689 +       unsigned char *to, RSA *rsa);
5690 +static int pk11_RSA_private_decrypt_low(int flen, const unsigned char *from,
5691 +       unsigned char *to, RSA *rsa);
5693 +static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA* rsa, RSA** key_ptr,
5694 +       BIGNUM **rsa_n_num, BIGNUM **rsa_e_num, CK_SESSION_HANDLE session);
5695 +static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa, RSA** key_ptr,
5696 +       BIGNUM **rsa_d_num, BIGNUM **rsa_n_num, BIGNUM **rsa_e_num,
5697 +       CK_SESSION_HANDLE session);
5699 +static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa);
5700 +static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa);
5701 +#endif
5703 +/* DSA stuff */
5704 +#ifndef OPENSSL_NO_DSA
5705 +static int pk11_DSA_init(DSA *dsa);
5706 +static int pk11_DSA_finish(DSA *dsa);
5707 +static DSA_SIG *pk11_dsa_do_sign(const unsigned char *dgst, int dlen,
5708 +       DSA *dsa);
5709 +static int pk11_dsa_do_verify(const unsigned char *dgst, int dgst_len,
5710 +       DSA_SIG *sig, DSA *dsa);
5712 +static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa, DSA **key_ptr,
5713 +       BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session);
5714 +static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa, DSA **key_ptr,
5715 +       BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session);
5717 +static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa);
5718 +static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa);
5719 +#endif
5721 +/* DH stuff */
5722 +#ifndef OPENSSL_NO_DH
5723 +static int pk11_DH_init(DH *dh);
5724 +static int pk11_DH_finish(DH *dh);
5725 +static int pk11_DH_generate_key(DH *dh);
5726 +static int pk11_DH_compute_key(unsigned char *key,
5727 +       const BIGNUM *pub_key, DH *dh);
5729 +static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh, DH **key_ptr,
5730 +       BIGNUM **priv_key, CK_SESSION_HANDLE session);
5732 +static int check_new_dh_key(PK11_SESSION *sp, DH *dh);
5733 +#endif
5735 +static int find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
5736 +       CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey);
5737 +static int init_template_value(BIGNUM *bn, CK_VOID_PTR *pValue,
5738 +       CK_ULONG *ulValueLen);
5739 +static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn);
5741 +static int pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
5742 +       CK_BBOOL is_private);
5744 +/* Read mode string to be used for fopen() */
5745 +#if SOLARIS_OPENSSL
5746 +static char *read_mode_flags = "rF";
5747 +#else
5748 +static char *read_mode_flags = "r";
5749 +#endif
5752 + * increment/create reference for an asymmetric key handle via active list
5753 + * manipulation. If active list operation fails, unlock (if locked), set error
5754 + * variable and jump to the specified label.
5755 + */
5756 +#define        KEY_HANDLE_REFHOLD(key_handle, alg_type, unlock, var, label)    \
5757 +       {                                                               \
5758 +       if (pk11_active_add(key_handle, alg_type) < 0)                  \
5759 +               {                                                       \
5760 +               var = TRUE;                                             \
5761 +               if (unlock)                                             \
5762 +                       UNLOCK_OBJSTORE(alg_type);                      \
5763 +               goto label;                                             \
5764 +               }                                                       \
5765 +       }
5768 + * Find active list entry according to object handle and return pointer to the
5769 + * entry otherwise return NULL.
5770 + *
5771 + * This function presumes it is called with lock protecting the active list
5772 + * held.
5773 + */
5774 +static PK11_active *pk11_active_find(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
5775 +       {
5776 +       PK11_active *entry;
5778 +       for (entry = active_list[type]; entry != NULL; entry = entry->next)
5779 +               if (entry->h == h)
5780 +                       return (entry);
5782 +       return (NULL);
5783 +       }
5786 + * Search for an entry in the active list using PKCS#11 object handle as a
5787 + * search key and return refcnt of the found/created entry or -1 in case of
5788 + * failure.
5789 + *
5790 + * This function presumes it is called with lock protecting the active list
5791 + * held.
5792 + */
5793 +int
5794 +pk11_active_add(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
5795 +       {
5796 +       PK11_active *entry = NULL;
5798 +       if (h == CK_INVALID_HANDLE)
5799 +               {
5800 +               PK11err(PK11_F_ACTIVE_ADD, PK11_R_INVALID_HANDLE);
5801 +               return (-1);
5802 +               }
5804 +       /* search for entry in the active list */
5805 +       if ((entry = pk11_active_find(h, type)) != NULL)
5806 +               entry->refcnt++;
5807 +       else
5808 +               {
5809 +               /* not found, create new entry and add it to the list */
5810 +               entry = OPENSSL_malloc(sizeof (PK11_active));
5811 +               if (entry == NULL)
5812 +                       {
5813 +                       PK11err(PK11_F_ACTIVE_ADD, PK11_R_MALLOC_FAILURE);
5814 +                       return (-1);
5815 +                       }
5816 +               entry->h = h;
5817 +               entry->refcnt = 1;
5818 +               entry->prev = NULL;
5819 +               entry->next = NULL;
5820 +               /* connect the newly created entry to the list */
5821 +               if (active_list[type] == NULL)
5822 +                       active_list[type] = entry;
5823 +               else /* make the entry first in the list */
5824 +                       {
5825 +                       entry->next = active_list[type];
5826 +                       active_list[type]->prev = entry;
5827 +                       active_list[type] = entry;
5828 +                       }
5829 +               }
5831 +       return (entry->refcnt);
5832 +       }
5835 + * Remove active list entry from the list and free it.
5836 + *
5837 + * This function presumes it is called with lock protecting the active list
5838 + * held.
5839 + */
5840 +void
5841 +pk11_active_remove(PK11_active *entry, PK11_OPTYPE type)
5842 +       {
5843 +       PK11_active *prev_entry;
5845 +       /* remove the entry from the list and free it */
5846 +       if ((prev_entry = entry->prev) != NULL)
5847 +               {
5848 +               prev_entry->next = entry->next;
5849 +               if (entry->next != NULL)
5850 +                       entry->next->prev = prev_entry;
5851 +               }
5852 +       else
5853 +               {
5854 +               active_list[type] = entry->next;
5855 +               /* we were the first but not the only one */
5856 +               if (entry->next != NULL)
5857 +                       entry->next->prev = NULL;
5858 +               }
5860 +       /* sanitization */
5861 +       entry->h = CK_INVALID_HANDLE;
5862 +       entry->prev = NULL;
5863 +       entry->next = NULL;
5864 +       OPENSSL_free(entry);
5865 +       }
5867 +/* Free all entries from the active list. */
5868 +void
5869 +pk11_free_active_list(PK11_OPTYPE type)
5870 +       {
5871 +       PK11_active *entry;
5873 +       /* only for asymmetric types since only they have C_Find* locks. */
5874 +       switch (type)
5875 +               {
5876 +               case OP_RSA:
5877 +               case OP_DSA:
5878 +               case OP_DH:
5879 +                       break;
5880 +               default:
5881 +                       return;
5882 +               }
5884 +       /* see find_lock array definition for more info on object locking */
5885 +       LOCK_OBJSTORE(type);
5886 +       while ((entry = active_list[type]) != NULL)
5887 +               pk11_active_remove(entry, type);
5888 +       UNLOCK_OBJSTORE(type);
5889 +       }
5892 + * Search for active list entry associated with given PKCS#11 object handle,
5893 + * decrement its refcnt and if it drops to 0, disconnect the entry and free it.
5894 + *
5895 + * Return 1 if the PKCS#11 object associated with the entry has no references,
5896 + * return 0 if there is at least one reference, -1 on error.
5897 + *
5898 + * This function presumes it is called with lock protecting the active list
5899 + * held.
5900 + */
5901 +int
5902 +pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
5903 +       {
5904 +       PK11_active *entry = NULL;
5906 +       if ((entry = pk11_active_find(h, type)) == NULL)
5907 +               {
5908 +               PK11err(PK11_F_ACTIVE_DELETE, PK11_R_INVALID_HANDLE);
5909 +               return (-1);
5910 +               }
5912 +       OPENSSL_assert(entry->refcnt > 0);
5913 +       entry->refcnt--;
5914 +       if (entry->refcnt == 0)
5915 +               {
5916 +               pk11_active_remove(entry, type);
5917 +               return (1);
5918 +               }
5920 +       return (0);
5921 +       }
5923 +#ifndef OPENSSL_NO_RSA
5924 +/* Our internal RSA_METHOD that we provide pointers to */
5925 +static RSA_METHOD pk11_rsa =
5926 +       {
5927 +       "PKCS#11 RSA method",
5928 +       pk11_RSA_public_encrypt,                /* rsa_pub_encrypt */
5929 +       pk11_RSA_public_decrypt,                /* rsa_pub_decrypt */
5930 +       pk11_RSA_private_encrypt,               /* rsa_priv_encrypt */
5931 +       pk11_RSA_private_decrypt,               /* rsa_priv_decrypt */
5932 +       NULL,                                   /* rsa_mod_exp */
5933 +       NULL,                                   /* bn_mod_exp */
5934 +       pk11_RSA_init,                          /* init */
5935 +       pk11_RSA_finish,                        /* finish */
5936 +       RSA_FLAG_SIGN_VER,                      /* flags */
5937 +       NULL,                                   /* app_data */
5938 +       pk11_RSA_sign,                          /* rsa_sign */
5939 +       pk11_RSA_verify                         /* rsa_verify */
5940 +       };
5942 +RSA_METHOD *
5943 +PK11_RSA(void)
5944 +       {
5945 +       return (&pk11_rsa);
5946 +       }
5947 +#endif
5949 +#ifndef OPENSSL_NO_DSA
5950 +/* Our internal DSA_METHOD that we provide pointers to */
5951 +static DSA_METHOD pk11_dsa =
5952 +       {
5953 +       "PKCS#11 DSA method",
5954 +       pk11_dsa_do_sign,       /* dsa_do_sign */
5955 +       NULL,                   /* dsa_sign_setup */
5956 +       pk11_dsa_do_verify,     /* dsa_do_verify */
5957 +       NULL,                   /* dsa_mod_exp */
5958 +       NULL,                   /* bn_mod_exp */
5959 +       pk11_DSA_init,          /* init */
5960 +       pk11_DSA_finish,        /* finish */
5961 +       0,                      /* flags */
5962 +       NULL                    /* app_data */
5963 +       };
5965 +DSA_METHOD *
5966 +PK11_DSA(void)
5967 +       {
5968 +       return (&pk11_dsa);
5969 +       }
5970 +#endif
5972 +#ifndef OPENSSL_NO_DH
5974 + * PKCS #11 V2.20, section 11.2 specifies that the number of bytes needed for
5975 + * output buffer may somewhat exceed the precise number of bytes needed, but
5976 + * should not exceed it by a large amount. That may be caused, for example, by
5977 + * rounding it up to multiple of X in the underlying bignum library. 8 should be
5978 + * enough.
5979 + */
5980 +#define        DH_BUF_RESERVE  8
5982 +/* Our internal DH_METHOD that we provide pointers to */
5983 +static DH_METHOD pk11_dh =
5984 +       {
5985 +       "PKCS#11 DH method",
5986 +       pk11_DH_generate_key,   /* generate_key */
5987 +       pk11_DH_compute_key,    /* compute_key */
5988 +       NULL,                   /* bn_mod_exp */
5989 +       pk11_DH_init,           /* init */
5990 +       pk11_DH_finish,         /* finish */
5991 +       0,                      /* flags */
5992 +       NULL,                   /* app_data */
5993 +       NULL                    /* generate_params */
5994 +       };
5996 +DH_METHOD *
5997 +PK11_DH(void)
5998 +       {
5999 +       return (&pk11_dh);
6000 +       }
6001 +#endif
6003 +/* Size of an SSL signature: MD5+SHA1 */
6004 +#define        SSL_SIG_LENGTH          36
6006 +/* Lengths of DSA data and signature */
6007 +#define        DSA_DATA_LEN            20
6008 +#define        DSA_SIGNATURE_LEN       40
6010 +static CK_BBOOL mytrue = TRUE;
6011 +static CK_BBOOL myfalse = FALSE;
6013 +#ifndef OPENSSL_NO_RSA
6015 + * Similiar to OpenSSL to take advantage of the paddings. The goal is to
6016 + * support all paddings in this engine although PK11 library does not
6017 + * support all the paddings used in OpenSSL.
6018 + * The input errors should have been checked in the padding functions.
6019 + */
6020 +static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
6021 +               unsigned char *to, RSA *rsa, int padding)
6022 +       {
6023 +       int i, num = 0, r = -1;
6024 +       unsigned char *buf = NULL;
6026 +       num = BN_num_bytes(rsa->n);
6027 +       if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
6028 +               {
6029 +               RSAerr(PK11_F_RSA_PUB_ENC, PK11_R_MALLOC_FAILURE);
6030 +               goto err;
6031 +               }
6033 +       switch (padding)
6034 +               {
6035 +       case RSA_PKCS1_PADDING:
6036 +               i = RSA_padding_add_PKCS1_type_2(buf, num, from, flen);
6037 +               break;
6038 +#ifndef OPENSSL_NO_SHA
6039 +       case RSA_PKCS1_OAEP_PADDING:
6040 +               i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0);
6041 +               break;
6042 +#endif
6043 +       case RSA_SSLV23_PADDING:
6044 +               i = RSA_padding_add_SSLv23(buf, num, from, flen);
6045 +               break;
6046 +       case RSA_NO_PADDING:
6047 +               i = RSA_padding_add_none(buf, num, from, flen);
6048 +               break;
6049 +       default:
6050 +               RSAerr(PK11_F_RSA_PUB_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
6051 +               goto err;
6052 +               }
6053 +       if (i <= 0) goto err;
6055 +       /* PK11 functions are called here */
6056 +       r = pk11_RSA_public_encrypt_low(num, buf, to, rsa);
6057 +err:
6058 +       if (buf != NULL)
6059 +               {
6060 +               OPENSSL_cleanse(buf, num);
6061 +               OPENSSL_free(buf);
6062 +               }
6063 +       return (r);
6064 +       }
6068 + * Similar to Openssl to take advantage of the paddings. The input errors
6069 + * should be catched in the padding functions
6070 + */
6071 +static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
6072 +       unsigned char *to, RSA *rsa, int padding)
6073 +       {
6074 +       int i, num = 0, r = -1;
6075 +       unsigned char *buf = NULL;
6077 +       num = BN_num_bytes(rsa->n);
6078 +       if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
6079 +               {
6080 +               RSAerr(PK11_F_RSA_PRIV_ENC, PK11_R_MALLOC_FAILURE);
6081 +               goto err;
6082 +               }
6084 +       switch (padding)
6085 +               {
6086 +       case RSA_PKCS1_PADDING:
6087 +               i = RSA_padding_add_PKCS1_type_1(buf, num, from, flen);
6088 +               break;
6089 +       case RSA_NO_PADDING:
6090 +               i = RSA_padding_add_none(buf, num, from, flen);
6091 +               break;
6092 +       case RSA_SSLV23_PADDING:
6093 +       default:
6094 +               RSAerr(PK11_F_RSA_PRIV_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
6095 +               goto err;
6096 +               }
6097 +       if (i <= 0) goto err;
6099 +       /* PK11 functions are called here */
6100 +       r = pk11_RSA_private_encrypt_low(num, buf, to, rsa);
6101 +err:
6102 +       if (buf != NULL)
6103 +               {
6104 +               OPENSSL_cleanse(buf, num);
6105 +               OPENSSL_free(buf);
6106 +               }
6107 +       return (r);
6108 +       }
6110 +/* Similar to OpenSSL code. Input errors are also checked here */
6111 +static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
6112 +       unsigned char *to, RSA *rsa, int padding)
6113 +       {
6114 +       BIGNUM f;
6115 +       int j, num = 0, r = -1;
6116 +       unsigned char *p;
6117 +       unsigned char *buf = NULL;
6119 +       BN_init(&f);
6121 +       num = BN_num_bytes(rsa->n);
6123 +       if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
6124 +               {
6125 +               RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_MALLOC_FAILURE);
6126 +               goto err;
6127 +               }
6129 +       /*
6130 +        * This check was for equality but PGP does evil things
6131 +        * and chops off the top '0' bytes
6132 +        */
6133 +       if (flen > num)
6134 +               {
6135 +               RSAerr(PK11_F_RSA_PRIV_DEC,
6136 +                       PK11_R_DATA_GREATER_THAN_MOD_LEN);
6137 +               goto err;
6138 +               }
6140 +       /* make data into a big number */
6141 +       if (BN_bin2bn(from, (int)flen, &f) == NULL)
6142 +               goto err;
6144 +       if (BN_ucmp(&f, rsa->n) >= 0)
6145 +               {
6146 +               RSAerr(PK11_F_RSA_PRIV_DEC,
6147 +                       PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
6148 +               goto err;
6149 +               }
6151 +       /* PK11 functions are called here */
6152 +       r = pk11_RSA_private_decrypt_low(flen, from, buf, rsa);
6154 +       /*
6155 +        * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
6156 +        * Needs to skip these 0's paddings here.
6157 +        */
6158 +       for (j = 0; j < r; j++)
6159 +               if (buf[j] != 0)
6160 +                       break;
6162 +       p = buf + j;
6163 +       j = r - j;  /* j is only used with no-padding mode */
6165 +       switch (padding)
6166 +               {
6167 +       case RSA_PKCS1_PADDING:
6168 +               r = RSA_padding_check_PKCS1_type_2(to, num, p, j, num);
6169 +               break;
6170 +#ifndef OPENSSL_NO_SHA
6171 +       case RSA_PKCS1_OAEP_PADDING:
6172 +               r = RSA_padding_check_PKCS1_OAEP(to, num, p, j, num, NULL, 0);
6173 +               break;
6174 +#endif
6175 +       case RSA_SSLV23_PADDING:
6176 +               r = RSA_padding_check_SSLv23(to, num, p, j, num);
6177 +               break;
6178 +       case RSA_NO_PADDING:
6179 +               r = RSA_padding_check_none(to, num, p, j, num);
6180 +               break;
6181 +       default:
6182 +               RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
6183 +               goto err;
6184 +               }
6185 +       if (r < 0)
6186 +               RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_PADDING_CHECK_FAILED);
6188 +err:
6189 +       BN_clear_free(&f);
6190 +       if (buf != NULL)
6191 +               {
6192 +               OPENSSL_cleanse(buf, num);
6193 +               OPENSSL_free(buf);
6194 +               }
6195 +       return (r);
6196 +       }
6198 +/* Similar to OpenSSL code. Input errors are also checked here */
6199 +static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
6200 +       unsigned char *to, RSA *rsa, int padding)
6201 +       {
6202 +       BIGNUM f;
6203 +       int i, num = 0, r = -1;
6204 +       unsigned char *p;
6205 +       unsigned char *buf = NULL;
6207 +       BN_init(&f);
6208 +       num = BN_num_bytes(rsa->n);
6209 +       buf = (unsigned char *)OPENSSL_malloc(num);
6210 +       if (buf == NULL)
6211 +               {
6212 +               RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_MALLOC_FAILURE);
6213 +               goto err;
6214 +               }
6216 +       /*
6217 +        * This check was for equality but PGP does evil things
6218 +        * and chops off the top '0' bytes
6219 +        */
6220 +       if (flen > num)
6221 +               {
6222 +               RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_DATA_GREATER_THAN_MOD_LEN);
6223 +               goto err;
6224 +               }
6226 +       if (BN_bin2bn(from, flen, &f) == NULL)
6227 +               goto err;
6229 +       if (BN_ucmp(&f, rsa->n) >= 0)
6230 +               {
6231 +               RSAerr(PK11_F_RSA_PUB_DEC,
6232 +                       PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
6233 +               goto err;
6234 +               }
6236 +       /* PK11 functions are called here */
6237 +       r = pk11_RSA_public_decrypt_low(flen, from, buf, rsa);
6239 +       /*
6240 +        * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
6241 +        * Needs to skip these 0's here
6242 +        */
6243 +       for (i = 0; i < r; i++)
6244 +               if (buf[i] != 0)
6245 +                       break;
6247 +       p = buf + i;
6248 +       i = r - i;  /* i is only used with no-padding mode */
6250 +       switch (padding)
6251 +               {
6252 +       case RSA_PKCS1_PADDING:
6253 +               r = RSA_padding_check_PKCS1_type_1(to, num, p, i, num);
6254 +               break;
6255 +       case RSA_NO_PADDING:
6256 +               r = RSA_padding_check_none(to, num, p, i, num);
6257 +               break;
6258 +       default:
6259 +               RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
6260 +               goto err;
6261 +               }
6262 +       if (r < 0)
6263 +               RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_PADDING_CHECK_FAILED);
6265 +err:
6266 +       BN_clear_free(&f);
6267 +       if (buf != NULL)
6268 +               {
6269 +               OPENSSL_cleanse(buf, num);
6270 +               OPENSSL_free(buf);
6271 +               }
6272 +       return (r);
6273 +       }
6276 + * This function implements RSA public encryption using C_EncryptInit and
6277 + * C_Encrypt pk11 interfaces. Note that the CKM_RSA_X_509 is used here.
6278 + * The calling function allocated sufficient memory in "to" to store results.
6279 + */
6280 +static int pk11_RSA_public_encrypt_low(int flen,
6281 +       const unsigned char *from, unsigned char *to, RSA *rsa)
6282 +       {
6283 +       CK_ULONG bytes_encrypted = flen;
6284 +       int retval = -1;
6285 +       CK_RV rv;
6286 +       CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6287 +       CK_MECHANISM *p_mech = &mech_rsa;
6288 +       CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
6289 +       PK11_SESSION *sp;
6291 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6292 +               return (-1);
6294 +       (void) check_new_rsa_key_pub(sp, rsa);
6296 +       h_pub_key = sp->opdata_rsa_pub_key;
6297 +       if (h_pub_key == CK_INVALID_HANDLE)
6298 +               h_pub_key = sp->opdata_rsa_pub_key =
6299 +                       pk11_get_public_rsa_key(rsa, &sp->opdata_rsa_pub,
6300 +                           &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
6301 +                           sp->session);
6303 +       if (h_pub_key != CK_INVALID_HANDLE)
6304 +               {
6305 +               rv = pFuncList->C_EncryptInit(sp->session, p_mech,
6306 +                       h_pub_key);
6308 +               if (rv != CKR_OK)
6309 +                       {
6310 +                       PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
6311 +                           PK11_R_ENCRYPTINIT, rv);
6312 +                       pk11_return_session(sp, OP_RSA);
6313 +                       return (-1);
6314 +                       }
6316 +               rv = pFuncList->C_Encrypt(sp->session,
6317 +                       (unsigned char *)from, flen, to, &bytes_encrypted);
6319 +               if (rv != CKR_OK)
6320 +                       {
6321 +                       PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
6322 +                           PK11_R_ENCRYPT, rv);
6323 +                       pk11_return_session(sp, OP_RSA);
6324 +                       return (-1);
6325 +                       }
6326 +               retval = bytes_encrypted;
6327 +               }
6329 +       pk11_return_session(sp, OP_RSA);
6330 +       return (retval);
6331 +       }
6335 + * This function implements RSA private encryption using C_SignInit and
6336 + * C_Sign pk11 APIs. Note that CKM_RSA_X_509 is used here.
6337 + * The calling function allocated sufficient memory in "to" to store results.
6338 + */
6339 +static int pk11_RSA_private_encrypt_low(int flen,
6340 +       const unsigned char *from, unsigned char *to, RSA *rsa)
6341 +       {
6342 +       CK_ULONG ul_sig_len = flen;
6343 +       int retval = -1;
6344 +       CK_RV rv;
6345 +       CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6346 +       CK_MECHANISM *p_mech = &mech_rsa;
6347 +       CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
6348 +       PK11_SESSION *sp;
6350 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6351 +               return (-1);
6353 +       (void) check_new_rsa_key_priv(sp, rsa);
6355 +       h_priv_key = sp->opdata_rsa_priv_key;
6356 +       if (h_priv_key == CK_INVALID_HANDLE)
6357 +               {
6358 +               h_priv_key = sp->opdata_rsa_priv_key =
6359 +                       pk11_get_private_rsa_key(rsa, &sp->opdata_rsa_priv,
6360 +                           &sp->opdata_rsa_d_num, &sp->opdata_rsa_pn_num,
6361 +                           &sp->opdata_rsa_pe_num, sp->session);
6362 +               }
6364 +       if (h_priv_key != CK_INVALID_HANDLE)
6365 +               {
6366 +               rv = pFuncList->C_SignInit(sp->session, p_mech,
6367 +                       h_priv_key);
6369 +               if (rv != CKR_OK)
6370 +                       {
6371 +                       PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW,
6372 +                           PK11_R_SIGNINIT, rv);
6373 +                       pk11_return_session(sp, OP_RSA);
6374 +                       return (-1);
6375 +                       }
6377 +               rv = pFuncList->C_Sign(sp->session,
6378 +                       (unsigned char *)from, flen, to, &ul_sig_len);
6380 +               if (rv != CKR_OK)
6381 +                       {
6382 +                       PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW, PK11_R_SIGN,
6383 +                           rv);
6384 +                       pk11_return_session(sp, OP_RSA);
6385 +                       return (-1);
6386 +                       }
6388 +               retval = ul_sig_len;
6389 +               }
6391 +       pk11_return_session(sp, OP_RSA);
6392 +       return (retval);
6393 +       }
6397 + * This function implements RSA private decryption using C_DecryptInit and
6398 + * C_Decrypt pk11 APIs. Note that CKM_RSA_X_509 mechanism is used here.
6399 + * The calling function allocated sufficient memory in "to" to store results.
6400 + */
6401 +static int pk11_RSA_private_decrypt_low(int flen,
6402 +       const unsigned char *from, unsigned char *to, RSA *rsa)
6403 +       {
6404 +       CK_ULONG bytes_decrypted = flen;
6405 +       int retval = -1;
6406 +       CK_RV rv;
6407 +       CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6408 +       CK_MECHANISM *p_mech = &mech_rsa;
6409 +       CK_OBJECT_HANDLE h_priv_key;
6410 +       PK11_SESSION *sp;
6412 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6413 +               return (-1);
6415 +       (void) check_new_rsa_key_priv(sp, rsa);
6417 +       h_priv_key = sp->opdata_rsa_priv_key;
6418 +       if (h_priv_key == CK_INVALID_HANDLE)
6419 +               h_priv_key = sp->opdata_rsa_priv_key =
6420 +                       pk11_get_private_rsa_key(rsa, &sp->opdata_rsa_priv,
6421 +                           &sp->opdata_rsa_d_num, &sp->opdata_rsa_pn_num,
6422 +                           &sp->opdata_rsa_pe_num, sp->session);
6424 +       if (h_priv_key != CK_INVALID_HANDLE)
6425 +               {
6426 +               rv = pFuncList->C_DecryptInit(sp->session, p_mech,
6427 +                       h_priv_key);
6429 +               if (rv != CKR_OK)
6430 +                       {
6431 +                       PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
6432 +                               PK11_R_DECRYPTINIT, rv);
6433 +                       pk11_return_session(sp, OP_RSA);
6434 +                       return (-1);
6435 +                       }
6437 +               rv = pFuncList->C_Decrypt(sp->session,
6438 +                       (unsigned char *)from, flen, to, &bytes_decrypted);
6440 +               if (rv != CKR_OK)
6441 +                       {
6442 +                       PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
6443 +                           PK11_R_DECRYPT, rv);
6444 +                       pk11_return_session(sp, OP_RSA);
6445 +                       return (-1);
6446 +                       }
6447 +               retval = bytes_decrypted;
6448 +               }
6450 +       pk11_return_session(sp, OP_RSA);
6451 +       return (retval);
6452 +       }
6456 + * This function implements RSA public decryption using C_VerifyRecoverInit
6457 + * and C_VerifyRecover pk11 APIs. Note that CKM_RSA_X_509 is used here.
6458 + * The calling function allocated sufficient memory in "to" to store results.
6459 + */
6460 +static int pk11_RSA_public_decrypt_low(int flen,
6461 +       const unsigned char *from, unsigned char *to, RSA *rsa)
6462 +       {
6463 +       CK_ULONG bytes_decrypted = flen;
6464 +       int retval = -1;
6465 +       CK_RV rv;
6466 +       CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6467 +       CK_MECHANISM *p_mech = &mech_rsa;
6468 +       CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
6469 +       PK11_SESSION *sp;
6471 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6472 +               return (-1);
6474 +       (void) check_new_rsa_key_pub(sp, rsa);
6476 +       h_pub_key = sp->opdata_rsa_pub_key;
6477 +       if (h_pub_key == CK_INVALID_HANDLE)
6478 +               h_pub_key = sp->opdata_rsa_pub_key =
6479 +                       pk11_get_public_rsa_key(rsa, &sp->opdata_rsa_pub,
6480 +                           &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
6481 +                           sp->session);
6483 +       if (h_pub_key != CK_INVALID_HANDLE)
6484 +               {
6485 +               rv = pFuncList->C_VerifyRecoverInit(sp->session,
6486 +                       p_mech, h_pub_key);
6488 +               if (rv != CKR_OK)
6489 +                       {
6490 +                       PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
6491 +                               PK11_R_VERIFYRECOVERINIT, rv);
6492 +                       pk11_return_session(sp, OP_RSA);
6493 +                       return (-1);
6494 +                       }
6496 +               rv = pFuncList->C_VerifyRecover(sp->session,
6497 +                       (unsigned char *)from, flen, to, &bytes_decrypted);
6499 +               if (rv != CKR_OK)
6500 +                       {
6501 +                       PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
6502 +                           PK11_R_VERIFYRECOVER, rv);
6503 +                       pk11_return_session(sp, OP_RSA);
6504 +                       return (-1);
6505 +                       }
6506 +               retval = bytes_decrypted;
6507 +               }
6509 +       pk11_return_session(sp, OP_RSA);
6510 +       return (retval);
6511 +       }
6513 +static int pk11_RSA_init(RSA *rsa)
6514 +       {
6515 +       /*
6516 +        * This flag in the RSA_METHOD enables the new rsa_sign,
6517 +        * rsa_verify functions. See rsa.h for details.
6518 +        */
6519 +       rsa->flags |= RSA_FLAG_SIGN_VER;
6521 +       return (1);
6522 +       }
6524 +static int pk11_RSA_finish(RSA *rsa)
6525 +       {
6526 +       /*
6527 +        * Since we are overloading OpenSSL's native RSA_eay_finish() we need
6528 +        * to do the same as in the original function, i.e. to free bignum
6529 +        * structures.
6530 +        */
6531 +       if (rsa->_method_mod_n != NULL)
6532 +               BN_MONT_CTX_free(rsa->_method_mod_n);
6533 +       if (rsa->_method_mod_p != NULL)
6534 +               BN_MONT_CTX_free(rsa->_method_mod_p);
6535 +       if (rsa->_method_mod_q != NULL)
6536 +               BN_MONT_CTX_free(rsa->_method_mod_q);
6538 +       return (1);
6539 +       }
6542 + * Standard engine interface function. Majority codes here are from
6543 + * rsa/rsa_sign.c. We replaced the decrypt function call by C_Sign of PKCS#11.
6544 + * See more details in rsa/rsa_sign.c
6545 + */
6546 +static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
6547 +       unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
6548 +       {
6549 +       X509_SIG sig;
6550 +       ASN1_TYPE parameter;
6551 +       int i, j = 0;
6552 +       unsigned char *p, *s = NULL;
6553 +       X509_ALGOR algor;
6554 +       ASN1_OCTET_STRING digest;
6555 +       CK_RV rv;
6556 +       CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
6557 +       CK_MECHANISM *p_mech = &mech_rsa;
6558 +       CK_OBJECT_HANDLE h_priv_key;
6559 +       PK11_SESSION *sp = NULL;
6560 +       int ret = 0;
6561 +       unsigned long ulsiglen;
6563 +       /* Encode the digest */
6564 +       /* Special case: SSL signature, just check the length */
6565 +       if (type == NID_md5_sha1)
6566 +               {
6567 +               if (m_len != SSL_SIG_LENGTH)
6568 +                       {
6569 +                       PK11err(PK11_F_RSA_SIGN,
6570 +                               PK11_R_INVALID_MESSAGE_LENGTH);
6571 +                       goto err;
6572 +                       }
6573 +               i = SSL_SIG_LENGTH;
6574 +               s = (unsigned char *)m;
6575 +               }
6576 +       else
6577 +               {
6578 +               sig.algor = &algor;
6579 +               sig.algor->algorithm = OBJ_nid2obj(type);
6580 +               if (sig.algor->algorithm == NULL)
6581 +                       {
6582 +                       PK11err(PK11_F_RSA_SIGN,
6583 +                               PK11_R_UNKNOWN_ALGORITHM_TYPE);
6584 +                       goto err;
6585 +                       }
6586 +               if (sig.algor->algorithm->length == 0)
6587 +                       {
6588 +                       PK11err(PK11_F_RSA_SIGN,
6589 +                               PK11_R_UNKNOWN_ASN1_OBJECT_ID);
6590 +                       goto err;
6591 +                       }
6592 +               parameter.type = V_ASN1_NULL;
6593 +               parameter.value.ptr = NULL;
6594 +               sig.algor->parameter = &parameter;
6596 +               sig.digest = &digest;
6597 +               sig.digest->data = (unsigned char *)m;
6598 +               sig.digest->length = m_len;
6600 +               i = i2d_X509_SIG(&sig, NULL);
6601 +               }
6603 +       j = RSA_size(rsa);
6604 +       if ((i - RSA_PKCS1_PADDING) > j)
6605 +               {
6606 +               PK11err(PK11_F_RSA_SIGN, PK11_R_DIGEST_TOO_BIG);
6607 +               goto err;
6608 +               }
6610 +       if (type != NID_md5_sha1)
6611 +               {
6612 +               s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
6613 +               if (s == NULL)
6614 +                       {
6615 +                       PK11err(PK11_F_RSA_SIGN, PK11_R_MALLOC_FAILURE);
6616 +                       goto err;
6617 +                       }
6618 +               p = s;
6619 +               (void) i2d_X509_SIG(&sig, &p);
6620 +               }
6622 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6623 +               goto err;
6625 +       (void) check_new_rsa_key_priv(sp, rsa);
6627 +       h_priv_key = sp->opdata_rsa_priv_key;
6628 +       if (h_priv_key == CK_INVALID_HANDLE)
6629 +               h_priv_key = sp->opdata_rsa_priv_key =
6630 +                       pk11_get_private_rsa_key((RSA *)rsa,
6631 +                           &sp->opdata_rsa_priv, &sp->opdata_rsa_d_num,
6632 +                           &sp->opdata_rsa_pn_num, &sp->opdata_rsa_pe_num,
6633 +                           sp->session);
6635 +       if (h_priv_key != CK_INVALID_HANDLE)
6636 +               {
6637 +               rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
6639 +               if (rv != CKR_OK)
6640 +                       {
6641 +                       PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGNINIT, rv);
6642 +                       goto err;
6643 +                       }
6645 +               ulsiglen = j;
6646 +               rv = pFuncList->C_Sign(sp->session, s, i, sigret,
6647 +                       (CK_ULONG_PTR) &ulsiglen);
6648 +               *siglen = ulsiglen;
6650 +               if (rv != CKR_OK)
6651 +                       {
6652 +                       PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGN, rv);
6653 +                       goto err;
6654 +                       }
6655 +               ret = 1;
6656 +               }
6658 +err:
6659 +       if ((type != NID_md5_sha1) && (s != NULL))
6660 +               {
6661 +               (void) memset(s, 0, (unsigned int)(j + 1));
6662 +               OPENSSL_free(s);
6663 +               }
6665 +       pk11_return_session(sp, OP_RSA);
6666 +       return (ret);
6667 +       }
6669 +#if OPENSSL_VERSION_NUMBER < 0x10000000L
6670 +static int pk11_RSA_verify(int type, const unsigned char *m,
6671 +       unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
6672 +       const RSA *rsa)
6673 +#else
6674 +static int pk11_RSA_verify(int type, const unsigned char *m,
6675 +       unsigned int m_len, const unsigned char *sigbuf, unsigned int siglen,
6676 +       const RSA *rsa)
6677 +#endif
6678 +       {
6679 +       X509_SIG sig;
6680 +       ASN1_TYPE parameter;
6681 +       int i, j = 0;
6682 +       unsigned char *p, *s = NULL;
6683 +       X509_ALGOR algor;
6684 +       ASN1_OCTET_STRING digest;
6685 +       CK_RV rv;
6686 +       CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
6687 +       CK_MECHANISM *p_mech = &mech_rsa;
6688 +       CK_OBJECT_HANDLE h_pub_key;
6689 +       PK11_SESSION *sp = NULL;
6690 +       int ret = 0;
6692 +       /* Encode the digest    */
6693 +       /* Special case: SSL signature, just check the length */
6694 +       if (type == NID_md5_sha1)
6695 +               {
6696 +               if (m_len != SSL_SIG_LENGTH)
6697 +                       {
6698 +                       PK11err(PK11_F_RSA_VERIFY,
6699 +                               PK11_R_INVALID_MESSAGE_LENGTH);
6700 +                       goto err;
6701 +                       }
6702 +               i = SSL_SIG_LENGTH;
6703 +               s = (unsigned char *)m;
6704 +               }
6705 +       else
6706 +               {
6707 +               sig.algor = &algor;
6708 +               sig.algor->algorithm = OBJ_nid2obj(type);
6709 +               if (sig.algor->algorithm == NULL)
6710 +                       {
6711 +                       PK11err(PK11_F_RSA_VERIFY,
6712 +                               PK11_R_UNKNOWN_ALGORITHM_TYPE);
6713 +                       goto err;
6714 +                       }
6715 +               if (sig.algor->algorithm->length == 0)
6716 +                       {
6717 +                       PK11err(PK11_F_RSA_VERIFY,
6718 +                               PK11_R_UNKNOWN_ASN1_OBJECT_ID);
6719 +                       goto err;
6720 +                       }
6721 +               parameter.type = V_ASN1_NULL;
6722 +               parameter.value.ptr = NULL;
6723 +               sig.algor->parameter = &parameter;
6724 +               sig.digest = &digest;
6725 +               sig.digest->data = (unsigned char *)m;
6726 +               sig.digest->length = m_len;
6727 +               i = i2d_X509_SIG(&sig, NULL);
6728 +               }
6730 +       j = RSA_size(rsa);
6731 +       if ((i - RSA_PKCS1_PADDING) > j)
6732 +               {
6733 +               PK11err(PK11_F_RSA_VERIFY, PK11_R_DIGEST_TOO_BIG);
6734 +               goto err;
6735 +               }
6737 +       if (type != NID_md5_sha1)
6738 +               {
6739 +               s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
6740 +               if (s == NULL)
6741 +                       {
6742 +                       PK11err(PK11_F_RSA_VERIFY, PK11_R_MALLOC_FAILURE);
6743 +                       goto err;
6744 +                       }
6745 +               p = s;
6746 +               (void) i2d_X509_SIG(&sig, &p);
6747 +               }
6749 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6750 +               goto err;
6752 +       (void) check_new_rsa_key_pub(sp, rsa);
6754 +       h_pub_key = sp->opdata_rsa_pub_key;
6755 +       if (h_pub_key == CK_INVALID_HANDLE)
6756 +               h_pub_key = sp->opdata_rsa_pub_key =
6757 +                       pk11_get_public_rsa_key((RSA *)rsa, &sp->opdata_rsa_pub,
6758 +                           &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
6759 +                           sp->session);
6761 +       if (h_pub_key != CK_INVALID_HANDLE)
6762 +               {
6763 +               rv = pFuncList->C_VerifyInit(sp->session, p_mech,
6764 +                       h_pub_key);
6766 +               if (rv != CKR_OK)
6767 +                       {
6768 +                       PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFYINIT,
6769 +                           rv);
6770 +                       goto err;
6771 +                       }
6772 +               rv = pFuncList->C_Verify(sp->session, s, i,
6773 +                       (CK_BYTE_PTR)sigbuf, (CK_ULONG)siglen);
6775 +               if (rv != CKR_OK)
6776 +                       {
6777 +                       PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFY, rv);
6778 +                       goto err;
6779 +                       }
6780 +               ret = 1;
6781 +               }
6783 +err:
6784 +       if ((type != NID_md5_sha1) && (s != NULL))
6785 +               {
6786 +               (void) memset(s, 0, (unsigned int)(j + 1));
6787 +               OPENSSL_free(s);
6788 +               }
6790 +       pk11_return_session(sp, OP_RSA);
6791 +       return (ret);
6792 +       }
6794 +static int hndidx_rsa = -1;
6796 +#define        MAXATTR 1024
6799 + * Load RSA private key from a file or get its PKCS#11 handle if stored in the
6800 + * PKCS#11 token.
6801 + */
6802 +/* ARGSUSED */
6803 +EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *privkey_file,
6804 +       UI_METHOD *ui_method, void *callback_data)
6805 +       {
6806 +       EVP_PKEY *pkey = NULL;
6807 +       FILE *privkey;
6808 +       CK_OBJECT_HANDLE  h_priv_key = CK_INVALID_HANDLE;
6809 +       RSA *rsa = NULL;
6810 +       PK11_SESSION *sp;
6811 +       /* Anything else below is needed for the key by reference extension. */
6812 +       CK_RV rv;
6813 +       CK_BBOOL is_token = TRUE;
6814 +       CK_BBOOL rollback = FALSE;
6815 +       CK_BYTE attr_data[2][MAXATTR];
6816 +       CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
6817 +       CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;    /* key in keystore */
6819 +       /* we look for private keys only */
6820 +       CK_ATTRIBUTE search_templ[] =
6821 +               {
6822 +               {CKA_TOKEN, &is_token, sizeof(is_token)},
6823 +               {CKA_CLASS, &key_class, sizeof(key_class)},
6824 +               {CKA_LABEL, NULL, 0}
6825 +               };
6827 +       /*
6828 +        * These public attributes are needed to initialize the OpenSSL RSA
6829 +        * structure with something we can use to look up the key. Note that we
6830 +        * never ask for private components.
6831 +        */
6832 +       CK_ATTRIBUTE get_templ[] =
6833 +               {
6834 +               {CKA_MODULUS, (void *)attr_data[0], MAXATTR},           /* n */
6835 +               {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},   /* e */
6836 +               };
6838 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6839 +               return (NULL);
6841 +       /*
6842 +        * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
6843 +        */
6844 +       if (strstr(privkey_file, "pkcs11:") == privkey_file)
6845 +               {
6846 +               search_templ[2].pValue = strstr(privkey_file, ":") + 1;
6847 +               search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
6849 +               if (pk11_token_login(sp->session, &pk11_login_done,
6850 +                   CK_TRUE) == 0)
6851 +                       goto err;
6853 +               /* see find_lock array definition
6854 +                  for more info on object locking */
6855 +               LOCK_OBJSTORE(OP_RSA);
6857 +               /*
6858 +                * Now let's try to find the key in the token. It is a failure
6859 +                * if we can't find it.
6860 +                */
6861 +               if (find_one_object(OP_RSA, sp->session, search_templ, 3,
6862 +                   &ks_key) == 0)
6863 +                       {
6864 +                       UNLOCK_OBJSTORE(OP_RSA);
6865 +                       goto err;
6866 +                       }
6868 +               if (hndidx_rsa == -1)
6869 +                       hndidx_rsa = RSA_get_ex_new_index(0,
6870 +                                       "pkcs11 RSA HSM key handle",
6871 +                                       NULL, NULL, NULL);
6873 +               /*
6874 +                * We might have a cache hit which we could confirm
6875 +                * according to the 'n'/'e' params, RSA public pointer
6876 +                * as NULL, and non-NULL RSA private pointer. However,
6877 +                * it is easier just to recreate everything. We expect
6878 +                * the keys to be loaded once and used many times. We
6879 +                * do not check the return value because even in case
6880 +                * of failure the sp structure will have both key
6881 +                * pointer and object handle cleaned and
6882 +                * pk11_destroy_object() reports the failure to the
6883 +                * OpenSSL error message buffer.
6884 +                */
6885 +               (void) pk11_destroy_rsa_object_priv(sp, FALSE);
6887 +               sp->opdata_rsa_priv_key = ks_key;
6888 +               /* This object shall not be deleted on a cache miss. */
6889 +               sp->priv_persistent = CK_TRUE;
6891 +               /*
6892 +                * Cache the RSA private structure pointer. We do not
6893 +                * use it now for key-by-ref keys but let's do it for
6894 +                * consistency reasons.
6895 +                */
6896 +               if ((rsa = sp->opdata_rsa_priv = RSA_new_method(e)) == NULL)
6897 +                       {
6898 +                       UNLOCK_OBJSTORE(OP_RSA);
6899 +                       goto err;
6900 +                       }
6902 +               /*
6903 +                * Now we have to initialize an OpenSSL RSA structure,
6904 +                * everything else is 0 or NULL.
6905 +                */
6906 +               rsa->flags = RSA_FLAG_SIGN_VER | RSA_FLAG_EXT_PKEY;
6907 +               RSA_set_ex_data(rsa, hndidx_rsa, (void *) ks_key);
6909 +               if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
6910 +                   get_templ, 2)) != CKR_OK)
6911 +                       {
6912 +                       UNLOCK_OBJSTORE(OP_RSA);
6913 +                       PK11err_add_data(PK11_F_LOAD_PRIVKEY,
6914 +                                        PK11_R_GETATTRIBUTVALUE, rv);
6915 +                       goto err;
6916 +                       }
6918 +               /*
6919 +                * We do not use pk11_get_private_rsa_key() here so we
6920 +                * must take care of handle management ourselves.
6921 +                */
6922 +               KEY_HANDLE_REFHOLD(ks_key, OP_RSA, TRUE, rollback, err);
6924 +               /*
6925 +                * Those are the sensitive components we do not want to export
6926 +                * from the token at all: rsa->(d|p|q|dmp1|dmq1|iqmp).
6927 +                */
6928 +               attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
6929 +               attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
6930 +               /*
6931 +                * Must have 'n'/'e' components in the session structure as
6932 +                * well. They serve as a public look-up key for the private key
6933 +                * in the keystore.
6934 +                */
6935 +               attr_to_BN(&get_templ[0], attr_data[0],
6936 +                       &sp->opdata_rsa_pn_num);
6937 +               attr_to_BN(&get_templ[1], attr_data[1],
6938 +                       &sp->opdata_rsa_pe_num);
6940 +               UNLOCK_OBJSTORE(OP_RSA);
6942 +               if ((pkey = EVP_PKEY_new()) == NULL)
6943 +                       goto err;
6945 +               if (EVP_PKEY_assign_RSA(pkey, rsa) == 0)
6946 +                       goto err;
6947 +               }
6948 +       else if ((privkey = fopen(privkey_file, read_mode_flags)) != NULL)
6949 +               {
6950 +               pkey = PEM_read_PrivateKey(privkey, NULL, NULL, NULL);
6951 +               (void) fclose(privkey);
6952 +               if (pkey != NULL)
6953 +                       {
6954 +                       rsa = EVP_PKEY_get1_RSA(pkey);
6955 +                       if (rsa != NULL)
6956 +                               {
6957 +                               /*
6958 +                                * This will always destroy the RSA
6959 +                                * object since we have a new RSA
6960 +                                * structure here.
6961 +                                */
6962 +                               (void) check_new_rsa_key_priv(sp, rsa);
6963 +                               sp->priv_persistent = CK_FALSE;
6965 +                               h_priv_key = sp->opdata_rsa_priv_key =
6966 +                                   pk11_get_private_rsa_key(rsa,
6967 +                                   &sp->opdata_rsa_priv,
6968 +                                   &sp->opdata_rsa_d_num,
6969 +                                   &sp->opdata_rsa_pn_num,
6970 +                                   &sp->opdata_rsa_pe_num, sp->session);
6971 +                               if (h_priv_key == CK_INVALID_HANDLE)
6972 +                                       goto err;
6973 +                               }
6974 +                       else
6975 +                               goto err;
6976 +                       }
6977 +               }
6979 +       pk11_return_session(sp, OP_RSA);
6980 +       return (pkey);
6981 +err:
6982 +       pk11_return_session(sp, OP_RSA);
6983 +       if (rsa != NULL)
6984 +               RSA_free(rsa);
6985 +       if (pkey != NULL)
6986 +               {
6987 +               EVP_PKEY_free(pkey);
6988 +               pkey = NULL;
6989 +               }
6990 +       rollback = rollback;
6991 +       return (pkey);
6992 +       }
6995 + * Load RSA public key from a file or get its PKCS#11 handle if stored in the
6996 + * PKCS#11 token.
6997 + */
6998 +/* ARGSUSED */
6999 +EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
7000 +       UI_METHOD *ui_method, void *callback_data)
7001 +       {
7002 +       EVP_PKEY *pkey = NULL;
7003 +       FILE *pubkey;
7004 +       CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
7005 +       RSA *rsa = NULL;
7006 +       PK11_SESSION *sp;
7007 +       /* Anything else below is needed for the key by reference extension. */
7008 +       CK_RV rv;
7009 +       CK_BBOOL is_token = TRUE;
7010 +       CK_BYTE attr_data[2][MAXATTR];
7011 +       CK_OBJECT_CLASS key_class = CKO_PUBLIC_KEY;
7012 +       CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;    /* key in keystore */
7014 +       /* we look for public keys only */
7015 +       CK_ATTRIBUTE search_templ[] =
7016 +               {
7017 +               {CKA_TOKEN, &is_token, sizeof(is_token)},
7018 +               {CKA_CLASS, &key_class, sizeof(key_class)},
7019 +               {CKA_LABEL, NULL, 0}
7020 +               };
7022 +       /*
7023 +        * These public attributes are needed to initialize OpenSSL RSA
7024 +        * structure with something we can use to look up the key.
7025 +        */
7026 +       CK_ATTRIBUTE get_templ[] =
7027 +               {
7028 +               {CKA_MODULUS, (void *)attr_data[0], MAXATTR},           /* n */
7029 +               {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},   /* e */
7030 +               };
7032 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
7033 +               return (NULL);
7035 +       /*
7036 +        * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
7037 +        */
7038 +       if (strstr(pubkey_file, "pkcs11:") == pubkey_file)
7039 +               {
7040 +               search_templ[2].pValue = strstr(pubkey_file, ":") + 1;
7041 +               search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
7043 +               if (pk11_token_login(sp->session, &pk11_login_done,
7044 +                   CK_FALSE) == 0)
7045 +                       goto err;
7047 +               /* see find_lock array definition
7048 +                  for more info on object locking */
7049 +               LOCK_OBJSTORE(OP_RSA);
7051 +               /*
7052 +                * Now let's try to find the key in the token. It is a failure
7053 +                * if we can't find it.
7054 +                */
7055 +               if (find_one_object(OP_RSA, sp->session, search_templ, 3,
7056 +                   &ks_key) == 0)
7057 +                       {
7058 +                       UNLOCK_OBJSTORE(OP_RSA);
7059 +                       goto err;
7060 +                       }
7062 +               /*
7063 +                * We load a new public key so we will create a new RSA
7064 +                * structure. No cache hit is possible.
7065 +                */
7066 +               (void) pk11_destroy_rsa_object_pub(sp, FALSE);
7068 +               sp->opdata_rsa_pub_key = ks_key;
7069 +               /* This object shall not be deleted on a cache miss. */
7070 +               sp->pub_persistent = CK_TRUE;
7072 +               /*
7073 +                * Cache the RSA public structure pointer.
7074 +                */
7075 +               if ((rsa = sp->opdata_rsa_pub = RSA_new_method(e)) == NULL)
7076 +                       {
7077 +                       UNLOCK_OBJSTORE(OP_RSA);
7078 +                       goto err;
7079 +                       }
7081 +               /*
7082 +                * Now we have to initialize an OpenSSL RSA structure,
7083 +                * everything else is 0 or NULL.
7084 +                */
7085 +               rsa->flags = RSA_FLAG_SIGN_VER;
7087 +               if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
7088 +                   get_templ, 2)) != CKR_OK)
7089 +                       {
7090 +                       UNLOCK_OBJSTORE(OP_RSA);
7091 +                       PK11err_add_data(PK11_F_LOAD_PUBKEY,
7092 +                                        PK11_R_GETATTRIBUTVALUE, rv);
7093 +                       goto err;
7094 +                       }
7096 +               attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
7097 +               attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
7099 +               UNLOCK_OBJSTORE(OP_RSA);
7101 +               if ((pkey = EVP_PKEY_new()) == NULL)
7102 +                       goto err;
7104 +               if (EVP_PKEY_assign_RSA(pkey, rsa) == 0)
7105 +                       goto err;
7107 +               /*
7108 +                * Create a session object from it so that when calling
7109 +                * pk11_get_public_rsa_key() the next time, we can find it. The
7110 +                * reason why we do that is that we cannot tell from the RSA
7111 +                * structure (OpenSSL RSA structure does not have any room for
7112 +                * additional data used by the engine, for example) if it bears
7113 +                * a public key stored in the keystore or not so it's better if
7114 +                * we always have a session key. Note that this is different
7115 +                * from what we do for the private keystore objects but in that
7116 +                * case, we can tell from the RSA structure that the keystore
7117 +                * object is in play - the 'd' component is NULL in that case.
7118 +                */
7119 +               h_pub_key = sp->opdata_rsa_pub_key =
7120 +                   pk11_get_public_rsa_key(rsa,
7121 +                   &sp->opdata_rsa_pub, &sp->opdata_rsa_n_num,
7122 +                   &sp->opdata_rsa_e_num, sp->session);
7123 +               if (h_pub_key == CK_INVALID_HANDLE)
7124 +                       goto err;
7125 +               }
7126 +       else if ((pubkey = fopen(pubkey_file, read_mode_flags)) != NULL)
7127 +               {
7128 +               pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL);
7129 +               (void) fclose(pubkey);
7130 +               if (pkey != NULL)
7131 +                       {
7132 +                       rsa = EVP_PKEY_get1_RSA(pkey);
7133 +                       if (rsa != NULL)
7134 +                               {
7135 +                               /*
7136 +                                * This will always destroy the RSA
7137 +                                * object since we have a new RSA
7138 +                                * structure here.
7139 +                                */
7140 +                               (void) check_new_rsa_key_pub(sp, rsa);
7141 +                               sp->pub_persistent = CK_FALSE;
7143 +                               h_pub_key = sp->opdata_rsa_pub_key =
7144 +                                   pk11_get_public_rsa_key(rsa,
7145 +                                   &sp->opdata_rsa_pub, &sp->opdata_rsa_n_num,
7146 +                                   &sp->opdata_rsa_e_num, sp->session);
7147 +                               if (h_pub_key == CK_INVALID_HANDLE)
7148 +                                       goto err;
7149 +                               }
7150 +                       else
7151 +                               goto err;
7152 +                       }
7153 +               }
7155 +       pk11_return_session(sp, OP_RSA);
7156 +       return (pkey);
7157 +err:
7158 +       pk11_return_session(sp, OP_RSA);
7159 +       if (rsa != NULL)
7160 +               RSA_free(rsa);
7161 +       if (pkey != NULL)
7162 +               {
7163 +               EVP_PKEY_free(pkey);
7164 +               pkey = NULL;
7165 +               }
7166 +       return (pkey);
7167 +       }
7170 + * Create a public key object in a session from a given rsa structure.
7171 + * The *rsa_n_num and *rsa_e_num pointers are non-NULL for RSA public keys.
7172 + */
7173 +static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA *rsa,
7174 +    RSA **key_ptr, BIGNUM **rsa_n_num, BIGNUM **rsa_e_num,
7175 +    CK_SESSION_HANDLE session)
7176 +       {
7177 +       CK_RV rv;
7178 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
7179 +       CK_ULONG found;
7180 +       CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
7181 +       CK_KEY_TYPE k_type = CKK_RSA;
7182 +       CK_ULONG ul_key_attr_count = 8;
7183 +       CK_BBOOL rollback = FALSE;
7185 +       CK_ATTRIBUTE  a_key_template[] =
7186 +               {
7187 +               {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
7188 +               {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
7189 +               {CKA_TOKEN, &myfalse, sizeof (myfalse)},
7190 +               {CKA_ENCRYPT, &mytrue, sizeof (mytrue)},
7191 +               {CKA_VERIFY, &mytrue, sizeof (mytrue)},
7192 +               {CKA_VERIFY_RECOVER, &mytrue, sizeof (mytrue)},
7193 +               {CKA_MODULUS, (void *)NULL, 0},
7194 +               {CKA_PUBLIC_EXPONENT, (void *)NULL, 0}
7195 +               };
7197 +       int i;
7199 +       a_key_template[0].pValue = &o_key;
7200 +       a_key_template[1].pValue = &k_type;
7202 +       a_key_template[6].ulValueLen = BN_num_bytes(rsa->n);
7203 +       a_key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
7204 +               (size_t)a_key_template[6].ulValueLen);
7205 +       if (a_key_template[6].pValue == NULL)
7206 +               {
7207 +               PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
7208 +               goto malloc_err;
7209 +               }
7211 +       BN_bn2bin(rsa->n, a_key_template[6].pValue);
7213 +       a_key_template[7].ulValueLen = BN_num_bytes(rsa->e);
7214 +       a_key_template[7].pValue = (CK_VOID_PTR)OPENSSL_malloc(
7215 +               (size_t)a_key_template[7].ulValueLen);
7216 +       if (a_key_template[7].pValue == NULL)
7217 +               {
7218 +               PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
7219 +               goto malloc_err;
7220 +               }
7222 +       BN_bn2bin(rsa->e, a_key_template[7].pValue);
7224 +       /* see find_lock array definition for more info on object locking */
7225 +       LOCK_OBJSTORE(OP_RSA);
7227 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template,
7228 +               ul_key_attr_count);
7230 +       if (rv != CKR_OK)
7231 +               {
7232 +               PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
7233 +                   PK11_R_FINDOBJECTSINIT, rv);
7234 +               goto err;
7235 +               }
7237 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
7239 +       if (rv != CKR_OK)
7240 +               {
7241 +               (void) pFuncList->C_FindObjectsFinal(session);
7242 +               PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
7243 +                   PK11_R_FINDOBJECTS, rv);
7244 +               goto err;
7245 +               }
7247 +       rv = pFuncList->C_FindObjectsFinal(session);
7249 +       if (rv != CKR_OK)
7250 +               {
7251 +               PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
7252 +                   PK11_R_FINDOBJECTSFINAL, rv);
7253 +               goto err;
7254 +               }
7256 +       if (found == 0)
7257 +               {
7258 +               rv = pFuncList->C_CreateObject(session,
7259 +                       a_key_template, ul_key_attr_count, &h_key);
7260 +               if (rv != CKR_OK)
7261 +                       {
7262 +                       PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
7263 +                           PK11_R_CREATEOBJECT, rv);
7264 +                       goto err;
7265 +                       }
7266 +               }
7268 +       if (rsa_n_num != NULL)
7269 +               if ((*rsa_n_num = BN_dup(rsa->n)) == NULL)
7270 +                       {
7271 +                       PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
7272 +                       rollback = TRUE;
7273 +                       goto err;
7274 +                       }
7275 +       if (rsa_e_num != NULL)
7276 +               if ((*rsa_e_num = BN_dup(rsa->e)) == NULL)
7277 +                       {
7278 +                       PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
7279 +                       BN_free(*rsa_n_num);
7280 +                       *rsa_n_num = NULL;
7281 +                       rollback = TRUE;
7282 +                       goto err;
7283 +                       }
7285 +       /* LINTED: E_CONSTANT_CONDITION */
7286 +       KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
7287 +       if (key_ptr != NULL)
7288 +               *key_ptr = rsa;
7290 +err:
7291 +       if (rollback)
7292 +               {
7293 +               /*
7294 +                * We do not care about the return value from C_DestroyObject()
7295 +                * since we are doing rollback.
7296 +                */
7297 +               if (found == 0)
7298 +                       (void) pFuncList->C_DestroyObject(session, h_key);
7299 +               h_key = CK_INVALID_HANDLE;
7300 +               }
7302 +       UNLOCK_OBJSTORE(OP_RSA);
7304 +malloc_err:
7305 +       for (i = 6; i <= 7; i++)
7306 +               {
7307 +               if (a_key_template[i].pValue != NULL)
7308 +                       {
7309 +                       OPENSSL_free(a_key_template[i].pValue);
7310 +                       a_key_template[i].pValue = NULL;
7311 +                       }
7312 +               }
7314 +       return (h_key);
7315 +       }
7318 + * Create a private key object in the session from a given rsa structure.
7319 + * The *rsa_d_num pointer is non-NULL for RSA private keys.
7320 + */
7321 +static CK_OBJECT_HANDLE
7322 +pk11_get_private_rsa_key(RSA *rsa, RSA **key_ptr, BIGNUM **rsa_d_num,
7323 +    BIGNUM **rsa_n_num, BIGNUM **rsa_e_num, CK_SESSION_HANDLE session)
7324 +       {
7325 +       CK_RV rv;
7326 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
7327 +       int i;
7328 +       CK_ULONG found;
7329 +       CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
7330 +       CK_KEY_TYPE k_type = CKK_RSA;
7331 +       CK_ULONG ul_key_attr_count = 14;
7332 +       CK_BBOOL rollback = FALSE;
7334 +       /* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys */
7335 +       CK_ATTRIBUTE  a_key_template[] =
7336 +               {
7337 +               {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
7338 +               {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
7339 +               {CKA_TOKEN, &myfalse, sizeof (myfalse)},
7340 +               {CKA_SENSITIVE, &myfalse, sizeof (myfalse)},
7341 +               {CKA_DECRYPT, &mytrue, sizeof (mytrue)},
7342 +               {CKA_SIGN, &mytrue, sizeof (mytrue)},
7343 +               {CKA_MODULUS, (void *)NULL, 0},
7344 +               {CKA_PUBLIC_EXPONENT, (void *)NULL, 0},
7345 +               {CKA_PRIVATE_EXPONENT, (void *)NULL, 0},
7346 +               {CKA_PRIME_1, (void *)NULL, 0},
7347 +               {CKA_PRIME_2, (void *)NULL, 0},
7348 +               {CKA_EXPONENT_1, (void *)NULL, 0},
7349 +               {CKA_EXPONENT_2, (void *)NULL, 0},
7350 +               {CKA_COEFFICIENT, (void *)NULL, 0},
7351 +               };
7353 +       if ((rsa->flags & RSA_FLAG_EXT_PKEY) != 0) {
7354 +               h_key = (CK_OBJECT_HANDLE)RSA_get_ex_data(rsa, hndidx_rsa);
7355 +               LOCK_OBJSTORE(OP_RSA);
7356 +               goto set;
7357 +       }
7358 +       
7359 +       a_key_template[0].pValue = &o_key;
7360 +       a_key_template[1].pValue = &k_type;
7362 +       /* Put the private key components into the template */
7363 +       if (init_template_value(rsa->n, &a_key_template[6].pValue,
7364 +               &a_key_template[6].ulValueLen) == 0 ||
7365 +           init_template_value(rsa->e, &a_key_template[7].pValue,
7366 +               &a_key_template[7].ulValueLen) == 0 ||
7367 +           init_template_value(rsa->d, &a_key_template[8].pValue,
7368 +               &a_key_template[8].ulValueLen) == 0 ||
7369 +           init_template_value(rsa->p, &a_key_template[9].pValue,
7370 +               &a_key_template[9].ulValueLen) == 0 ||
7371 +           init_template_value(rsa->q, &a_key_template[10].pValue,
7372 +               &a_key_template[10].ulValueLen) == 0 ||
7373 +           init_template_value(rsa->dmp1, &a_key_template[11].pValue,
7374 +               &a_key_template[11].ulValueLen) == 0 ||
7375 +           init_template_value(rsa->dmq1, &a_key_template[12].pValue,
7376 +               &a_key_template[12].ulValueLen) == 0 ||
7377 +           init_template_value(rsa->iqmp, &a_key_template[13].pValue,
7378 +               &a_key_template[13].ulValueLen) == 0)
7379 +               {
7380 +               PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
7381 +               goto malloc_err;
7382 +               }
7384 +       /* see find_lock array definition for more info on object locking */
7385 +       LOCK_OBJSTORE(OP_RSA);
7387 +       /*
7388 +        * We are getting the private key but the private 'd'
7389 +        * component is NULL.  That means this is key by reference RSA
7390 +        * key. In that case, we can use only public components for
7391 +        * searching for the private key handle.
7392 +        */
7393 +       if (rsa->d == NULL)
7394 +               {
7395 +               ul_key_attr_count = 8;
7396 +               /*
7397 +                * We will perform the search in the token, not in the existing
7398 +                * session keys.
7399 +                */
7400 +               a_key_template[2].pValue = &mytrue;
7401 +               }
7403 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template,
7404 +               ul_key_attr_count);
7406 +       if (rv != CKR_OK)
7407 +               {
7408 +               PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7409 +                   PK11_R_FINDOBJECTSINIT, rv);
7410 +               goto err;
7411 +               }
7413 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
7415 +       if (rv != CKR_OK)
7416 +               {
7417 +               (void) pFuncList->C_FindObjectsFinal(session);
7418 +               PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7419 +                   PK11_R_FINDOBJECTS, rv);
7420 +               goto err;
7421 +               }
7423 +       rv = pFuncList->C_FindObjectsFinal(session);
7425 +       if (rv != CKR_OK)
7426 +               {
7427 +               PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7428 +                   PK11_R_FINDOBJECTSFINAL, rv);
7429 +               goto err;
7430 +               }
7432 +       if (found == 0)
7433 +               {
7434 +               /*
7435 +                * We have an RSA structure with 'n'/'e' components
7436 +                * only so we tried to find the private key in the
7437 +                * keystore. If it was really a token key we have a
7438 +                * problem. Note that for other key types we just
7439 +                * create a new session key using the private
7440 +                * components from the RSA structure.
7441 +                */
7442 +               if (rsa->d == NULL)
7443 +                       {
7444 +                       PK11err(PK11_F_GET_PRIV_RSA_KEY,
7445 +                           PK11_R_PRIV_KEY_NOT_FOUND);
7446 +                       goto err;
7447 +                       }
7449 +               rv = pFuncList->C_CreateObject(session,
7450 +                       a_key_template, ul_key_attr_count, &h_key);
7451 +               if (rv != CKR_OK)
7452 +                       {
7453 +                       PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7454 +                               PK11_R_CREATEOBJECT, rv);
7455 +                       goto err;
7456 +                       }
7457 +               }
7459 +set:
7460 +       if (rsa_d_num != NULL)
7461 +               {
7462 +               /*
7463 +                * When RSA keys by reference code is used, we never
7464 +                * extract private components from the keystore. In
7465 +                * that case 'd' was set to NULL and we expect the
7466 +                * application to properly cope with that. It is
7467 +                * documented in openssl(5). In general, if keys by
7468 +                * reference are used we expect it to be used
7469 +                * exclusively using the high level API and then there
7470 +                * is no problem. If the application expects the
7471 +                * private components to be read from the keystore
7472 +                * then that is not a supported way of usage.
7473 +                */
7474 +               if (rsa->d != NULL && (*rsa_d_num = BN_dup(rsa->d)) == NULL)
7475 +                       {
7476 +                       PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
7477 +                       rollback = TRUE;
7478 +                       goto err;
7479 +                       }
7480 +               else
7481 +                       *rsa_d_num = NULL;
7482 +               }
7484 +       /*
7485 +        * For the key by reference code, we need public components as well
7486 +        * since 'd' component is always NULL. For that reason, we always cache
7487 +        * 'n'/'e' components as well.
7488 +        */
7489 +       *rsa_n_num = BN_dup(rsa->n);
7490 +       *rsa_e_num = BN_dup(rsa->e);
7492 +       /* LINTED: E_CONSTANT_CONDITION */
7493 +       KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
7494 +       if (key_ptr != NULL)
7495 +               *key_ptr = rsa;
7497 +err:
7498 +       if (rollback)
7499 +               {
7500 +               /*
7501 +                * We do not care about the return value from C_DestroyObject()
7502 +                * since we are doing rollback.
7503 +                */
7504 +               if (found == 0 &&
7505 +                   (rsa->flags & RSA_FLAG_EXT_PKEY) == 0)
7506 +                       (void) pFuncList->C_DestroyObject(session, h_key);
7507 +               h_key = CK_INVALID_HANDLE;
7508 +               }
7510 +       UNLOCK_OBJSTORE(OP_RSA);
7512 +malloc_err:
7513 +       /*
7514 +        * 6 to 13 entries in the key template are key components.
7515 +        * They need to be freed upon exit or error.
7516 +        */
7517 +       for (i = 6; i <= 13; i++)
7518 +               {
7519 +               if (a_key_template[i].pValue != NULL)
7520 +                       {
7521 +                       (void) memset(a_key_template[i].pValue, 0,
7522 +                               a_key_template[i].ulValueLen);
7523 +                       OPENSSL_free(a_key_template[i].pValue);
7524 +                       a_key_template[i].pValue = NULL;
7525 +                       }
7526 +               }
7528 +       return (h_key);
7529 +       }
7532 + * Check for cache miss and clean the object pointer and handle
7533 + * in such case. Return 1 for cache hit, 0 for cache miss.
7534 + */
7535 +static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa)
7536 +       {
7537 +       /*
7538 +        * Provide protection against RSA structure reuse by making the
7539 +        * check for cache hit stronger. Only public components of RSA
7540 +        * key matter here so it is sufficient to compare them with values
7541 +        * cached in PK11_SESSION structure.
7542 +        *
7543 +        * We must check the handle as well since with key by reference, public
7544 +        * components 'n'/'e' are cached in private keys as well. That means we
7545 +        * could have a cache hit in a private key when looking for a public
7546 +        * key. That would not work, you cannot have one PKCS#11 object for
7547 +        * both data signing and verifying.
7548 +        */
7549 +       if ((sp->opdata_rsa_pub != rsa) ||
7550 +           (BN_cmp(sp->opdata_rsa_n_num, rsa->n) != 0) ||
7551 +           (BN_cmp(sp->opdata_rsa_e_num, rsa->e) != 0) ||
7552 +           (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE))
7553 +               {
7554 +               /*
7555 +                * We do not check the return value because even in case of
7556 +                * failure the sp structure will have both key pointer
7557 +                * and object handle cleaned and pk11_destroy_object()
7558 +                * reports the failure to the OpenSSL error message buffer.
7559 +                */
7560 +               (void) pk11_destroy_rsa_object_pub(sp, TRUE);
7561 +               return (0);
7562 +               }
7563 +       return (1);
7564 +       }
7567 + * Check for cache miss and clean the object pointer and handle
7568 + * in such case. Return 1 for cache hit, 0 for cache miss.
7569 + */
7570 +static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa)
7571 +       {
7572 +       /*
7573 +        * Provide protection against RSA structure reuse by making
7574 +        * the check for cache hit stronger. Comparing public exponent
7575 +        * of RSA key with value cached in PK11_SESSION structure
7576 +        * should be sufficient. Note that we want to compare the
7577 +        * public component since with the keys by reference
7578 +        * mechanism, private components are not in the RSA
7579 +        * structure. Also, see check_new_rsa_key_pub() about why we
7580 +        * compare the handle as well.
7581 +        */
7582 +       if ((sp->opdata_rsa_priv != rsa) ||
7583 +           (BN_cmp(sp->opdata_rsa_pn_num, rsa->n) != 0) ||
7584 +           (BN_cmp(sp->opdata_rsa_pe_num, rsa->e) != 0) ||
7585 +           (sp->opdata_rsa_pn_num == NULL) ||
7586 +           (sp->opdata_rsa_pe_num == NULL) ||
7587 +           (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE))
7588 +               {
7589 +               /*
7590 +                * We do not check the return value because even in case of
7591 +                * failure the sp structure will have both key pointer
7592 +                * and object handle cleaned and pk11_destroy_object()
7593 +                * reports the failure to the OpenSSL error message buffer.
7594 +                */
7595 +               (void) pk11_destroy_rsa_object_priv(sp, TRUE);
7596 +               return (0);
7597 +               }
7598 +       return (1);
7599 +       }
7600 +#endif
7602 +#ifndef OPENSSL_NO_DSA
7603 +/* The DSA function implementation */
7604 +/* ARGSUSED */
7605 +static int pk11_DSA_init(DSA *dsa)
7606 +       {
7607 +       return (1);
7608 +       }
7610 +/* ARGSUSED */
7611 +static int pk11_DSA_finish(DSA *dsa)
7612 +       {
7613 +       return (1);
7614 +       }
7617 +static DSA_SIG *
7618 +pk11_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
7619 +       {
7620 +       BIGNUM *r = NULL, *s = NULL;
7621 +       int i;
7622 +       DSA_SIG *dsa_sig = NULL;
7624 +       CK_RV rv;
7625 +       CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
7626 +       CK_MECHANISM *p_mech = &Mechanism_dsa;
7627 +       CK_OBJECT_HANDLE h_priv_key;
7629 +       /*
7630 +        * The signature is the concatenation of r and s,
7631 +        * each is 20 bytes long
7632 +        */
7633 +       unsigned char sigret[DSA_SIGNATURE_LEN];
7634 +       unsigned long siglen = DSA_SIGNATURE_LEN;
7635 +       unsigned int siglen2 = DSA_SIGNATURE_LEN / 2;
7637 +       PK11_SESSION *sp = NULL;
7639 +       if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
7640 +               {
7641 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MISSING_KEY_COMPONENT);
7642 +               goto ret;
7643 +               }
7645 +       i = BN_num_bytes(dsa->q); /* should be 20 */
7646 +       if (dlen > i)
7647 +               {
7648 +               PK11err(PK11_F_DSA_SIGN, PK11_R_INVALID_SIGNATURE_LENGTH);
7649 +               goto ret;
7650 +               }
7652 +       if ((sp = pk11_get_session(OP_DSA)) == NULL)
7653 +               goto ret;
7655 +       (void) check_new_dsa_key_priv(sp, dsa);
7657 +       h_priv_key = sp->opdata_dsa_priv_key;
7658 +       if (h_priv_key == CK_INVALID_HANDLE)
7659 +               h_priv_key = sp->opdata_dsa_priv_key =
7660 +                       pk11_get_private_dsa_key((DSA *)dsa,
7661 +                           &sp->opdata_dsa_priv,
7662 +                           &sp->opdata_dsa_priv_num, sp->session);
7664 +       if (h_priv_key != CK_INVALID_HANDLE)
7665 +               {
7666 +               rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
7668 +               if (rv != CKR_OK)
7669 +                       {
7670 +                       PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGNINIT, rv);
7671 +                       goto ret;
7672 +                       }
7674 +               (void) memset(sigret, 0, siglen);
7675 +               rv = pFuncList->C_Sign(sp->session,
7676 +                       (unsigned char*) dgst, dlen, sigret,
7677 +                       (CK_ULONG_PTR) &siglen);
7679 +               if (rv != CKR_OK)
7680 +                       {
7681 +                       PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGN, rv);
7682 +                       goto ret;
7683 +                       }
7684 +               }
7687 +       if ((s = BN_new()) == NULL)
7688 +               {
7689 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7690 +               goto ret;
7691 +               }
7693 +       if ((r = BN_new()) == NULL)
7694 +               {
7695 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7696 +               goto ret;
7697 +               }
7699 +       if ((dsa_sig = DSA_SIG_new()) == NULL)
7700 +               {
7701 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7702 +               goto ret;
7703 +               }
7705 +       if (BN_bin2bn(sigret, siglen2, r) == NULL ||
7706 +           BN_bin2bn(&sigret[siglen2], siglen2, s) == NULL)
7707 +               {
7708 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7709 +               goto ret;
7710 +               }
7712 +       dsa_sig->r = r;
7713 +       dsa_sig->s = s;
7715 +ret:
7716 +       if (dsa_sig == NULL)
7717 +               {
7718 +               if (r != NULL)
7719 +                       BN_free(r);
7720 +               if (s != NULL)
7721 +                       BN_free(s);
7722 +               }
7724 +       pk11_return_session(sp, OP_DSA);
7725 +       return (dsa_sig);
7726 +       }
7728 +static int
7729 +pk11_dsa_do_verify(const unsigned char *dgst, int dlen, DSA_SIG *sig,
7730 +       DSA *dsa)
7731 +       {
7732 +       int i;
7733 +       CK_RV rv;
7734 +       int retval = 0;
7735 +       CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
7736 +       CK_MECHANISM *p_mech = &Mechanism_dsa;
7737 +       CK_OBJECT_HANDLE h_pub_key;
7739 +       unsigned char sigbuf[DSA_SIGNATURE_LEN];
7740 +       unsigned long siglen = DSA_SIGNATURE_LEN;
7741 +       unsigned long siglen2 = DSA_SIGNATURE_LEN/2;
7743 +       PK11_SESSION *sp = NULL;
7745 +       if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0)
7746 +               {
7747 +               PK11err(PK11_F_DSA_VERIFY,
7748 +                       PK11_R_INVALID_DSA_SIGNATURE_R);
7749 +               goto ret;
7750 +               }
7752 +       if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0)
7753 +               {
7754 +               PK11err(PK11_F_DSA_VERIFY,
7755 +                       PK11_R_INVALID_DSA_SIGNATURE_S);
7756 +               goto ret;
7757 +               }
7759 +       i = BN_num_bytes(dsa->q); /* should be 20 */
7761 +       if (dlen > i)
7762 +               {
7763 +               PK11err(PK11_F_DSA_VERIFY,
7764 +                       PK11_R_INVALID_SIGNATURE_LENGTH);
7765 +               goto ret;
7766 +               }
7768 +       if ((sp = pk11_get_session(OP_DSA)) == NULL)
7769 +               goto ret;
7771 +       (void) check_new_dsa_key_pub(sp, dsa);
7773 +       h_pub_key = sp->opdata_dsa_pub_key;
7774 +       if (h_pub_key == CK_INVALID_HANDLE)
7775 +               h_pub_key = sp->opdata_dsa_pub_key =
7776 +                       pk11_get_public_dsa_key((DSA *)dsa, &sp->opdata_dsa_pub,
7777 +                           &sp->opdata_dsa_pub_num, sp->session);
7779 +       if (h_pub_key != CK_INVALID_HANDLE)
7780 +               {
7781 +               rv = pFuncList->C_VerifyInit(sp->session, p_mech,
7782 +                       h_pub_key);
7784 +               if (rv != CKR_OK)
7785 +                       {
7786 +                       PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFYINIT,
7787 +                           rv);
7788 +                       goto ret;
7789 +                       }
7791 +               /*
7792 +                * The representation of each of the two big numbers could
7793 +                * be shorter than DSA_SIGNATURE_LEN/2 bytes so we need
7794 +                * to act accordingly and shift if necessary.
7795 +                */
7796 +               (void) memset(sigbuf, 0, siglen);
7797 +               BN_bn2bin(sig->r, sigbuf + siglen2 - BN_num_bytes(sig->r));
7798 +               BN_bn2bin(sig->s, &sigbuf[siglen2] + siglen2 -
7799 +                   BN_num_bytes(sig->s));
7801 +               rv = pFuncList->C_Verify(sp->session,
7802 +                       (unsigned char *) dgst, dlen, sigbuf, (CK_ULONG)siglen);
7804 +               if (rv != CKR_OK)
7805 +                       {
7806 +                       PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFY, rv);
7807 +                       goto ret;
7808 +                       }
7809 +               }
7811 +       retval = 1;
7812 +ret:
7814 +       pk11_return_session(sp, OP_DSA);
7815 +       return (retval);
7816 +       }
7820 + * Create a public key object in a session from a given dsa structure.
7821 + * The *dsa_pub_num pointer is non-NULL for DSA public keys.
7822 + */
7823 +static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa,
7824 +    DSA **key_ptr, BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session)
7825 +       {
7826 +       CK_RV rv;
7827 +       CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
7828 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
7829 +       CK_ULONG found;
7830 +       CK_KEY_TYPE k_type = CKK_DSA;
7831 +       CK_ULONG ul_key_attr_count = 8;
7832 +       CK_BBOOL rollback = FALSE;
7833 +       int i;
7835 +       CK_ATTRIBUTE  a_key_template[] =
7836 +               {
7837 +               {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
7838 +               {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
7839 +               {CKA_TOKEN, &myfalse, sizeof (myfalse)},
7840 +               {CKA_VERIFY, &mytrue, sizeof (mytrue)},
7841 +               {CKA_PRIME, (void *)NULL, 0},           /* p */
7842 +               {CKA_SUBPRIME, (void *)NULL, 0},        /* q */
7843 +               {CKA_BASE, (void *)NULL, 0},            /* g */
7844 +               {CKA_VALUE, (void *)NULL, 0}            /* pub_key - y */
7845 +               };
7847 +       a_key_template[0].pValue = &o_key;
7848 +       a_key_template[1].pValue = &k_type;
7850 +       if (init_template_value(dsa->p, &a_key_template[4].pValue,
7851 +               &a_key_template[4].ulValueLen) == 0 ||
7852 +           init_template_value(dsa->q, &a_key_template[5].pValue,
7853 +               &a_key_template[5].ulValueLen) == 0 ||
7854 +           init_template_value(dsa->g, &a_key_template[6].pValue,
7855 +               &a_key_template[6].ulValueLen) == 0 ||
7856 +           init_template_value(dsa->pub_key, &a_key_template[7].pValue,
7857 +               &a_key_template[7].ulValueLen) == 0)
7858 +               {
7859 +               PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
7860 +               goto malloc_err;
7861 +               }
7863 +       /* see find_lock array definition for more info on object locking */
7864 +       LOCK_OBJSTORE(OP_DSA);
7865 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template,
7866 +               ul_key_attr_count);
7868 +       if (rv != CKR_OK)
7869 +               {
7870 +               PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
7871 +                   PK11_R_FINDOBJECTSINIT, rv);
7872 +               goto err;
7873 +               }
7875 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
7877 +       if (rv != CKR_OK)
7878 +               {
7879 +               (void) pFuncList->C_FindObjectsFinal(session);
7880 +               PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
7881 +                   PK11_R_FINDOBJECTS, rv);
7882 +               goto err;
7883 +               }
7885 +       rv = pFuncList->C_FindObjectsFinal(session);
7887 +       if (rv != CKR_OK)
7888 +               {
7889 +               PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
7890 +                   PK11_R_FINDOBJECTSFINAL, rv);
7891 +               goto err;
7892 +               }
7894 +       if (found == 0)
7895 +               {
7896 +               rv = pFuncList->C_CreateObject(session,
7897 +                       a_key_template, ul_key_attr_count, &h_key);
7898 +               if (rv != CKR_OK)
7899 +                       {
7900 +                       PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
7901 +                           PK11_R_CREATEOBJECT, rv);
7902 +                       goto err;
7903 +                       }
7904 +               }
7906 +       if (dsa_pub_num != NULL)
7907 +               if ((*dsa_pub_num = BN_dup(dsa->pub_key)) == NULL)
7908 +                       {
7909 +                       PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
7910 +                       rollback = TRUE;
7911 +                       goto err;
7912 +                       }
7914 +       /* LINTED: E_CONSTANT_CONDITION */
7915 +       KEY_HANDLE_REFHOLD(h_key, OP_DSA, FALSE, rollback, err);
7916 +       if (key_ptr != NULL)
7917 +               *key_ptr = dsa;
7919 +err:
7920 +       if (rollback)
7921 +               {
7922 +               /*
7923 +                * We do not care about the return value from C_DestroyObject()
7924 +                * since we are doing rollback.
7925 +                */
7926 +               if (found == 0)
7927 +                       (void) pFuncList->C_DestroyObject(session, h_key);
7928 +               h_key = CK_INVALID_HANDLE;
7929 +               }
7931 +       UNLOCK_OBJSTORE(OP_DSA);
7933 +malloc_err:
7934 +       for (i = 4; i <= 7; i++)
7935 +               {
7936 +               if (a_key_template[i].pValue != NULL)
7937 +                       {
7938 +                       OPENSSL_free(a_key_template[i].pValue);
7939 +                       a_key_template[i].pValue = NULL;
7940 +                       }
7941 +               }
7943 +       return (h_key);
7944 +       }
7947 + * Create a private key object in the session from a given dsa structure
7948 + * The *dsa_priv_num pointer is non-NULL for DSA private keys.
7949 + */
7950 +static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa,
7951 +    DSA **key_ptr, BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session)
7952 +       {
7953 +       CK_RV rv;
7954 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
7955 +       CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
7956 +       int i;
7957 +       CK_ULONG found;
7958 +       CK_KEY_TYPE k_type = CKK_DSA;
7959 +       CK_ULONG ul_key_attr_count = 9;
7960 +       CK_BBOOL rollback = FALSE;
7962 +       /* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys */
7963 +       CK_ATTRIBUTE  a_key_template[] =
7964 +               {
7965 +               {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
7966 +               {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
7967 +               {CKA_TOKEN, &myfalse, sizeof (myfalse)},
7968 +               {CKA_SENSITIVE, &myfalse, sizeof (myfalse)},
7969 +               {CKA_SIGN, &mytrue, sizeof (mytrue)},
7970 +               {CKA_PRIME, (void *)NULL, 0},           /* p */
7971 +               {CKA_SUBPRIME, (void *)NULL, 0},        /* q */
7972 +               {CKA_BASE, (void *)NULL, 0},            /* g */
7973 +               {CKA_VALUE, (void *)NULL, 0}            /* priv_key - x */
7974 +               };
7976 +       a_key_template[0].pValue = &o_key;
7977 +       a_key_template[1].pValue = &k_type;
7979 +       /* Put the private key components into the template */
7980 +       if (init_template_value(dsa->p, &a_key_template[5].pValue,
7981 +               &a_key_template[5].ulValueLen) == 0 ||
7982 +           init_template_value(dsa->q, &a_key_template[6].pValue,
7983 +               &a_key_template[6].ulValueLen) == 0 ||
7984 +           init_template_value(dsa->g, &a_key_template[7].pValue,
7985 +               &a_key_template[7].ulValueLen) == 0 ||
7986 +           init_template_value(dsa->priv_key, &a_key_template[8].pValue,
7987 +               &a_key_template[8].ulValueLen) == 0)
7988 +               {
7989 +               PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
7990 +               goto malloc_err;
7991 +               }
7993 +       /* see find_lock array definition for more info on object locking */
7994 +       LOCK_OBJSTORE(OP_DSA);
7995 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template,
7996 +               ul_key_attr_count);
7998 +       if (rv != CKR_OK)
7999 +               {
8000 +               PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
8001 +                   PK11_R_FINDOBJECTSINIT, rv);
8002 +               goto err;
8003 +               }
8005 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
8007 +       if (rv != CKR_OK)
8008 +               {
8009 +               (void) pFuncList->C_FindObjectsFinal(session);
8010 +               PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
8011 +                   PK11_R_FINDOBJECTS, rv);
8012 +               goto err;
8013 +               }
8015 +       rv = pFuncList->C_FindObjectsFinal(session);
8017 +       if (rv != CKR_OK)
8018 +               {
8019 +               PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
8020 +                   PK11_R_FINDOBJECTSFINAL, rv);
8021 +               goto err;
8022 +               }
8024 +       if (found == 0)
8025 +               {
8026 +               rv = pFuncList->C_CreateObject(session,
8027 +                       a_key_template, ul_key_attr_count, &h_key);
8028 +               if (rv != CKR_OK)
8029 +                       {
8030 +                       PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
8031 +                           PK11_R_CREATEOBJECT, rv);
8032 +                       goto err;
8033 +                       }
8034 +               }
8036 +       if (dsa_priv_num != NULL)
8037 +               if ((*dsa_priv_num = BN_dup(dsa->priv_key)) == NULL)
8038 +                       {
8039 +                       PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
8040 +                       rollback = TRUE;
8041 +                       goto err;
8042 +                       }
8044 +       /* LINTED: E_CONSTANT_CONDITION */
8045 +       KEY_HANDLE_REFHOLD(h_key, OP_DSA, FALSE, rollback, err);
8046 +       if (key_ptr != NULL)
8047 +               *key_ptr = dsa;
8049 +err:
8050 +       if (rollback)
8051 +               {
8052 +               /*
8053 +                * We do not care about the return value from C_DestroyObject()
8054 +                * since we are doing rollback.
8055 +                */
8056 +               if (found == 0)
8057 +                       (void) pFuncList->C_DestroyObject(session, h_key);
8058 +               h_key = CK_INVALID_HANDLE;
8059 +               }
8061 +       UNLOCK_OBJSTORE(OP_DSA);
8063 +malloc_err:
8064 +       /*
8065 +        * 5 to 8 entries in the key template are key components.
8066 +        * They need to be freed apon exit or error.
8067 +        */
8068 +       for (i = 5; i <= 8; i++)
8069 +               {
8070 +               if (a_key_template[i].pValue != NULL)
8071 +                       {
8072 +                       (void) memset(a_key_template[i].pValue, 0,
8073 +                               a_key_template[i].ulValueLen);
8074 +                       OPENSSL_free(a_key_template[i].pValue);
8075 +                       a_key_template[i].pValue = NULL;
8076 +                       }
8077 +               }
8079 +       return (h_key);
8080 +       }
8083 + * Check for cache miss and clean the object pointer and handle
8084 + * in such case. Return 1 for cache hit, 0 for cache miss.
8085 + */
8086 +static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa)
8087 +       {
8088 +       /*
8089 +        * Provide protection against DSA structure reuse by making the
8090 +        * check for cache hit stronger. Only public key component of DSA
8091 +        * key matters here so it is sufficient to compare it with value
8092 +        * cached in PK11_SESSION structure.
8093 +        */
8094 +       if ((sp->opdata_dsa_pub != dsa) ||
8095 +           (BN_cmp(sp->opdata_dsa_pub_num, dsa->pub_key) != 0))
8096 +               {
8097 +               /*
8098 +                * We do not check the return value because even in case of
8099 +                * failure the sp structure will have both key pointer
8100 +                * and object handle cleaned and pk11_destroy_object()
8101 +                * reports the failure to the OpenSSL error message buffer.
8102 +                */
8103 +               (void) pk11_destroy_dsa_object_pub(sp, TRUE);
8104 +               return (0);
8105 +               }
8106 +       return (1);
8107 +       }
8110 + * Check for cache miss and clean the object pointer and handle
8111 + * in such case. Return 1 for cache hit, 0 for cache miss.
8112 + */
8113 +static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa)
8114 +       {
8115 +       /*
8116 +        * Provide protection against DSA structure reuse by making the
8117 +        * check for cache hit stronger. Only private key component of DSA
8118 +        * key matters here so it is sufficient to compare it with value
8119 +        * cached in PK11_SESSION structure.
8120 +        */
8121 +       if ((sp->opdata_dsa_priv != dsa) ||
8122 +           (BN_cmp(sp->opdata_dsa_priv_num, dsa->priv_key) != 0))
8123 +               {
8124 +               /*
8125 +                * We do not check the return value because even in case of
8126 +                * failure the sp structure will have both key pointer
8127 +                * and object handle cleaned and pk11_destroy_object()
8128 +                * reports the failure to the OpenSSL error message buffer.
8129 +                */
8130 +               (void) pk11_destroy_dsa_object_priv(sp, TRUE);
8131 +               return (0);
8132 +               }
8133 +       return (1);
8134 +       }
8135 +#endif
8138 +#ifndef OPENSSL_NO_DH
8139 +/* The DH function implementation */
8140 +/* ARGSUSED */
8141 +static int pk11_DH_init(DH *dh)
8142 +       {
8143 +       return (1);
8144 +       }
8146 +/* ARGSUSED */
8147 +static int pk11_DH_finish(DH *dh)
8148 +       {
8149 +       return (1);
8150 +       }
8153 + * Generate DH key-pair.
8154 + *
8155 + * Warning: Unlike OpenSSL's DH_generate_key(3) we ignore dh->priv_key
8156 + * and override it even if it is set. OpenSSL does not touch dh->priv_key
8157 + * if set and just computes dh->pub_key. It looks like PKCS#11 standard
8158 + * is not capable of providing this functionality. This could be a problem
8159 + * for applications relying on OpenSSL's semantics.
8160 + */
8161 +static int pk11_DH_generate_key(DH *dh)
8162 +       {
8163 +       CK_ULONG i;
8164 +       CK_RV rv, rv1;
8165 +       int reuse_mem_len = 0, ret = 0;
8166 +       PK11_SESSION *sp = NULL;
8167 +       CK_BYTE_PTR reuse_mem;
8169 +       CK_MECHANISM mechanism = {CKM_DH_PKCS_KEY_PAIR_GEN, NULL_PTR, 0};
8170 +       CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
8171 +       CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
8173 +       CK_ULONG ul_pub_key_attr_count = 3;
8174 +       CK_ATTRIBUTE pub_key_template[] =
8175 +               {
8176 +               {CKA_PRIVATE, &myfalse, sizeof (myfalse)},
8177 +               {CKA_PRIME, (void *)NULL, 0},
8178 +               {CKA_BASE, (void *)NULL, 0}
8179 +               };
8181 +       CK_ULONG ul_priv_key_attr_count = 3;
8182 +       CK_ATTRIBUTE priv_key_template[] =
8183 +               {
8184 +               {CKA_PRIVATE, &myfalse, sizeof (myfalse)},
8185 +               {CKA_SENSITIVE, &myfalse, sizeof (myfalse)},
8186 +               {CKA_DERIVE, &mytrue, sizeof (mytrue)}
8187 +               };
8189 +       CK_ULONG pub_key_attr_result_count = 1;
8190 +       CK_ATTRIBUTE pub_key_result[] =
8191 +               {
8192 +               {CKA_VALUE, (void *)NULL, 0}
8193 +               };
8195 +       CK_ULONG priv_key_attr_result_count = 1;
8196 +       CK_ATTRIBUTE priv_key_result[] =
8197 +               {
8198 +               {CKA_VALUE, (void *)NULL, 0}
8199 +               };
8201 +       pub_key_template[1].ulValueLen = BN_num_bytes(dh->p);
8202 +       if (pub_key_template[1].ulValueLen > 0)
8203 +               {
8204 +               /*
8205 +                * We must not increase ulValueLen by DH_BUF_RESERVE since that
8206 +                * could cause the same rounding problem. See definition of
8207 +                * DH_BUF_RESERVE above.
8208 +                */
8209 +               pub_key_template[1].pValue =
8210 +                       OPENSSL_malloc(pub_key_template[1].ulValueLen +
8211 +                       DH_BUF_RESERVE);
8212 +               if (pub_key_template[1].pValue == NULL)
8213 +                       {
8214 +                       PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
8215 +                       goto err;
8216 +                       }
8218 +               i = BN_bn2bin(dh->p, pub_key_template[1].pValue);
8219 +               }
8220 +       else
8221 +               goto err;
8223 +       pub_key_template[2].ulValueLen = BN_num_bytes(dh->g);
8224 +       if (pub_key_template[2].ulValueLen > 0)
8225 +               {
8226 +               pub_key_template[2].pValue =
8227 +                       OPENSSL_malloc(pub_key_template[2].ulValueLen +
8228 +                       DH_BUF_RESERVE);
8229 +               if (pub_key_template[2].pValue == NULL)
8230 +                       {
8231 +                       PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
8232 +                       goto err;
8233 +                       }
8235 +               i = BN_bn2bin(dh->g, pub_key_template[2].pValue);
8236 +               }
8237 +       else
8238 +               goto err;
8240 +       /*
8241 +        * Note: we are only using PK11_SESSION structure for getting
8242 +        *       a session handle. The objects created in this function are
8243 +        *       destroyed before return and thus not cached.
8244 +        */
8245 +       if ((sp = pk11_get_session(OP_DH)) == NULL)
8246 +               goto err;
8248 +       rv = pFuncList->C_GenerateKeyPair(sp->session,
8249 +           &mechanism,
8250 +           pub_key_template,
8251 +           ul_pub_key_attr_count,
8252 +           priv_key_template,
8253 +           ul_priv_key_attr_count,
8254 +           &h_pub_key,
8255 +           &h_priv_key);
8256 +       if (rv != CKR_OK)
8257 +               {
8258 +               PK11err_add_data(PK11_F_DH_GEN_KEY, PK11_R_GEN_KEY, rv);
8259 +               goto err;
8260 +               }
8262 +       /*
8263 +        * Reuse the larger memory allocated. We know the larger memory
8264 +        * should be sufficient for reuse.
8265 +        */
8266 +       if (pub_key_template[1].ulValueLen > pub_key_template[2].ulValueLen)
8267 +               {
8268 +               reuse_mem = pub_key_template[1].pValue;
8269 +               reuse_mem_len = pub_key_template[1].ulValueLen + DH_BUF_RESERVE;
8270 +               }
8271 +       else
8272 +               {
8273 +               reuse_mem = pub_key_template[2].pValue;
8274 +               reuse_mem_len = pub_key_template[2].ulValueLen + DH_BUF_RESERVE;
8275 +               }
8277 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
8278 +               pub_key_result, pub_key_attr_result_count);
8279 +       rv1 = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
8280 +               priv_key_result, priv_key_attr_result_count);
8282 +       if (rv != CKR_OK || rv1 != CKR_OK)
8283 +               {
8284 +               rv = (rv != CKR_OK) ? rv : rv1;
8285 +               PK11err_add_data(PK11_F_DH_GEN_KEY,
8286 +                   PK11_R_GETATTRIBUTVALUE, rv);
8287 +               goto err;
8288 +               }
8290 +       if (((CK_LONG) pub_key_result[0].ulValueLen) <= 0 ||
8291 +               ((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
8292 +               {
8293 +               PK11err(PK11_F_DH_GEN_KEY, PK11_R_GETATTRIBUTVALUE);
8294 +               goto err;
8295 +               }
8297 +       /* Reuse the memory allocated */
8298 +       pub_key_result[0].pValue = reuse_mem;
8299 +       pub_key_result[0].ulValueLen = reuse_mem_len;
8301 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
8302 +               pub_key_result, pub_key_attr_result_count);
8304 +       if (rv != CKR_OK)
8305 +               {
8306 +               PK11err_add_data(PK11_F_DH_GEN_KEY,
8307 +                   PK11_R_GETATTRIBUTVALUE, rv);
8308 +               goto err;
8309 +               }
8311 +       if (pub_key_result[0].type == CKA_VALUE)
8312 +               {
8313 +               if (dh->pub_key == NULL)
8314 +                       if ((dh->pub_key = BN_new()) == NULL)
8315 +                               {
8316 +                               PK11err(PK11_F_DH_GEN_KEY,
8317 +                                       PK11_R_MALLOC_FAILURE);
8318 +                               goto err;
8319 +                               }
8320 +               dh->pub_key = BN_bin2bn(pub_key_result[0].pValue,
8321 +                       pub_key_result[0].ulValueLen, dh->pub_key);
8322 +               if (dh->pub_key == NULL)
8323 +                       {
8324 +                       PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
8325 +                       goto err;
8326 +                       }
8327 +               }
8329 +       /* Reuse the memory allocated */
8330 +       priv_key_result[0].pValue = reuse_mem;
8331 +       priv_key_result[0].ulValueLen = reuse_mem_len;
8333 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
8334 +               priv_key_result, priv_key_attr_result_count);
8336 +       if (rv != CKR_OK)
8337 +               {
8338 +               PK11err_add_data(PK11_F_DH_GEN_KEY,
8339 +                   PK11_R_GETATTRIBUTVALUE, rv);
8340 +               goto err;
8341 +               }
8343 +       if (priv_key_result[0].type == CKA_VALUE)
8344 +               {
8345 +               if (dh->priv_key == NULL)
8346 +                       if ((dh->priv_key = BN_new()) == NULL)
8347 +                               {
8348 +                               PK11err(PK11_F_DH_GEN_KEY,
8349 +                                       PK11_R_MALLOC_FAILURE);
8350 +                               goto err;
8351 +                               }
8352 +               dh->priv_key = BN_bin2bn(priv_key_result[0].pValue,
8353 +                       priv_key_result[0].ulValueLen, dh->priv_key);
8354 +               if (dh->priv_key == NULL)
8355 +                       {
8356 +                       PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
8357 +                       goto err;
8358 +                       }
8359 +               }
8361 +       ret = 1;
8363 +err:
8365 +       if (h_pub_key != CK_INVALID_HANDLE)
8366 +               {
8367 +               rv = pFuncList->C_DestroyObject(sp->session, h_pub_key);
8368 +               if (rv != CKR_OK)
8369 +                       {
8370 +                       PK11err_add_data(PK11_F_DH_GEN_KEY,
8371 +                           PK11_R_DESTROYOBJECT, rv);
8372 +                       }
8373 +               }
8375 +       if (h_priv_key != CK_INVALID_HANDLE)
8376 +               {
8377 +               rv = pFuncList->C_DestroyObject(sp->session, h_priv_key);
8378 +               if (rv != CKR_OK)
8379 +                       {
8380 +                       PK11err_add_data(PK11_F_DH_GEN_KEY,
8381 +                           PK11_R_DESTROYOBJECT, rv);
8382 +                       }
8383 +               }
8385 +       for (i = 1; i <= 2; i++)
8386 +               {
8387 +               if (pub_key_template[i].pValue != NULL)
8388 +                       {
8389 +                       OPENSSL_free(pub_key_template[i].pValue);
8390 +                       pub_key_template[i].pValue = NULL;
8391 +                       }
8392 +               }
8394 +       pk11_return_session(sp, OP_DH);
8395 +       return (ret);
8396 +       }
8398 +static int pk11_DH_compute_key(unsigned char *key, const BIGNUM *pub_key,
8399 +       DH *dh)
8400 +       {
8401 +       unsigned int i;
8402 +       CK_MECHANISM mechanism = {CKM_DH_PKCS_DERIVE, NULL_PTR, 0};
8403 +       CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
8404 +       CK_KEY_TYPE key_type = CKK_GENERIC_SECRET;
8405 +       CK_OBJECT_HANDLE h_derived_key = CK_INVALID_HANDLE;
8406 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
8408 +       CK_ULONG seclen;
8409 +       CK_ULONG ul_priv_key_attr_count = 3;
8410 +       CK_ATTRIBUTE priv_key_template[] =
8411 +               {
8412 +               {CKA_CLASS, (void*) NULL, sizeof (key_class)},
8413 +               {CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
8414 +               {CKA_VALUE_LEN, &seclen, sizeof (seclen)},
8415 +               };
8417 +       CK_ULONG priv_key_attr_result_count = 1;
8418 +       CK_ATTRIBUTE priv_key_result[] =
8419 +               {
8420 +               {CKA_VALUE, (void *)NULL, 0}
8421 +               };
8423 +       CK_RV rv;
8424 +       int ret = -1;
8425 +       PK11_SESSION *sp = NULL;
8427 +       if (dh->priv_key == NULL)
8428 +               goto err;
8430 +       priv_key_template[0].pValue = &key_class;
8431 +       priv_key_template[1].pValue = &key_type;
8432 +       seclen = BN_num_bytes(dh->p);
8434 +       if ((sp = pk11_get_session(OP_DH)) == NULL)
8435 +               goto err;
8437 +       mechanism.ulParameterLen = BN_num_bytes(pub_key);
8438 +       mechanism.pParameter = OPENSSL_malloc(mechanism.ulParameterLen);
8439 +       if (mechanism.pParameter == NULL)
8440 +               {
8441 +               PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
8442 +               goto err;
8443 +               }
8444 +       BN_bn2bin(pub_key, mechanism.pParameter);
8446 +       (void) check_new_dh_key(sp, dh);
8448 +       h_key = sp->opdata_dh_key;
8449 +       if (h_key == CK_INVALID_HANDLE)
8450 +               h_key = sp->opdata_dh_key =
8451 +                       pk11_get_dh_key((DH*) dh, &sp->opdata_dh,
8452 +                           &sp->opdata_dh_priv_num, sp->session);
8454 +       if (h_key == CK_INVALID_HANDLE)
8455 +               {
8456 +               PK11err(PK11_F_DH_COMP_KEY, PK11_R_CREATEOBJECT);
8457 +               goto err;
8458 +               }
8460 +       rv = pFuncList->C_DeriveKey(sp->session,
8461 +           &mechanism,
8462 +           h_key,
8463 +           priv_key_template,
8464 +           ul_priv_key_attr_count,
8465 +           &h_derived_key);
8466 +       if (rv != CKR_OK)
8467 +               {
8468 +               PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_DERIVEKEY, rv);
8469 +               goto err;
8470 +               }
8472 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
8473 +           priv_key_result, priv_key_attr_result_count);
8475 +       if (rv != CKR_OK)
8476 +               {
8477 +               PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
8478 +                   rv);
8479 +               goto err;
8480 +               }
8482 +       if (((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
8483 +               {
8484 +               PK11err(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE);
8485 +               goto err;
8486 +               }
8487 +       priv_key_result[0].pValue =
8488 +               OPENSSL_malloc(priv_key_result[0].ulValueLen);
8489 +       if (!priv_key_result[0].pValue)
8490 +               {
8491 +               PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
8492 +               goto err;
8493 +               }
8495 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
8496 +               priv_key_result, priv_key_attr_result_count);
8498 +       if (rv != CKR_OK)
8499 +               {
8500 +               PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
8501 +                   rv);
8502 +               goto err;
8503 +               }
8505 +       /*
8506 +        * OpenSSL allocates the output buffer 'key' which is the same
8507 +        * length of the public key. It is long enough for the derived key
8508 +        */
8509 +       if (priv_key_result[0].type == CKA_VALUE)
8510 +               {
8511 +               /*
8512 +                * CKM_DH_PKCS_DERIVE mechanism is not supposed to strip
8513 +                * leading zeros from a computed shared secret. However,
8514 +                * OpenSSL always did it so we must do the same here. The
8515 +                * vagueness of the spec regarding leading zero bytes was
8516 +                * finally cleared with TLS 1.1 (RFC 4346) saying that leading
8517 +                * zeros are stripped before the computed data is used as the
8518 +                * pre-master secret.
8519 +                */
8520 +               for (i = 0; i < priv_key_result[0].ulValueLen; ++i)
8521 +                       {
8522 +                       if (((char *)priv_key_result[0].pValue)[i] != 0)
8523 +                               break;
8524 +                       }
8526 +               (void) memcpy(key, ((char *)priv_key_result[0].pValue) + i,
8527 +                       priv_key_result[0].ulValueLen - i);
8528 +               ret = priv_key_result[0].ulValueLen - i;
8529 +               }
8531 +err:
8533 +       if (h_derived_key != CK_INVALID_HANDLE)
8534 +               {
8535 +               rv = pFuncList->C_DestroyObject(sp->session, h_derived_key);
8536 +               if (rv != CKR_OK)
8537 +                       {
8538 +                       PK11err_add_data(PK11_F_DH_COMP_KEY,
8539 +                           PK11_R_DESTROYOBJECT, rv);
8540 +                       }
8541 +               }
8542 +       if (priv_key_result[0].pValue)
8543 +               {
8544 +               OPENSSL_free(priv_key_result[0].pValue);
8545 +               priv_key_result[0].pValue = NULL;
8546 +               }
8548 +       if (mechanism.pParameter)
8549 +               {
8550 +               OPENSSL_free(mechanism.pParameter);
8551 +               mechanism.pParameter = NULL;
8552 +               }
8554 +       pk11_return_session(sp, OP_DH);
8555 +       return (ret);
8556 +       }
8559 +static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh,
8560 +       DH **key_ptr, BIGNUM **dh_priv_num, CK_SESSION_HANDLE session)
8561 +       {
8562 +       CK_RV rv;
8563 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
8564 +       CK_OBJECT_CLASS class = CKO_PRIVATE_KEY;
8565 +       CK_KEY_TYPE key_type = CKK_DH;
8566 +       CK_ULONG found;
8567 +       CK_BBOOL rollback = FALSE;
8568 +       int i;
8570 +       CK_ULONG ul_key_attr_count = 7;
8571 +       CK_ATTRIBUTE key_template[] =
8572 +               {
8573 +               {CKA_CLASS, (void*) NULL, sizeof (class)},
8574 +               {CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
8575 +               {CKA_DERIVE, &mytrue, sizeof (mytrue)},
8576 +               {CKA_PRIVATE, &myfalse, sizeof (myfalse)},
8577 +               {CKA_PRIME, (void *) NULL, 0},
8578 +               {CKA_BASE, (void *) NULL, 0},
8579 +               {CKA_VALUE, (void *) NULL, 0},
8580 +               };
8582 +       key_template[0].pValue = &class;
8583 +       key_template[1].pValue = &key_type;
8585 +       key_template[4].ulValueLen = BN_num_bytes(dh->p);
8586 +       key_template[4].pValue = (CK_VOID_PTR)OPENSSL_malloc(
8587 +               (size_t)key_template[4].ulValueLen);
8588 +       if (key_template[4].pValue == NULL)
8589 +               {
8590 +               PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8591 +               goto malloc_err;
8592 +               }
8594 +       BN_bn2bin(dh->p, key_template[4].pValue);
8596 +       key_template[5].ulValueLen = BN_num_bytes(dh->g);
8597 +       key_template[5].pValue = (CK_VOID_PTR)OPENSSL_malloc(
8598 +               (size_t)key_template[5].ulValueLen);
8599 +       if (key_template[5].pValue == NULL)
8600 +               {
8601 +               PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8602 +               goto malloc_err;
8603 +               }
8605 +       BN_bn2bin(dh->g, key_template[5].pValue);
8607 +       key_template[6].ulValueLen = BN_num_bytes(dh->priv_key);
8608 +       key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
8609 +               (size_t)key_template[6].ulValueLen);
8610 +       if (key_template[6].pValue == NULL)
8611 +               {
8612 +               PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8613 +               goto malloc_err;
8614 +               }
8616 +       BN_bn2bin(dh->priv_key, key_template[6].pValue);
8618 +       /* see find_lock array definition for more info on object locking */
8619 +       LOCK_OBJSTORE(OP_DH);
8620 +       rv = pFuncList->C_FindObjectsInit(session, key_template,
8621 +               ul_key_attr_count);
8623 +       if (rv != CKR_OK)
8624 +               {
8625 +               PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSINIT, rv);
8626 +               goto err;
8627 +               }
8629 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
8631 +       if (rv != CKR_OK)
8632 +               {
8633 +               (void) pFuncList->C_FindObjectsFinal(session);
8634 +               PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTS, rv);
8635 +               goto err;
8636 +               }
8638 +       rv = pFuncList->C_FindObjectsFinal(session);
8640 +       if (rv != CKR_OK)
8641 +               {
8642 +               PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSFINAL,
8643 +                   rv);
8644 +               goto err;
8645 +               }
8647 +       if (found == 0)
8648 +               {
8649 +               rv = pFuncList->C_CreateObject(session,
8650 +                       key_template, ul_key_attr_count, &h_key);
8651 +               if (rv != CKR_OK)
8652 +                       {
8653 +                       PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_CREATEOBJECT,
8654 +                           rv);
8655 +                       goto err;
8656 +                       }
8657 +               }
8659 +       if (dh_priv_num != NULL)
8660 +               if ((*dh_priv_num = BN_dup(dh->priv_key)) == NULL)
8661 +                       {
8662 +                       PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8663 +                       rollback = TRUE;
8664 +                       goto err;
8665 +                       }
8667 +       /* LINTED: E_CONSTANT_CONDITION */
8668 +       KEY_HANDLE_REFHOLD(h_key, OP_DH, FALSE, rollback, err);
8669 +       if (key_ptr != NULL)
8670 +               *key_ptr = dh;
8672 +err:
8673 +       if (rollback)
8674 +               {
8675 +               /*
8676 +                * We do not care about the return value from C_DestroyObject()
8677 +                * since we are doing rollback.
8678 +                */
8679 +               if (found == 0)
8680 +                       (void) pFuncList->C_DestroyObject(session, h_key);
8681 +               h_key = CK_INVALID_HANDLE;
8682 +               }
8684 +       UNLOCK_OBJSTORE(OP_DH);
8686 +malloc_err:
8687 +       for (i = 4; i <= 6; i++)
8688 +               {
8689 +               if (key_template[i].pValue != NULL)
8690 +                       {
8691 +                       OPENSSL_free(key_template[i].pValue);
8692 +                       key_template[i].pValue = NULL;
8693 +                       }
8694 +               }
8696 +       return (h_key);
8697 +       }
8700 + * Check for cache miss and clean the object pointer and handle
8701 + * in such case. Return 1 for cache hit, 0 for cache miss.
8702 + *
8703 + * Note: we rely on pk11_destroy_dh_key_objects() to set sp->opdata_dh
8704 + *       to CK_INVALID_HANDLE even when it fails to destroy the object.
8705 + */
8706 +static int check_new_dh_key(PK11_SESSION *sp, DH *dh)
8707 +       {
8708 +       /*
8709 +        * Provide protection against DH structure reuse by making the
8710 +        * check for cache hit stronger. Private key component of DH key
8711 +        * is unique so it is sufficient to compare it with value cached
8712 +        * in PK11_SESSION structure.
8713 +        */
8714 +       if ((sp->opdata_dh != dh) ||
8715 +           (BN_cmp(sp->opdata_dh_priv_num, dh->priv_key) != 0))
8716 +               {
8717 +               /*
8718 +                * We do not check the return value because even in case of
8719 +                * failure the sp structure will have both key pointer
8720 +                * and object handle cleaned and pk11_destroy_object()
8721 +                * reports the failure to the OpenSSL error message buffer.
8722 +                */
8723 +               (void) pk11_destroy_dh_object(sp, TRUE);
8724 +               return (0);
8725 +               }
8726 +       return (1);
8727 +       }
8728 +#endif
8731 + * Local function to simplify key template population
8732 + * Return 0 -- error, 1 -- no error
8733 + */
8734 +static int
8735 +init_template_value(BIGNUM *bn, CK_VOID_PTR *p_value,
8736 +       CK_ULONG *ul_value_len)
8737 +       {
8738 +       CK_ULONG len = 0;
8740 +       /*
8741 +        * This function can be used on non-initialized BIGNUMs. It is
8742 +        * easier to check that here than individually in the callers.
8743 +        */
8744 +       if (bn != NULL)
8745 +               len = BN_num_bytes(bn);
8747 +       if (bn == NULL || len == 0)
8748 +               return (1);
8750 +       *ul_value_len = len;
8751 +       *p_value = (CK_VOID_PTR)OPENSSL_malloc((size_t)*ul_value_len);
8752 +       if (*p_value == NULL)
8753 +               return (0);
8755 +       BN_bn2bin(bn, *p_value);
8757 +       return (1);
8758 +       }
8760 +static void
8761 +attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn)
8762 +       {
8763 +       if (attr->ulValueLen > 0)
8764 +               *bn = BN_bin2bn(attr_data, attr->ulValueLen, NULL);
8765 +       }
8768 + * Find one object in the token. It is an error if we can not find the
8769 + * object or if we find more objects based on the template we got.
8770 + * Assume object store locked.
8771 + *
8772 + * Returns:
8773 + *     1 OK
8774 + *     0 no object or more than 1 object found
8775 + */
8776 +static int
8777 +find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
8778 +    CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey)
8779 +       {
8780 +       CK_RV rv;
8781 +       CK_ULONG objcnt;
8783 +       if ((rv = pFuncList->C_FindObjectsInit(s, ptempl, nattr)) != CKR_OK)
8784 +               {
8785 +               PK11err_add_data(PK11_F_FIND_ONE_OBJECT,
8786 +                   PK11_R_FINDOBJECTSINIT, rv);
8787 +               return (0);
8788 +               }
8790 +       rv = pFuncList->C_FindObjects(s, pkey, 1, &objcnt);
8791 +       if (rv != CKR_OK)
8792 +               {
8793 +               (void) pFuncList->C_FindObjectsFinal(s);
8794 +               PK11err_add_data(PK11_F_FIND_ONE_OBJECT, PK11_R_FINDOBJECTS,
8795 +                   rv);
8796 +               return (0);
8797 +               }
8799 +       (void) pFuncList->C_FindObjectsFinal(s);
8801 +       if (objcnt > 1)
8802 +               {
8803 +               PK11err(PK11_F_FIND_ONE_OBJECT,
8804 +                   PK11_R_MORE_THAN_ONE_OBJECT_FOUND);
8805 +               return (0);
8806 +               }
8807 +       else if (objcnt == 0)
8808 +               {
8809 +               PK11err(PK11_F_FIND_ONE_OBJECT, PK11_R_NO_OBJECT_FOUND);
8810 +               return (0);
8811 +               }
8812 +       return (1);
8813 +       }
8815 +/* from uri stuff */
8817 +extern char *pk11_pin;
8819 +static int pk11_get_pin(void);
8821 +static int
8822 +pk11_get_pin(void)
8824 +       char *pin;
8826 +       /* The getpassphrase() function is not MT safe. */
8827 +#ifndef NOPTHREADS
8828 +       OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
8829 +#else
8830 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
8831 +#endif
8832 +       pin = getpassphrase("Enter PIN: ");
8833 +       if (pin == NULL)
8834 +               {
8835 +               PK11err(PK11_F_GET_PIN, PK11_R_COULD_NOT_READ_PIN);
8836 +#ifndef NOPTHREADS
8837 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
8838 +#else
8839 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
8840 +#endif
8841 +               return (0);
8842 +               }
8843 +       pk11_pin = BUF_strdup(pin);
8844 +       if (pk11_pin == NULL)
8845 +               {
8846 +               PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_MALLOC_FAILURE);
8847 +#ifndef NOPTHREADS
8848 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
8849 +#else
8850 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
8851 +#endif
8852 +               return (0);
8853 +               }
8854 +       memset(pin, 0, strlen(pin));
8855 +#ifndef NOPTHREADS
8856 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
8857 +#else
8858 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
8859 +#endif
8860 +       return (1);
8861 +       }
8864 + * Log in to the keystore if we are supposed to do that at all. Take care of
8865 + * reading and caching the PIN etc. Log in only once even when called from
8866 + * multiple threads.
8867 + *
8868 + * Returns:
8869 + *     1 on success
8870 + *     0 on failure
8871 + */
8872 +static int
8873 +pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
8874 +    CK_BBOOL is_private)
8875 +       {
8876 +       CK_RV rv;
8878 +#if 0
8879 +       /* doesn't work on the AEP Keyper??? */
8880 +       if ((pubkey_token_flags & CKF_TOKEN_INITIALIZED) == 0)
8881 +               {
8882 +               PK11err(PK11_F_TOKEN_LOGIN,
8883 +                   PK11_R_TOKEN_NOT_INITIALIZED);
8884 +               return (0);
8885 +               }
8886 +#endif
8888 +       /*
8889 +        * If login is required or needed but the PIN has not been
8890 +        * even initialized we can bail out right now. Note that we
8891 +        * are supposed to always log in if we are going to access
8892 +        * private keys. However, we may need to log in even for
8893 +        * accessing public keys in case that the CKF_LOGIN_REQUIRED
8894 +        * flag is set.
8895 +        */
8896 +       if (((pubkey_token_flags & CKF_LOGIN_REQUIRED) ||
8897 +            (is_private == CK_TRUE)) &&
8898 +           (~pubkey_token_flags & CKF_USER_PIN_INITIALIZED))
8899 +               {
8900 +               PK11err(PK11_F_TOKEN_LOGIN, PK11_R_TOKEN_PIN_NOT_SET);
8901 +               return (0);
8902 +               }
8904 +       /*
8905 +        * Note on locking: it is possible that more than one thread
8906 +        * gets into pk11_get_pin() so we must deal with that. We
8907 +        * cannot avoid it since we cannot guard fork() in there with
8908 +        * a lock because we could end up in a dead lock in the
8909 +        * child. Why? Remember we are in a multithreaded environment
8910 +        * so we must lock all mutexes in the prefork function to
8911 +        * avoid a situation in which a thread that did not call
8912 +        * fork() held a lock, making future unlocking impossible. We
8913 +        * lock right before C_Login().
8914 +        */
8915 +       if ((pubkey_token_flags & CKF_LOGIN_REQUIRED) ||
8916 +           (is_private == CK_TRUE))
8917 +               {
8918 +               if (*login_done == CK_FALSE)
8919 +                       {
8920 +                       if ((pk11_pin == NULL) && (pk11_get_pin() == 0))
8921 +                               {
8922 +                               PK11err(PK11_F_TOKEN_LOGIN,
8923 +                                   PK11_R_TOKEN_PIN_NOT_PROVIDED);
8924 +                               return (0);
8925 +                               }
8926 +                       }
8928 +               /*
8929 +                * Note that what we are logging into is the keystore from
8930 +                * pubkey_SLOTID because we work with OP_RSA session type here.
8931 +                * That also means that we can work with only one keystore in
8932 +                * the engine.
8933 +                *
8934 +                * We must make sure we do not try to login more than once.
8935 +                * Also, see the comment above on locking strategy.
8936 +                */
8938 +#ifndef NOPTHREADS
8939 +               OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
8940 +#else
8941 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
8942 +#endif
8943 +               if (*login_done == CK_FALSE)
8944 +                       {
8945 +                       if ((rv = pFuncList->C_Login(session,
8946 +                           CKU_USER, (CK_UTF8CHAR*)pk11_pin,
8947 +                           strlen(pk11_pin))) != CKR_OK)
8948 +                               {
8949 +                               PK11err_add_data(PK11_F_TOKEN_LOGIN,
8950 +                                   PK11_R_TOKEN_LOGIN_FAILED, rv);
8951 +                               goto err_locked;
8952 +                               }
8954 +                       *login_done = CK_TRUE;
8956 +                       }
8957 +#ifndef NOPTHREADS
8958 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
8959 +#else
8960 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
8961 +#endif
8962 +               }
8963 +       else
8964 +               {
8965 +                       /*
8966 +                        * If token does not require login we take it as the
8967 +                        * login was done.
8968 +                        */
8969 +                       *login_done = CK_TRUE;
8970 +               }
8972 +       return (1);
8974 +err_locked:
8975 +       if (pk11_pin) {
8976 +               memset(pk11_pin, 0, strlen(pk11_pin));
8977 +               OPENSSL_free((void*)pk11_pin);
8978 +       }
8979 +       pk11_pin = NULL;
8980 +#ifndef NOPTHREADS
8981 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
8982 +#else
8983 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
8984 +#endif
8985 +       return (0);
8986 +       }
8989 + * Log in to the keystore in the child if we were logged in in the
8990 + * parent. There are similarities in the code with pk11_token_login()
8991 + * but still it is quite different so we need a separate function for
8992 + * this.
8993 + *
8994 + * Note that this function is called under the locked session mutex when fork is
8995 + * detected. That means that C_Login() will be called from the child just once.
8996 + *
8997 + * Returns:
8998 + *     1 on success
8999 + *     0 on failure
9000 + */
9001 +int
9002 +pk11_token_relogin(CK_SESSION_HANDLE session)
9003 +       {
9004 +       CK_RV rv;
9006 +       if ((pk11_pin == NULL) && (pk11_get_pin() == 0))
9007 +               return (0);
9009 +#ifndef NOPTHREADS
9010 +       OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
9011 +#else
9012 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
9013 +#endif
9014 +       if ((rv = pFuncList->C_Login(session, CKU_USER,
9015 +           (CK_UTF8CHAR_PTR)pk11_pin, strlen(pk11_pin))) != CKR_OK)
9016 +               {
9017 +               PK11err_add_data(PK11_F_TOKEN_RELOGIN,
9018 +                   PK11_R_TOKEN_LOGIN_FAILED, rv);
9019 +#ifndef NOPTHREADS
9020 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
9021 +#else
9022 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
9023 +#endif
9024 +               return (0);
9025 +               }
9026 +#ifndef NOPTHREADS
9027 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
9028 +#else
9029 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
9030 +#endif
9032 +       return (1);
9033 +       }
9035 +#ifdef OPENSSL_SYS_WIN32
9036 +char *getpassphrase(const char *prompt)
9037 +       {
9038 +       static char buf[128];
9039 +       HANDLE h;
9040 +       DWORD cc, mode;
9041 +       int cnt;
9043 +       h = GetStdHandle(STD_INPUT_HANDLE);
9044 +       fputs(prompt, stderr);
9045 +       fflush(stderr);
9046 +       fflush(stdout);
9047 +       FlushConsoleInputBuffer(h);
9048 +       GetConsoleMode(h, &mode);
9049 +       SetConsoleMode(h, ENABLE_PROCESSED_INPUT);
9051 +       for (cnt = 0; cnt < sizeof(buf) - 1; cnt++)
9052 +               {
9053 +               ReadFile(h, buf + cnt, 1, &cc, NULL);
9054 +               if (buf[cnt] == '\r')
9055 +                       break;
9056 +               fputc('*', stdout);
9057 +               fflush(stderr);
9058 +               fflush(stdout);
9059 +               }
9061 +       SetConsoleMode(h, mode);
9062 +       buf[cnt] = '\0';
9063 +       fputs("\n", stderr);
9064 +       return buf;
9065 +       }
9066 +#endif /* OPENSSL_SYS_WIN32 */
9067 +#endif /* OPENSSL_NO_HW_PK11CA */
9068 +#endif /* OPENSSL_NO_HW_PK11 */
9069 +#endif /* OPENSSL_NO_HW */
9070 Index: openssl/crypto/engine/hw_pk11ca.h
9071 diff -u /dev/null openssl/crypto/engine/hw_pk11ca.h:1.4
9072 --- /dev/null   Fri Jan  2 14:59:08 2015
9073 +++ openssl/crypto/engine/hw_pk11ca.h   Wed Jun 15 21:12:20 2011
9074 @@ -0,0 +1,32 @@
9075 +/* Redefine all pk11/PK11 external symbols to pk11ca/PK11CA */
9077 +#define token_lock                     pk11ca_token_lock
9078 +#define find_lock                      pk11ca_find_lock
9079 +#define active_list                    pk11ca_active_list
9080 +#define pubkey_token_flags             pk11ca_pubkey_token_flags
9081 +#define pubkey_SLOTID                  pk11ca_pubkey_SLOTID
9082 +#define ERR_pk11_error                 ERR_pk11ca_error
9083 +#define PK11err_add_data               PK11CAerr_add_data
9084 +#define pk11_get_session               pk11ca_get_session
9085 +#define pk11_return_session            pk11ca_return_session
9086 +#define pk11_active_add                        pk11ca_active_add
9087 +#define pk11_active_delete             pk11ca_active_delete
9088 +#define pk11_active_remove             pk11ca_active_remove
9089 +#define pk11_free_active_list          pk11ca_free_active_list
9090 +#define pk11_destroy_rsa_key_objects   pk11ca_destroy_rsa_key_objects
9091 +#define pk11_destroy_rsa_object_pub    pk11ca_destroy_rsa_object_pub
9092 +#define pk11_destroy_rsa_object_priv   pk11ca_destroy_rsa_object_priv
9093 +#define pk11_load_privkey              pk11ca_load_privkey
9094 +#define pk11_load_pubkey               pk11ca_load_pubkey
9095 +#define PK11_RSA                       PK11CA_RSA
9096 +#define pk11_destroy_dsa_key_objects   pk11ca_destroy_dsa_key_objects
9097 +#define pk11_destroy_dsa_object_pub    pk11ca_destroy_dsa_object_pub
9098 +#define pk11_destroy_dsa_object_priv   pk11ca_destroy_dsa_object_priv
9099 +#define PK11_DSA                       PK11CA_DSA
9100 +#define pk11_destroy_dh_key_objects    pk11ca_destroy_dh_key_objects
9101 +#define pk11_destroy_dh_object         pk11ca_destroy_dh_object
9102 +#define PK11_DH                                PK11CA_DH
9103 +#define pk11_token_relogin             pk11ca_token_relogin
9104 +#define pFuncList                      pk11ca_pFuncList
9105 +#define pk11_pin                       pk11ca_pin
9106 +#define ENGINE_load_pk11               ENGINE_load_pk11ca
9107 Index: openssl/crypto/engine/hw_pk11so.c
9108 diff -u /dev/null openssl/crypto/engine/hw_pk11so.c:1.8
9109 --- /dev/null   Fri Jan  2 14:59:08 2015
9110 +++ openssl/crypto/engine/hw_pk11so.c   Fri Oct  4 14:05:16 2013
9111 @@ -0,0 +1,1775 @@
9113 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
9114 + * Use is subject to license terms.
9115 + */
9117 +/* crypto/engine/hw_pk11.c */
9119 + * This product includes software developed by the OpenSSL Project for
9120 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
9121 + *
9122 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
9123 + * Afchine Madjlessi.
9124 + */
9126 + * ====================================================================
9127 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
9128 + *
9129 + * Redistribution and use in source and binary forms, with or without
9130 + * modification, are permitted provided that the following conditions
9131 + * are met:
9132 + *
9133 + * 1. Redistributions of source code must retain the above copyright
9134 + *    notice, this list of conditions and the following disclaimer.
9135 + *
9136 + * 2. Redistributions in binary form must reproduce the above copyright
9137 + *    notice, this list of conditions and the following disclaimer in
9138 + *    the documentation and/or other materials provided with the
9139 + *    distribution.
9140 + *
9141 + * 3. All advertising materials mentioning features or use of this
9142 + *    software must display the following acknowledgment:
9143 + *    "This product includes software developed by the OpenSSL Project
9144 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
9145 + *
9146 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
9147 + *    endorse or promote products derived from this software without
9148 + *    prior written permission. For written permission, please contact
9149 + *    licensing@OpenSSL.org.
9150 + *
9151 + * 5. Products derived from this software may not be called "OpenSSL"
9152 + *    nor may "OpenSSL" appear in their names without prior written
9153 + *    permission of the OpenSSL Project.
9154 + *
9155 + * 6. Redistributions of any form whatsoever must retain the following
9156 + *    acknowledgment:
9157 + *    "This product includes software developed by the OpenSSL Project
9158 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
9159 + *
9160 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
9161 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
9162 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
9163 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
9164 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9165 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
9166 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
9167 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
9168 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
9169 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
9170 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
9171 + * OF THE POSSIBILITY OF SUCH DAMAGE.
9172 + * ====================================================================
9173 + *
9174 + * This product includes cryptographic software written by Eric Young
9175 + * (eay@cryptsoft.com).  This product includes software written by Tim
9176 + * Hudson (tjh@cryptsoft.com).
9177 + *
9178 + */
9180 +/* Modified to keep only RNG and RSA Sign */
9182 +#ifdef OPENSSL_NO_RSA
9183 +#error RSA is disabled
9184 +#endif
9186 +#include <stdio.h>
9187 +#include <stdlib.h>
9188 +#include <string.h>
9189 +#include <sys/types.h>
9191 +#include <openssl/e_os2.h>
9192 +#include <openssl/crypto.h>
9193 +#include <cryptlib.h>
9194 +#include <openssl/engine.h>
9195 +#include <openssl/dso.h>
9196 +#include <openssl/err.h>
9197 +#include <openssl/bn.h>
9198 +#include <openssl/md5.h>
9199 +#include <openssl/pem.h>
9200 +#include <openssl/rsa.h>
9201 +#include <openssl/rand.h>
9202 +#include <openssl/objects.h>
9203 +#include <openssl/x509.h>
9205 +#ifdef OPENSSL_SYS_WIN32
9206 +typedef int pid_t;
9207 +#define getpid() GetCurrentProcessId()
9208 +#define NOPTHREADS
9209 +#ifndef NULL_PTR
9210 +#define NULL_PTR NULL
9211 +#endif
9212 +#define CK_DEFINE_FUNCTION(returnType, name) \
9213 +       returnType __declspec(dllexport) name
9214 +#define CK_DECLARE_FUNCTION(returnType, name) \
9215 +       returnType __declspec(dllimport) name
9216 +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
9217 +       returnType __declspec(dllimport) (* name)
9218 +#else
9219 +#include <signal.h>
9220 +#include <unistd.h>
9221 +#include <dlfcn.h>
9222 +#endif
9224 +/* Debug mutexes */
9225 +/*#undef DEBUG_MUTEX */
9226 +#define DEBUG_MUTEX
9228 +#ifndef NOPTHREADS
9229 +/* for pthread error check on Linuxes */
9230 +#ifdef DEBUG_MUTEX
9231 +#define __USE_UNIX98
9232 +#endif
9233 +#include <pthread.h>
9234 +#endif
9236 +#ifndef OPENSSL_NO_HW
9237 +#ifndef OPENSSL_NO_HW_PK11
9238 +#ifndef OPENSSL_NO_HW_PK11SO
9240 +/* label for debug messages printed on stderr */
9241 +#define        PK11_DBG        "PKCS#11 ENGINE DEBUG"
9242 +/* prints a lot of debug messages on stderr about slot selection process */
9243 +/*#undef       DEBUG_SLOT_SELECTION */
9245 +#ifndef OPENSSL_NO_DSA
9246 +#define OPENSSL_NO_DSA
9247 +#endif
9248 +#ifndef OPENSSL_NO_DH
9249 +#define OPENSSL_NO_DH
9250 +#endif
9252 +#ifdef OPENSSL_SYS_WIN32
9253 +#pragma pack(push, cryptoki, 1)
9254 +#include "cryptoki.h"
9255 +#include "pkcs11.h"
9256 +#pragma pack(pop, cryptoki)
9257 +#else
9258 +#include "cryptoki.h"
9259 +#include "pkcs11.h"
9260 +#endif
9261 +#include "hw_pk11so.h"
9262 +#include "hw_pk11_err.c"
9265 + * We use this lock to prevent multiple C_Login()s, guard getpassphrase(),
9266 + * uri_struct manipulation, and static token info. All of that is used by the
9267 + * RSA keys by reference feature.
9268 + */
9269 +#ifndef NOPTHREADS
9270 +pthread_mutex_t *token_lock;
9271 +#endif
9273 +/* PKCS#11 session caches and their locks for all operation types */
9274 +static PK11_CACHE session_cache[OP_MAX];
9277 + * We cache the flags so that we do not have to run C_GetTokenInfo() again when
9278 + * logging into the token.
9279 + */
9280 +CK_FLAGS pubkey_token_flags;
9283 + * As stated in v2.20, 11.7 Object Management Function, in section for
9284 + * C_FindObjectsInit(), at most one search operation may be active at a given
9285 + * time in a given session. Therefore, C_Find{,Init,Final}Objects() should be
9286 + * grouped together to form one atomic search operation. This is already
9287 + * ensured by the property of unique PKCS#11 session handle used for each
9288 + * PK11_SESSION object.
9289 + *
9290 + * This is however not the biggest concern - maintaining consistency of the
9291 + * underlying object store is more important. The same section of the spec also
9292 + * says that one thread can be in the middle of a search operation while another
9293 + * thread destroys the object matching the search template which would result in
9294 + * invalid handle returned from the search operation.
9295 + *
9296 + * Hence, the following locks are used for both protection of the object stores.
9297 + * They are also used for active list protection.
9298 + */
9299 +#ifndef NOPTHREADS
9300 +pthread_mutex_t *find_lock[OP_MAX] = { NULL };
9301 +#endif
9304 + * lists of asymmetric key handles which are active (referenced by at least one
9305 + * PK11_SESSION structure, either held by a thread or present in free_session
9306 + * list) for given algorithm type
9307 + */
9308 +PK11_active *active_list[OP_MAX] = { NULL };
9311 + * Create all secret key objects in a global session so that they are available
9312 + * to use for other sessions. These other sessions may be opened or closed
9313 + * without losing the secret key objects.
9314 + */
9315 +static CK_SESSION_HANDLE       global_session = CK_INVALID_HANDLE;
9317 +/* ENGINE level stuff */
9318 +static int pk11_init(ENGINE *e);
9319 +static int pk11_library_init(ENGINE *e);
9320 +static int pk11_finish(ENGINE *e);
9321 +static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
9322 +static int pk11_destroy(ENGINE *e);
9324 +/* RAND stuff */
9325 +static void pk11_rand_seed(const void *buf, int num);
9326 +static void pk11_rand_add(const void *buf, int num, double add_entropy);
9327 +static void pk11_rand_cleanup(void);
9328 +static int pk11_rand_bytes(unsigned char *buf, int num);
9329 +static int pk11_rand_status(void);
9331 +/* These functions are also used in other files */
9332 +PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
9333 +void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
9335 +/* active list manipulation functions used in this file */
9336 +extern int pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type);
9337 +extern void pk11_free_active_list(PK11_OPTYPE type);
9339 +int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
9340 +int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
9341 +int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
9343 +/* Local helper functions */
9344 +static int pk11_free_all_sessions(void);
9345 +static int pk11_free_session_list(PK11_OPTYPE optype);
9346 +static int pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype);
9347 +static int pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
9348 +       CK_BBOOL persistent);
9349 +static const char *get_PK11_LIBNAME(void);
9350 +static void free_PK11_LIBNAME(void);
9351 +static long set_PK11_LIBNAME(const char *name);
9353 +static int pk11_choose_slots(int *any_slot_found);
9355 +static int pk11_init_all_locks(void);
9356 +static void pk11_free_all_locks(void);
9358 +#define        TRY_OBJ_DESTROY(sp, obj_hdl, retval, uselock, alg_type, priv)   \
9359 +       {                                                               \
9360 +       if (uselock)                                                    \
9361 +               LOCK_OBJSTORE(alg_type);                                \
9362 +       if (pk11_active_delete(obj_hdl, alg_type) == 1)                 \
9363 +               {                                                       \
9364 +                 retval = pk11_destroy_object(sp->session, obj_hdl,    \
9365 +                 priv ? sp->priv_persistent : sp->pub_persistent);     \
9366 +               }                                                       \
9367 +       if (uselock)                                                    \
9368 +               UNLOCK_OBJSTORE(alg_type);                              \
9369 +       }
9371 +static CK_BBOOL pk11_have_rsa  = CK_FALSE;
9372 +static CK_BBOOL pk11_have_random = CK_FALSE;
9375 + * Initialization function. Sets up various PKCS#11 library components.
9376 + * The definitions for control commands specific to this engine
9377 + */
9378 +#define PK11_CMD_SO_PATH               ENGINE_CMD_BASE
9379 +#define PK11_CMD_PIN                   (ENGINE_CMD_BASE+1)
9380 +#define PK11_CMD_SLOT                  (ENGINE_CMD_BASE+2)
9381 +static const ENGINE_CMD_DEFN pk11_cmd_defns[] =
9382 +       {
9383 +               {
9384 +               PK11_CMD_SO_PATH,
9385 +               "SO_PATH",
9386 +               "Specifies the path to the 'pkcs#11' shared library",
9387 +               ENGINE_CMD_FLAG_STRING
9388 +               },
9389 +               {
9390 +               PK11_CMD_PIN,
9391 +               "PIN",
9392 +               "Specifies the pin code",
9393 +               ENGINE_CMD_FLAG_STRING
9394 +               },
9395 +               {
9396 +               PK11_CMD_SLOT,
9397 +               "SLOT",
9398 +               "Specifies the slot (default is auto select)",
9399 +               ENGINE_CMD_FLAG_NUMERIC,
9400 +               },
9401 +               {0, NULL, NULL, 0}
9402 +       };
9405 +static RAND_METHOD pk11_random =
9406 +       {
9407 +       pk11_rand_seed,
9408 +       pk11_rand_bytes,
9409 +       pk11_rand_cleanup,
9410 +       pk11_rand_add,
9411 +       pk11_rand_bytes,
9412 +       pk11_rand_status
9413 +       };
9416 +/* Constants used when creating the ENGINE */
9417 +#ifdef OPENSSL_NO_HW_PK11CA
9418 +#error "can't load both crypto-accelerator and sign-only PKCS#11 engines"
9419 +#endif
9420 +static const char *engine_pk11_id = "pkcs11";
9421 +static const char *engine_pk11_name = "PKCS #11 engine support (sign only)";
9423 +CK_FUNCTION_LIST_PTR pFuncList = NULL;
9424 +static const char PK11_GET_FUNCTION_LIST[] = "C_GetFunctionList";
9427 + * This is a static string constant for the DSO file name and the function
9428 + * symbol names to bind to. We set it in the Configure script based on whether
9429 + * this is 32 or 64 bit build.
9430 + */
9431 +static const char def_PK11_LIBNAME[] = PK11_LIB_LOCATION;
9433 +/* Needed in hw_pk11_pub.c as well so that's why it is not static. */
9434 +CK_SLOT_ID pubkey_SLOTID = 0;
9435 +static CK_SLOT_ID rand_SLOTID = 0;
9436 +static CK_SLOT_ID SLOTID = 0;
9437 +char *pk11_pin = NULL;
9438 +static CK_BBOOL pk11_library_initialized = FALSE;
9439 +static CK_BBOOL pk11_atfork_initialized = FALSE;
9440 +static int pk11_pid = 0;
9442 +static DSO *pk11_dso = NULL;
9444 +/* allocate and initialize all locks used by the engine itself */
9445 +static int pk11_init_all_locks(void)
9446 +       {
9447 +#ifndef NOPTHREADS
9448 +       int type;
9449 +       pthread_mutexattr_t attr;
9451 +       if (pthread_mutexattr_init(&attr) != 0)
9452 +       {
9453 +               PK11err(PK11_F_INIT_ALL_LOCKS, 100);
9454 +               return (0);
9455 +       }
9457 +#ifdef DEBUG_MUTEX
9458 +       if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0)
9459 +       {
9460 +               PK11err(PK11_F_INIT_ALL_LOCKS, 101);
9461 +               return (0);
9462 +       }
9463 +#endif
9465 +       if ((token_lock = OPENSSL_malloc(sizeof (pthread_mutex_t))) == NULL)
9466 +               goto malloc_err;
9467 +       (void) pthread_mutex_init(token_lock, &attr);
9469 +       find_lock[OP_RSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
9470 +       if (find_lock[OP_RSA] == NULL)
9471 +               goto malloc_err;
9472 +       (void) pthread_mutex_init(find_lock[OP_RSA], &attr);
9474 +       for (type = 0; type < OP_MAX; type++)
9475 +               {
9476 +               session_cache[type].lock =
9477 +                   OPENSSL_malloc(sizeof (pthread_mutex_t));
9478 +               if (session_cache[type].lock == NULL)
9479 +                       goto malloc_err;
9480 +               (void) pthread_mutex_init(session_cache[type].lock, &attr);
9481 +               }
9483 +       return (1);
9485 +malloc_err:
9486 +       pk11_free_all_locks();
9487 +       PK11err(PK11_F_INIT_ALL_LOCKS, PK11_R_MALLOC_FAILURE);
9488 +       return (0);
9489 +#else
9490 +       return (1);
9491 +#endif
9492 +       }
9494 +static void pk11_free_all_locks(void)
9495 +       {
9496 +#ifndef NOPTHREADS
9497 +       int type;
9499 +       if (token_lock != NULL)
9500 +               {
9501 +               (void) pthread_mutex_destroy(token_lock);
9502 +               OPENSSL_free(token_lock);
9503 +               token_lock = NULL;
9504 +               }
9506 +       if (find_lock[OP_RSA] != NULL)
9507 +               {
9508 +               (void) pthread_mutex_destroy(find_lock[OP_RSA]);
9509 +               OPENSSL_free(find_lock[OP_RSA]);
9510 +               find_lock[OP_RSA] = NULL;
9511 +               }
9513 +       for (type = 0; type < OP_MAX; type++)
9514 +               {
9515 +               if (session_cache[type].lock != NULL)
9516 +                       {
9517 +                       (void) pthread_mutex_destroy(session_cache[type].lock);
9518 +                       OPENSSL_free(session_cache[type].lock);
9519 +                       session_cache[type].lock = NULL;
9520 +                       }
9521 +               }
9522 +#endif
9523 +       }
9526 + * This internal function is used by ENGINE_pk11() and "dynamic" ENGINE support.
9527 + */
9528 +static int bind_pk11(ENGINE *e)
9529 +       {
9530 +       if (!pk11_library_initialized)
9531 +               if (!pk11_library_init(e))
9532 +                       return (0);
9534 +       if (!ENGINE_set_id(e, engine_pk11_id) ||
9535 +           !ENGINE_set_name(e, engine_pk11_name))
9536 +               return (0);
9538 +       if (pk11_have_rsa == CK_TRUE)
9539 +               {
9540 +               if (!ENGINE_set_RSA(e, PK11_RSA()) ||
9541 +                   !ENGINE_set_load_privkey_function(e, pk11_load_privkey) ||
9542 +                   !ENGINE_set_load_pubkey_function(e, pk11_load_pubkey))
9543 +                       return (0);
9544 +#ifdef DEBUG_SLOT_SELECTION
9545 +               fprintf(stderr, "%s: registered RSA\n", PK11_DBG);
9546 +#endif /* DEBUG_SLOT_SELECTION */
9547 +               }
9549 +       if (pk11_have_random)
9550 +               {
9551 +               if (!ENGINE_set_RAND(e, &pk11_random))
9552 +                       return (0);
9553 +#ifdef DEBUG_SLOT_SELECTION
9554 +               fprintf(stderr, "%s: registered random\n", PK11_DBG);
9555 +#endif /* DEBUG_SLOT_SELECTION */
9556 +               }
9557 +       if (!ENGINE_set_init_function(e, pk11_init) ||
9558 +           !ENGINE_set_destroy_function(e, pk11_destroy) ||
9559 +           !ENGINE_set_finish_function(e, pk11_finish) ||
9560 +           !ENGINE_set_ctrl_function(e, pk11_ctrl) ||
9561 +           !ENGINE_set_cmd_defns(e, pk11_cmd_defns))
9562 +               return (0);
9564 +       /* Ensure the pk11 error handling is set up */
9565 +       ERR_load_pk11_strings();
9567 +       return (1);
9568 +       }
9570 +/* Dynamic engine support is disabled at a higher level for Solaris */
9571 +#ifdef ENGINE_DYNAMIC_SUPPORT
9572 +#error "dynamic engine not supported"
9573 +static int bind_helper(ENGINE *e, const char *id)
9574 +       {
9575 +       if (id && (strcmp(id, engine_pk11_id) != 0))
9576 +               return (0);
9578 +       if (!bind_pk11(e))
9579 +               return (0);
9581 +       return (1);
9582 +       }
9584 +IMPLEMENT_DYNAMIC_CHECK_FN()
9585 +IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
9587 +#else
9588 +static ENGINE *engine_pk11(void)
9589 +       {
9590 +       ENGINE *ret = ENGINE_new();
9592 +       if (!ret)
9593 +               return (NULL);
9595 +       if (!bind_pk11(ret))
9596 +               {
9597 +               ENGINE_free(ret);
9598 +               return (NULL);
9599 +               }
9601 +       return (ret);
9602 +       }
9604 +void
9605 +ENGINE_load_pk11(void)
9606 +       {
9607 +       ENGINE *e_pk11 = NULL;
9609 +       /*
9610 +        * Do not use dynamic PKCS#11 library on Solaris due to
9611 +        * security reasons. We will link it in statically.
9612 +        */
9613 +       /* Attempt to load PKCS#11 library */
9614 +       if (!pk11_dso)
9615 +               pk11_dso = DSO_load(NULL, get_PK11_LIBNAME(), NULL, 0);
9617 +       if (pk11_dso == NULL)
9618 +               {
9619 +               PK11err(PK11_F_LOAD, PK11_R_DSO_FAILURE);
9620 +               return;
9621 +               }
9623 +       e_pk11 = engine_pk11();
9624 +       if (!e_pk11)
9625 +               {
9626 +               DSO_free(pk11_dso);
9627 +               pk11_dso = NULL;
9628 +               return;
9629 +               }
9631 +       /*
9632 +        * At this point, the pk11 shared library is either dynamically
9633 +        * loaded or statically linked in. So, initialize the pk11
9634 +        * library before calling ENGINE_set_default since the latter
9635 +        * needs cipher and digest algorithm information
9636 +        */
9637 +       if (!pk11_library_init(e_pk11))
9638 +               {
9639 +               DSO_free(pk11_dso);
9640 +               pk11_dso = NULL;
9641 +               ENGINE_free(e_pk11);
9642 +               return;
9643 +               }
9645 +       ENGINE_add(e_pk11);
9647 +       ENGINE_free(e_pk11);
9648 +       ERR_clear_error();
9649 +       }
9650 +#endif /* ENGINE_DYNAMIC_SUPPORT */
9653 + * These are the static string constants for the DSO file name and
9654 + * the function symbol names to bind to.
9655 + */
9656 +static const char *PK11_LIBNAME = NULL;
9658 +static const char *get_PK11_LIBNAME(void)
9659 +       {
9660 +       if (PK11_LIBNAME)
9661 +               return (PK11_LIBNAME);
9663 +       return (def_PK11_LIBNAME);
9664 +       }
9666 +static void free_PK11_LIBNAME(void)
9667 +       {
9668 +       if (PK11_LIBNAME)
9669 +               OPENSSL_free((void*)PK11_LIBNAME);
9671 +       PK11_LIBNAME = NULL;
9672 +       }
9674 +static long set_PK11_LIBNAME(const char *name)
9675 +       {
9676 +       free_PK11_LIBNAME();
9678 +       return ((PK11_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
9679 +       }
9681 +/* acquire all engine specific mutexes before fork */
9682 +static void pk11_fork_prepare(void)
9683 +       {
9684 +#ifndef NOPTHREADS
9685 +       int i;
9687 +       if (!pk11_library_initialized)
9688 +               return;
9690 +       LOCK_OBJSTORE(OP_RSA);
9691 +       OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
9692 +       for (i = 0; i < OP_MAX; i++)
9693 +               {
9694 +               OPENSSL_assert(pthread_mutex_lock(session_cache[i].lock) == 0);
9695 +               }
9696 +#endif
9697 +       }
9699 +/* release all engine specific mutexes */
9700 +static void pk11_fork_parent(void)
9701 +       {
9702 +#ifndef NOPTHREADS
9703 +       int i;
9705 +       if (!pk11_library_initialized)
9706 +               return;
9708 +       for (i = OP_MAX - 1; i >= 0; i--)
9709 +               {
9710 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[i].lock) == 0);
9711 +               }
9712 +       UNLOCK_OBJSTORE(OP_RSA);
9713 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
9714 +#endif
9715 +       }
9718 + * same situation as in parent - we need to unlock all locks to make them
9719 + * accessible to all threads.
9720 + */
9721 +static void pk11_fork_child(void)
9722 +       {
9723 +#ifndef NOPTHREADS
9724 +       int i;
9726 +       if (!pk11_library_initialized)
9727 +               return;
9729 +       for (i = OP_MAX - 1; i >= 0; i--)
9730 +               {
9731 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[i].lock) == 0);
9732 +               }
9733 +       UNLOCK_OBJSTORE(OP_RSA);
9734 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
9735 +#endif
9736 +       }
9738 +/* Initialization function for the pk11 engine */
9739 +static int pk11_init(ENGINE *e)
9741 +       return (pk11_library_init(e));
9744 +static CK_C_INITIALIZE_ARGS pk11_init_args =
9745 +       {
9746 +       NULL_PTR,               /* CreateMutex */
9747 +       NULL_PTR,               /* DestroyMutex */
9748 +       NULL_PTR,               /* LockMutex */
9749 +       NULL_PTR,               /* UnlockMutex */
9750 +       CKF_OS_LOCKING_OK,      /* flags */
9751 +       NULL_PTR,               /* pReserved */
9752 +       };
9755 + * Initialization function. Sets up various PKCS#11 library components.
9756 + * It selects a slot based on predefined critiera. In the process, it also
9757 + * count how many ciphers and digests to support. Since the cipher and
9758 + * digest information is needed when setting default engine, this function
9759 + * needs to be called before calling ENGINE_set_default.
9760 + */
9761 +/* ARGSUSED */
9762 +static int pk11_library_init(ENGINE *e)
9763 +       {
9764 +       CK_C_GetFunctionList p;
9765 +       CK_RV rv = CKR_OK;
9766 +       CK_INFO info;
9767 +       int any_slot_found;
9768 +       int i;
9769 +#ifndef OPENSSL_SYS_WIN32
9770 +       struct sigaction sigint_act, sigterm_act, sighup_act;
9771 +#endif
9773 +       /*
9774 +        * pk11_library_initialized is set to 0 in pk11_finish() which
9775 +        * is called from ENGINE_finish(). However, if there is still
9776 +        * at least one existing functional reference to the engine
9777 +        * (see engine(3) for more information), pk11_finish() is
9778 +        * skipped. For example, this can happen if an application
9779 +        * forgets to clear one cipher context. In case of a fork()
9780 +        * when the application is finishing the engine so that it can
9781 +        * be reinitialized in the child, forgotten functional
9782 +        * reference causes pk11_library_initialized to stay 1. In
9783 +        * that case we need the PID check so that we properly
9784 +        * initialize the engine again.
9785 +        */
9786 +       if (pk11_library_initialized)
9787 +               {
9788 +               if (pk11_pid == getpid())
9789 +                       {
9790 +                       return (1);
9791 +                       }
9792 +               else
9793 +                       {
9794 +                       global_session = CK_INVALID_HANDLE;
9795 +                       /*
9796 +                        * free the locks first to prevent memory leak in case
9797 +                        * the application calls fork() without finishing the
9798 +                        * engine first.
9799 +                        */
9800 +                       pk11_free_all_locks();
9801 +                       }
9802 +               }
9804 +       if (pk11_dso == NULL)
9805 +               {
9806 +               PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
9807 +               goto err;
9808 +               }
9810 +       /* get the C_GetFunctionList function from the loaded library */
9811 +       p = (CK_C_GetFunctionList)DSO_bind_func(pk11_dso,
9812 +               PK11_GET_FUNCTION_LIST);
9813 +       if (!p)
9814 +               {
9815 +               PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
9816 +               goto err;
9817 +               }
9819 +       /* get the full function list from the loaded library */
9820 +       rv = p(&pFuncList);
9821 +       if (rv != CKR_OK)
9822 +               {
9823 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE, rv);
9824 +               goto err;
9825 +               }
9827 +#ifndef OPENSSL_SYS_WIN32
9828 +       /* Not all PKCS#11 library are signal safe! */
9830 +       (void) memset(&sigint_act, 0, sizeof(sigint_act));
9831 +       (void) memset(&sigterm_act, 0, sizeof(sigterm_act));
9832 +       (void) memset(&sighup_act, 0, sizeof(sighup_act));
9833 +       (void) sigaction(SIGINT, NULL, &sigint_act);
9834 +       (void) sigaction(SIGTERM, NULL, &sigterm_act);
9835 +       (void) sigaction(SIGHUP, NULL, &sighup_act);
9836 +#endif
9837 +       rv = pFuncList->C_Initialize((CK_VOID_PTR)&pk11_init_args);
9838 +#ifndef OPENSSL_SYS_WIN32
9839 +       (void) sigaction(SIGINT, &sigint_act, NULL);
9840 +       (void) sigaction(SIGTERM, &sigterm_act, NULL);
9841 +       (void) sigaction(SIGHUP, &sighup_act, NULL);
9842 +#endif
9843 +       if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
9844 +               {
9845 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_INITIALIZE, rv);
9846 +               goto err;
9847 +               }
9849 +       rv = pFuncList->C_GetInfo(&info);
9850 +       if (rv != CKR_OK)
9851 +               {
9852 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_GETINFO, rv);
9853 +               goto err;
9854 +               }
9856 +       if (pk11_choose_slots(&any_slot_found) == 0)
9857 +               goto err;
9859 +       /*
9860 +        * The library we use, set in def_PK11_LIBNAME, may not offer any
9861 +        * slot(s). In that case, we must not proceed but we must not return an
9862 +        * error. The reason is that applications that try to set up the PKCS#11
9863 +        * engine don't exit on error during the engine initialization just
9864 +        * because no slot was present.
9865 +        */
9866 +       if (any_slot_found == 0)
9867 +               return (1);
9869 +       if (global_session == CK_INVALID_HANDLE)
9870 +               {
9871 +               /* Open the global_session for the new process */
9872 +               rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
9873 +                       NULL_PTR, NULL_PTR, &global_session);
9874 +               if (rv != CKR_OK)
9875 +                       {
9876 +                       PK11err_add_data(PK11_F_LIBRARY_INIT,
9877 +                           PK11_R_OPENSESSION, rv);
9878 +                       goto err;
9879 +                       }
9880 +               }
9882 +       pk11_library_initialized = TRUE;
9883 +       pk11_pid = getpid();
9884 +       /*
9885 +        * if initialization of the locks fails pk11_init_all_locks()
9886 +        * will do the cleanup.
9887 +        */
9888 +       if (!pk11_init_all_locks())
9889 +               goto err;
9890 +       for (i = 0; i < OP_MAX; i++)
9891 +               session_cache[i].head = NULL;
9892 +       /*
9893 +        * initialize active lists. We only use active lists
9894 +        * for asymmetric ciphers.
9895 +        */
9896 +       for (i = 0; i < OP_MAX; i++)
9897 +               active_list[i] = NULL;
9899 +#ifndef NOPTHREADS
9900 +       if (!pk11_atfork_initialized)
9901 +               {
9902 +               if (pthread_atfork(pk11_fork_prepare, pk11_fork_parent,
9903 +                   pk11_fork_child) != 0)
9904 +                       {
9905 +                       PK11err(PK11_F_LIBRARY_INIT, PK11_R_ATFORK_FAILED);
9906 +                       goto err;
9907 +                       }
9908 +               pk11_atfork_initialized = TRUE;
9909 +               }
9910 +#endif
9912 +       return (1);
9914 +err:
9915 +       return (0);
9916 +       }
9918 +/* Destructor (complements the "ENGINE_pk11()" constructor) */
9919 +/* ARGSUSED */
9920 +static int pk11_destroy(ENGINE *e)
9921 +       {
9922 +       free_PK11_LIBNAME();
9923 +       ERR_unload_pk11_strings();
9924 +       if (pk11_pin) {
9925 +               memset(pk11_pin, 0, strlen(pk11_pin));
9926 +               OPENSSL_free((void*)pk11_pin);
9927 +       }
9928 +       pk11_pin = NULL;
9929 +       return (1);
9930 +       }
9933 + * Termination function to clean up the session, the token, and the pk11
9934 + * library.
9935 + */
9936 +/* ARGSUSED */
9937 +static int pk11_finish(ENGINE *e)
9938 +       {
9939 +       int i;
9941 +       if (pk11_pin) {
9942 +               memset(pk11_pin, 0, strlen(pk11_pin));
9943 +               OPENSSL_free((void*)pk11_pin);
9944 +       }
9945 +       pk11_pin = NULL;
9947 +       if (pk11_dso == NULL)
9948 +               {
9949 +               PK11err(PK11_F_FINISH, PK11_R_NOT_LOADED);
9950 +               goto err;
9951 +               }
9953 +       OPENSSL_assert(pFuncList != NULL);
9955 +       if (pk11_free_all_sessions() == 0)
9956 +               goto err;
9958 +       /* free all active lists */
9959 +       for (i = 0; i < OP_MAX; i++)
9960 +               pk11_free_active_list(i);
9962 +       pFuncList->C_CloseSession(global_session);
9963 +       global_session = CK_INVALID_HANDLE;
9965 +       /*
9966 +        * Since we are part of a library (libcrypto.so), calling this function
9967 +        * may have side-effects.
9968 +        */
9969 +#if 0
9970 +       pFuncList->C_Finalize(NULL);
9971 +#endif
9973 +       if (!DSO_free(pk11_dso))
9974 +               {
9975 +               PK11err(PK11_F_FINISH, PK11_R_DSO_FAILURE);
9976 +               goto err;
9977 +               }
9978 +       pk11_dso = NULL;
9979 +       pFuncList = NULL;
9980 +       pk11_library_initialized = FALSE;
9981 +       pk11_pid = 0;
9982 +       /*
9983 +        * There is no way how to unregister atfork handlers (other than
9984 +        * unloading the library) so we just free the locks. For this reason
9985 +        * the atfork handlers check if the engine is initialized and bail out
9986 +        * immediately if not. This is necessary in case a process finishes
9987 +        * the engine before calling fork().
9988 +        */
9989 +       pk11_free_all_locks();
9991 +       return (1);
9993 +err:
9994 +       return (0);
9995 +       }
9997 +/* Standard engine interface function to set the dynamic library path */
9998 +/* ARGSUSED */
9999 +static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
10000 +       {
10001 +       int initialized = ((pk11_dso == NULL) ? 0 : 1);
10003 +       switch (cmd)
10004 +               {
10005 +       case PK11_CMD_SO_PATH:
10006 +               if (p == NULL)
10007 +                       {
10008 +                       PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
10009 +                       return (0);
10010 +                       }
10012 +               if (initialized)
10013 +                       {
10014 +                       PK11err(PK11_F_CTRL, PK11_R_ALREADY_LOADED);
10015 +                       return (0);
10016 +                       }
10018 +               return (set_PK11_LIBNAME((const char *)p));
10019 +       case PK11_CMD_PIN:
10020 +               if (pk11_pin) {
10021 +                       memset(pk11_pin, 0, strlen(pk11_pin));
10022 +                       OPENSSL_free((void*)pk11_pin);
10023 +               }
10024 +               pk11_pin = NULL;
10026 +               if (p == NULL)
10027 +                       {
10028 +                       PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
10029 +                       return (0);
10030 +                       }
10032 +               pk11_pin = BUF_strdup(p);
10033 +               if (pk11_pin == NULL)
10034 +                       {
10035 +                       PK11err(PK11_F_GET_SESSION, PK11_R_MALLOC_FAILURE);
10036 +                       return (0);
10037 +                       }
10038 +               return (1);
10039 +       case PK11_CMD_SLOT:
10040 +               SLOTID = (CK_SLOT_ID)i;
10041 +#ifdef DEBUG_SLOT_SELECTION
10042 +               fprintf(stderr, "%s: slot set\n", PK11_DBG);
10043 +#endif
10044 +               return (1);
10045 +       default:
10046 +               break;
10047 +               }
10049 +       PK11err(PK11_F_CTRL, PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED);
10051 +       return (0);
10052 +       }
10055 +/* Required function by the engine random interface. It does nothing here */
10056 +static void pk11_rand_cleanup(void)
10057 +       {
10058 +       return;
10059 +       }
10061 +/* ARGSUSED */
10062 +static void pk11_rand_add(const void *buf, int num, double add)
10063 +       {
10064 +       PK11_SESSION *sp;
10066 +       if ((sp = pk11_get_session(OP_RAND)) == NULL)
10067 +               return;
10069 +       /*
10070 +        * Ignore any errors (e.g. CKR_RANDOM_SEED_NOT_SUPPORTED) since
10071 +        * the calling functions do not care anyway
10072 +        */
10073 +       pFuncList->C_SeedRandom(sp->session, (unsigned char *) buf, num);
10074 +       pk11_return_session(sp, OP_RAND);
10076 +       return;
10077 +       }
10079 +static void pk11_rand_seed(const void *buf, int num)
10080 +       {
10081 +       pk11_rand_add(buf, num, 0);
10082 +       }
10084 +static int pk11_rand_bytes(unsigned char *buf, int num)
10085 +       {
10086 +       CK_RV rv;
10087 +       PK11_SESSION *sp;
10089 +       if ((sp = pk11_get_session(OP_RAND)) == NULL)
10090 +               return (0);
10092 +       rv = pFuncList->C_GenerateRandom(sp->session, buf, num);
10093 +       if (rv != CKR_OK)
10094 +               {
10095 +               PK11err_add_data(PK11_F_RAND_BYTES, PK11_R_GENERATERANDOM, rv);
10096 +               pk11_return_session(sp, OP_RAND);
10097 +               return (0);
10098 +               }
10100 +       pk11_return_session(sp, OP_RAND);
10101 +       return (1);
10102 +       }
10104 +/* Required function by the engine random interface. It does nothing here */
10105 +static int pk11_rand_status(void)
10106 +       {
10107 +       return (1);
10108 +       }
10110 +/* Free all BIGNUM structures from PK11_SESSION. */
10111 +static void pk11_free_nums(PK11_SESSION *sp, PK11_OPTYPE optype)
10112 +       {
10113 +       switch (optype)
10114 +               {
10115 +               case OP_RSA:
10116 +                       if (sp->opdata_rsa_n_num != NULL)
10117 +                               {
10118 +                               BN_free(sp->opdata_rsa_n_num);
10119 +                               sp->opdata_rsa_n_num = NULL;
10120 +                               }
10121 +                       if (sp->opdata_rsa_e_num != NULL)
10122 +                               {
10123 +                               BN_free(sp->opdata_rsa_e_num);
10124 +                               sp->opdata_rsa_e_num = NULL;
10125 +                               }
10126 +                       if (sp->opdata_rsa_pn_num != NULL)
10127 +                               {
10128 +                               BN_free(sp->opdata_rsa_pn_num);
10129 +                               sp->opdata_rsa_pn_num = NULL;
10130 +                               }
10131 +                       if (sp->opdata_rsa_pe_num != NULL)
10132 +                               {
10133 +                               BN_free(sp->opdata_rsa_pe_num);
10134 +                               sp->opdata_rsa_pe_num = NULL;
10135 +                               }
10136 +                       if (sp->opdata_rsa_d_num != NULL)
10137 +                               {
10138 +                               BN_free(sp->opdata_rsa_d_num);
10139 +                               sp->opdata_rsa_d_num = NULL;
10140 +                               }
10141 +                       break;
10142 +               default:
10143 +                       break;
10144 +               }
10145 +       }
10148 + * Get new PK11_SESSION structure ready for use. Every process must have
10149 + * its own freelist of PK11_SESSION structures so handle fork() here
10150 + * by destroying the old and creating new freelist.
10151 + * The returned PK11_SESSION structure is disconnected from the freelist.
10152 + */
10153 +PK11_SESSION *
10154 +pk11_get_session(PK11_OPTYPE optype)
10155 +       {
10156 +       PK11_SESSION *sp = NULL, *sp1, *freelist;
10157 +#ifndef NOPTHREADS
10158 +       pthread_mutex_t *freelist_lock = NULL;
10159 +#endif
10160 +       static pid_t pid = 0;
10161 +       pid_t new_pid;
10162 +       CK_RV rv;
10164 +       switch (optype)
10165 +               {
10166 +               case OP_RSA:
10167 +               case OP_DSA:
10168 +               case OP_DH:
10169 +               case OP_RAND:
10170 +               case OP_DIGEST:
10171 +               case OP_CIPHER:
10172 +#ifndef NOPTHREADS
10173 +                       freelist_lock = session_cache[optype].lock;
10174 +#endif
10175 +                       break;
10176 +               default:
10177 +                       PK11err(PK11_F_GET_SESSION,
10178 +                               PK11_R_INVALID_OPERATION_TYPE);
10179 +                       return (NULL);
10180 +               }
10181 +#ifndef NOPTHREADS
10182 +       OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
10183 +#else
10184 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
10185 +#endif
10187 +       /*
10188 +        * Will use it to find out if we forked. We cannot use the PID field in
10189 +        * the session structure because we could get a newly allocated session
10190 +        * here, with no PID information.
10191 +        */
10192 +       if (pid == 0)
10193 +               pid = getpid();
10195 +       freelist = session_cache[optype].head;
10196 +       sp = freelist;
10198 +       /*
10199 +        * If the free list is empty, allocate new unitialized (filled
10200 +        * with zeroes) PK11_SESSION structure otherwise return first
10201 +        * structure from the freelist.
10202 +        */
10203 +       if (sp == NULL)
10204 +               {
10205 +               if ((sp = OPENSSL_malloc(sizeof (PK11_SESSION))) == NULL)
10206 +                       {
10207 +                       PK11err(PK11_F_GET_SESSION,
10208 +                               PK11_R_MALLOC_FAILURE);
10209 +                       goto err;
10210 +                       }
10211 +               (void) memset(sp, 0, sizeof (PK11_SESSION));
10213 +               /*
10214 +                * It is a new session so it will look like a cache miss to the
10215 +                * code below. So, we must not try to to destroy its members so
10216 +                * mark them as unused.
10217 +                */
10218 +               sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
10219 +               sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
10220 +               }
10221 +       else
10222 +               {
10223 +               freelist = sp->next;
10224 +               }
10226 +       /*
10227 +        * Check whether we have forked. In that case, we must get rid of all
10228 +        * inherited sessions and start allocating new ones.
10229 +        */
10230 +       if (pid != (new_pid = getpid()))
10231 +               {
10232 +               pid = new_pid;
10234 +               /*
10235 +                * We are a new process and thus need to free any inherited
10236 +                * PK11_SESSION objects aside from the first session (sp) which
10237 +                * is the only PK11_SESSION structure we will reuse (for the
10238 +                * head of the list).
10239 +                */
10240 +               while ((sp1 = freelist) != NULL)
10241 +                       {
10242 +                       freelist = sp1->next;
10243 +                       /*
10244 +                        * NOTE: we do not want to call pk11_free_all_sessions()
10245 +                        * here because it would close underlying PKCS#11
10246 +                        * sessions and destroy all objects.
10247 +                        */
10248 +                       pk11_free_nums(sp1, optype);
10249 +                       OPENSSL_free(sp1);
10250 +                       }
10252 +               /* we have to free the active list as well. */
10253 +               pk11_free_active_list(optype);
10255 +               /* Initialize the process */
10256 +               rv = pFuncList->C_Initialize((CK_VOID_PTR)&pk11_init_args);
10257 +               if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
10258 +                       {
10259 +                       PK11err_add_data(PK11_F_GET_SESSION, PK11_R_INITIALIZE,
10260 +                           rv);
10261 +                       OPENSSL_free(sp);
10262 +                       sp = NULL;
10263 +                       goto err;
10264 +                       }
10266 +               /*
10267 +                * Choose slot here since the slot table is different on this
10268 +                * process. If we are here then we must have found at least one
10269 +                * usable slot before so we don't need to check any_slot_found.
10270 +                * See pk11_library_init()'s usage of this function for more
10271 +                * information.
10272 +                */
10273 +               if (pk11_choose_slots(NULL) == 0)
10274 +                       goto err;
10276 +               /* Open the global_session for the new process */
10277 +               rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
10278 +                       NULL_PTR, NULL_PTR, &global_session);
10279 +               if (rv != CKR_OK)
10280 +                       {
10281 +                       PK11err_add_data(PK11_F_GET_SESSION, PK11_R_OPENSESSION,
10282 +                           rv);
10283 +                       OPENSSL_free(sp);
10284 +                       sp = NULL;
10285 +                       goto err;
10286 +                       }
10288 +               /*
10289 +                * It is an inherited session from our parent so it needs
10290 +                * re-initialization.
10291 +                */
10292 +               if (pk11_setup_session(sp, optype) == 0)
10293 +                       {
10294 +                       OPENSSL_free(sp);
10295 +                       sp = NULL;
10296 +                       goto err;
10297 +                       }
10298 +               if (pk11_token_relogin(sp->session) == 0) 
10299 +                       {
10300 +                       /*
10301 +                        * We will keep the session in the cache list and let
10302 +                        * the caller cope with the situation.
10303 +                        */
10304 +                       freelist = sp;
10305 +                       sp = NULL;
10306 +                       goto err;
10307 +                       }
10308 +               }
10310 +       if (sp->pid == 0)
10311 +               {
10312 +               /* It is a new session and needs initialization. */
10313 +               if (pk11_setup_session(sp, optype) == 0)
10314 +                       {
10315 +                       OPENSSL_free(sp);
10316 +                       sp = NULL;
10317 +                       }
10318 +               }
10320 +       /* set new head for the list of PK11_SESSION objects */
10321 +       session_cache[optype].head = freelist;
10323 +err:
10324 +       if (sp != NULL)
10325 +               sp->next = NULL;
10327 +#ifndef NOPTHREADS
10328 +       OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
10329 +#else
10330 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
10331 +#endif
10333 +       return (sp);
10334 +       }
10337 +void
10338 +pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype)
10339 +       {
10340 +#ifndef NOPTHREADS
10341 +       pthread_mutex_t *freelist_lock;
10342 +#endif
10343 +       PK11_SESSION *freelist;
10345 +       /*
10346 +        * If this is a session from the parent it will be taken care of and
10347 +        * freed in pk11_get_session() as part of the post-fork clean up the
10348 +        * next time we will ask for a new session.
10349 +        */
10350 +       if (sp == NULL || sp->pid != getpid())
10351 +               return;
10353 +       switch (optype)
10354 +               {
10355 +               case OP_RSA:
10356 +               case OP_DSA:
10357 +               case OP_DH:
10358 +               case OP_RAND:
10359 +               case OP_DIGEST:
10360 +               case OP_CIPHER:
10361 +#ifndef NOPTHREADS
10362 +                       freelist_lock = session_cache[optype].lock;
10363 +#endif
10364 +                       break;
10365 +               default:
10366 +                       PK11err(PK11_F_RETURN_SESSION,
10367 +                               PK11_R_INVALID_OPERATION_TYPE);
10368 +                       return;
10369 +               }
10371 +#ifndef NOPTHREADS
10372 +       OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
10373 +#else
10374 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
10375 +#endif
10376 +       freelist = session_cache[optype].head;
10377 +       sp->next = freelist;
10378 +       session_cache[optype].head = sp;
10379 +#ifndef NOPTHREADS
10380 +       OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
10381 +#else
10382 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
10383 +#endif
10384 +       }
10387 +/* Destroy all objects. This function is called when the engine is finished */
10388 +static int pk11_free_all_sessions()
10389 +       {
10390 +       int ret = 1;
10391 +       int type;
10393 +       (void) pk11_destroy_rsa_key_objects(NULL);
10395 +       /*
10396 +        * We try to release as much as we can but any error means that we will
10397 +        * return 0 on exit.
10398 +        */
10399 +       for (type = 0; type < OP_MAX; type++)
10400 +               {
10401 +               if (pk11_free_session_list(type) == 0)
10402 +                       ret = 0;
10403 +               }
10405 +       return (ret);
10406 +       }
10409 + * Destroy session structures from the linked list specified. Free as many
10410 + * sessions as possible but any failure in C_CloseSession() means that we
10411 + * return an error on return.
10412 + */
10413 +static int pk11_free_session_list(PK11_OPTYPE optype)
10414 +       {
10415 +       CK_RV rv;
10416 +       PK11_SESSION *sp = NULL;
10417 +       PK11_SESSION *freelist = NULL;
10418 +       pid_t mypid = getpid();
10419 +#ifndef NOPTHREADS
10420 +       pthread_mutex_t *freelist_lock;
10421 +#endif
10422 +       int ret = 1;
10424 +       switch (optype)
10425 +               {
10426 +               case OP_RSA:
10427 +               case OP_DSA:
10428 +               case OP_DH:
10429 +               case OP_RAND:
10430 +               case OP_DIGEST:
10431 +               case OP_CIPHER:
10432 +#ifndef NOPTHREADS
10433 +                       freelist_lock = session_cache[optype].lock;
10434 +#endif
10435 +                       break;
10436 +               default:
10437 +                       PK11err(PK11_F_FREE_ALL_SESSIONS,
10438 +                               PK11_R_INVALID_OPERATION_TYPE);
10439 +                       return (0);
10440 +               }
10442 +#ifndef NOPTHREADS
10443 +       OPENSSL_assert(pthread_mutex_lock(freelist_lock) == 0);
10444 +#else
10445 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
10446 +#endif
10447 +       freelist = session_cache[optype].head;
10448 +       while ((sp = freelist) != NULL)
10449 +               {
10450 +               if (sp->session != CK_INVALID_HANDLE && sp->pid == mypid)
10451 +                       {
10452 +                       rv = pFuncList->C_CloseSession(sp->session);
10453 +                       if (rv != CKR_OK)
10454 +                               {
10455 +                               PK11err_add_data(PK11_F_FREE_ALL_SESSIONS,
10456 +                                       PK11_R_CLOSESESSION, rv);
10457 +                               ret = 0;
10458 +                               }
10459 +                       }
10460 +               freelist = sp->next;
10461 +               pk11_free_nums(sp, optype);
10462 +               OPENSSL_free(sp);
10463 +               }
10465 +#ifndef NOPTHREADS
10466 +       OPENSSL_assert(pthread_mutex_unlock(freelist_lock) == 0);
10467 +#else
10468 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
10469 +#endif
10470 +       return (ret);
10471 +       }
10474 +static int
10475 +pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype)
10476 +       {
10477 +       CK_RV rv;
10478 +       CK_SLOT_ID myslot;
10480 +       switch (optype)
10481 +               {
10482 +               case OP_RSA:
10483 +                       myslot = pubkey_SLOTID;
10484 +                       break;
10485 +               case OP_RAND:
10486 +                       myslot = rand_SLOTID;
10487 +                       break;
10488 +               default:
10489 +                       PK11err(PK11_F_SETUP_SESSION,
10490 +                           PK11_R_INVALID_OPERATION_TYPE);
10491 +                       return (0);
10492 +               }
10494 +       sp->session = CK_INVALID_HANDLE;
10495 +#ifdef DEBUG_SLOT_SELECTION
10496 +       fprintf(stderr, "%s: myslot=%d optype=%d\n", PK11_DBG, myslot, optype);
10497 +#endif /* DEBUG_SLOT_SELECTION */
10498 +       rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
10499 +               NULL_PTR, NULL_PTR, &sp->session);
10500 +       if (rv == CKR_CRYPTOKI_NOT_INITIALIZED)
10501 +               {
10502 +               /*
10503 +                * We are probably a child process so force the
10504 +                * reinitialize of the session
10505 +                */
10506 +               pk11_library_initialized = FALSE;
10507 +               if (!pk11_library_init(NULL))
10508 +                       return (0);
10509 +               rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
10510 +                       NULL_PTR, NULL_PTR, &sp->session);
10511 +               }
10512 +       if (rv != CKR_OK)
10513 +               {
10514 +               PK11err_add_data(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION, rv);
10515 +               return (0);
10516 +               }
10518 +       sp->pid = getpid();
10520 +       if (optype == OP_RSA)
10521 +               {
10522 +               sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
10523 +               sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
10524 +               sp->opdata_rsa_pub = NULL;
10525 +               sp->opdata_rsa_n_num = NULL;
10526 +               sp->opdata_rsa_e_num = NULL;
10527 +               sp->opdata_rsa_priv = NULL;
10528 +               sp->opdata_rsa_pn_num = NULL;
10529 +               sp->opdata_rsa_pe_num = NULL;
10530 +               sp->opdata_rsa_d_num = NULL;
10531 +               }
10533 +       /*
10534 +        * We always initialize the session as containing a non-persistent
10535 +        * object. The key load functions set it to persistent if that is so.
10536 +        */
10537 +       sp->pub_persistent = CK_FALSE;
10538 +       sp->priv_persistent = CK_FALSE;
10539 +       return (1);
10540 +       }
10542 +/* Destroy RSA public key from single session. */
10543 +int
10544 +pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
10545 +       {
10546 +       int ret = 0;
10548 +       if (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE)
10549 +               {
10550 +               TRY_OBJ_DESTROY(sp, sp->opdata_rsa_pub_key,
10551 +                   ret, uselock, OP_RSA, CK_FALSE);
10552 +               sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
10553 +               sp->opdata_rsa_pub = NULL;
10554 +               if (sp->opdata_rsa_n_num != NULL)
10555 +                       {
10556 +                       BN_free(sp->opdata_rsa_n_num);
10557 +                       sp->opdata_rsa_n_num = NULL;
10558 +                       }
10559 +               if (sp->opdata_rsa_e_num != NULL)
10560 +                       {
10561 +                       BN_free(sp->opdata_rsa_e_num);
10562 +                       sp->opdata_rsa_e_num = NULL;
10563 +                       }
10564 +               }
10566 +       return (ret);
10567 +       }
10569 +/* Destroy RSA private key from single session. */
10570 +int
10571 +pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
10572 +       {
10573 +       int ret = 0;
10575 +       if (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE)
10576 +               {
10577 +               TRY_OBJ_DESTROY(sp, sp->opdata_rsa_priv_key,
10578 +                   ret, uselock, OP_RSA, CK_TRUE);
10579 +               sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
10580 +               sp->opdata_rsa_priv = NULL;
10581 +               if (sp->opdata_rsa_d_num != NULL)
10582 +                       {
10583 +                       BN_free(sp->opdata_rsa_d_num);
10584 +                       sp->opdata_rsa_d_num = NULL;
10585 +                       }
10587 +               /*
10588 +                * For the RSA key by reference code, public components 'n'/'e'
10589 +                * are the key components we use to check for the cache hit. We
10590 +                * must free those as well.
10591 +                */
10592 +               if (sp->opdata_rsa_pn_num != NULL)
10593 +                       {
10594 +                       BN_free(sp->opdata_rsa_pn_num);
10595 +                       sp->opdata_rsa_pn_num = NULL;
10596 +                       }
10597 +               if (sp->opdata_rsa_pe_num != NULL)
10598 +                       {
10599 +                       BN_free(sp->opdata_rsa_pe_num);
10600 +                       sp->opdata_rsa_pe_num = NULL;
10601 +                       }
10602 +               }
10604 +       return (ret);
10605 +       }
10608 + * Destroy RSA key object wrapper. If session is NULL, try to destroy all
10609 + * objects in the free list.
10610 + */
10611 +int
10612 +pk11_destroy_rsa_key_objects(PK11_SESSION *session)
10613 +       {
10614 +       int ret = 1;
10615 +       PK11_SESSION *sp = NULL;
10616 +       PK11_SESSION *local_free_session;
10617 +       CK_BBOOL uselock = TRUE;
10619 +       if (session != NULL)
10620 +               local_free_session = session;
10621 +       else
10622 +               {
10623 +#ifndef NOPTHREADS
10624 +               OPENSSL_assert(pthread_mutex_lock(session_cache[OP_RSA].lock) == 0);
10625 +#else
10626 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
10627 +#endif
10628 +               local_free_session = session_cache[OP_RSA].head;
10629 +               uselock = FALSE;
10630 +               }
10632 +       /*
10633 +        * go through the list of sessions and delete key objects
10634 +        */
10635 +       while ((sp = local_free_session) != NULL)
10636 +               {
10637 +               local_free_session = sp->next;
10639 +               /*
10640 +                * Do not terminate list traversal if one of the
10641 +                * destroy operations fails.
10642 +                */
10643 +               if (pk11_destroy_rsa_object_pub(sp, uselock) == 0)
10644 +                       {
10645 +                       ret = 0;
10646 +                       continue;
10647 +                       }
10648 +               if (pk11_destroy_rsa_object_priv(sp, uselock) == 0)
10649 +                       {
10650 +                       ret = 0;
10651 +                       continue;
10652 +                       }
10653 +               }
10655 +#ifndef NOPTHREADS
10656 +       if (session == NULL)
10657 +               OPENSSL_assert(pthread_mutex_unlock(session_cache[OP_RSA].lock) == 0);
10658 +#else
10659 +       if (session == NULL)
10660 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
10661 +#endif
10663 +       return (ret);
10664 +       }
10666 +static int
10667 +pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh,
10668 +       CK_BBOOL persistent)
10669 +       {
10670 +       CK_RV rv;
10672 +       /*
10673 +        * We never try to destroy persistent objects which are the objects
10674 +        * stored in the keystore. Also, we always use read-only sessions so
10675 +        * C_DestroyObject() would be returning CKR_SESSION_READ_ONLY here.
10676 +        */
10677 +       if (persistent == CK_TRUE)
10678 +               return (1);
10680 +       rv = pFuncList->C_DestroyObject(session, oh);
10681 +       if (rv != CKR_OK)
10682 +               {
10683 +               PK11err_add_data(PK11_F_DESTROY_OBJECT, PK11_R_DESTROYOBJECT,
10684 +                   rv);
10685 +               return (0);
10686 +               }
10688 +       return (1);
10689 +       }
10693 + * Public key mechanisms optionally supported
10694 + *
10695 + * CKM_RSA_PKCS
10696 + *
10697 + * The first slot that supports at least one of those mechanisms is chosen as a
10698 + * public key slot.
10699 + *
10700 + * The output of this function is a set of global variables indicating which
10701 + * mechanisms from RSA, DSA, DH and RAND are present, and also two arrays of
10702 + * mechanisms, one for symmetric ciphers and one for digests. Also, 3 global
10703 + * variables carry information about which slot was chosen for (a) public key
10704 + * mechanisms, (b) random operations, and (c) symmetric ciphers and digests.
10705 + */
10706 +static int
10707 +pk11_choose_slots(int *any_slot_found)
10708 +       {
10709 +       CK_SLOT_ID_PTR pSlotList = NULL_PTR;
10710 +       CK_ULONG ulSlotCount = 0;
10711 +       CK_MECHANISM_INFO mech_info;
10712 +       CK_TOKEN_INFO token_info;
10713 +       unsigned int i;
10714 +       CK_RV rv;
10715 +       CK_SLOT_ID best_slot_sofar = 0;
10716 +       CK_BBOOL found_candidate_slot = CK_FALSE;
10717 +       CK_SLOT_ID current_slot = 0;
10719 +       /* let's initialize the output parameter */
10720 +       if (any_slot_found != NULL)
10721 +               *any_slot_found = 0;
10723 +       /* Get slot list for memory allocation */
10724 +       rv = pFuncList->C_GetSlotList(CK_FALSE, NULL_PTR, &ulSlotCount);
10726 +       if (rv != CKR_OK)
10727 +               {
10728 +               PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
10729 +               return (0);
10730 +               }
10732 +       /* it's not an error if we didn't find any providers */
10733 +       if (ulSlotCount == 0)
10734 +               {
10735 +#ifdef DEBUG_SLOT_SELECTION
10736 +               fprintf(stderr, "%s: no crypto providers found\n", PK11_DBG);
10737 +#endif /* DEBUG_SLOT_SELECTION */
10738 +               return (1);
10739 +               }
10741 +       pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
10743 +       if (pSlotList == NULL)
10744 +               {
10745 +               PK11err(PK11_F_CHOOSE_SLOT, PK11_R_MALLOC_FAILURE);
10746 +               return (0);
10747 +               }
10749 +       /* Get the slot list for processing */
10750 +       rv = pFuncList->C_GetSlotList(CK_FALSE, pSlotList, &ulSlotCount);
10751 +       if (rv != CKR_OK)
10752 +               {
10753 +               PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
10754 +               OPENSSL_free(pSlotList);
10755 +               return (0);
10756 +               }
10758 +#ifdef DEBUG_SLOT_SELECTION
10759 +       fprintf(stderr, "%s: provider: %s\n", PK11_DBG, def_PK11_LIBNAME);
10760 +       fprintf(stderr, "%s: number of slots: %d\n", PK11_DBG, ulSlotCount);
10762 +       fprintf(stderr, "%s: == checking rand slots ==\n", PK11_DBG);
10763 +#endif /* DEBUG_SLOT_SELECTION */
10764 +       for (i = 0; i < ulSlotCount; i++)
10765 +               {
10766 +               current_slot = pSlotList[i];
10768 +#ifdef DEBUG_SLOT_SELECTION
10769 +       fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
10770 +#endif /* DEBUG_SLOT_SELECTION */
10771 +               /* Check if slot has random support. */
10772 +               rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
10773 +               if (rv != CKR_OK)
10774 +                       continue;
10776 +#ifdef DEBUG_SLOT_SELECTION
10777 +       fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
10778 +#endif /* DEBUG_SLOT_SELECTION */
10780 +               if (token_info.flags & CKF_RNG)
10781 +                       {
10782 +#ifdef DEBUG_SLOT_SELECTION
10783 +       fprintf(stderr, "%s: this token has CKF_RNG flag\n", PK11_DBG);
10784 +#endif /* DEBUG_SLOT_SELECTION */
10785 +                       pk11_have_random = CK_TRUE;
10786 +                       rand_SLOTID = current_slot;
10787 +                       break;
10788 +                       }
10789 +               }
10791 +#ifdef DEBUG_SLOT_SELECTION
10792 +       fprintf(stderr, "%s: == checking pubkey slots ==\n", PK11_DBG);
10793 +#endif /* DEBUG_SLOT_SELECTION */
10795 +       pubkey_SLOTID = pSlotList[0];
10796 +       for (i = 0; i < ulSlotCount; i++)
10797 +               {
10798 +               CK_BBOOL slot_has_rsa = CK_FALSE;
10799 +               current_slot = pSlotList[i];
10801 +#ifdef DEBUG_SLOT_SELECTION
10802 +       fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
10803 +#endif /* DEBUG_SLOT_SELECTION */
10804 +               rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
10805 +               if (rv != CKR_OK)
10806 +                       continue;
10808 +#ifdef DEBUG_SLOT_SELECTION
10809 +       fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
10810 +#endif /* DEBUG_SLOT_SELECTION */
10812 +               /*
10813 +                * Check if this slot is capable of signing with CKM_RSA_PKCS.
10814 +                */
10815 +               rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS,
10816 +                       &mech_info);
10818 +               if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN)))
10819 +                       {
10820 +                       slot_has_rsa = CK_TRUE;
10821 +                       }
10823 +               if (!found_candidate_slot && slot_has_rsa)
10824 +                       {
10825 +#ifdef DEBUG_SLOT_SELECTION
10826 +                       fprintf(stderr,
10827 +                           "%s: potential slot: %d\n", PK11_DBG, current_slot);
10828 +#endif /* DEBUG_SLOT_SELECTION */
10829 +                       best_slot_sofar = current_slot;
10830 +                       pk11_have_rsa = slot_has_rsa;
10831 +                       found_candidate_slot = CK_TRUE;
10832 +                       /*
10833 +                        * Cache the flags for later use. We might
10834 +                        * need those if RSA keys by reference feature
10835 +                        * is used.
10836 +                        */
10837 +                       pubkey_token_flags = token_info.flags;
10838 +#ifdef DEBUG_SLOT_SELECTION
10839 +                       fprintf(stderr,
10840 +                           "%s: setting found_candidate_slot to CK_TRUE\n",
10841 +                           PK11_DBG);
10842 +                       fprintf(stderr,
10843 +                           "%s: best so far slot: %d\n", PK11_DBG,
10844 +                           best_slot_sofar);
10845 +                       fprintf(stderr, "%s: pubkey flags changed to "
10846 +                           "%lu.\n", PK11_DBG, pubkey_token_flags);
10847 +                       }
10848 +               else
10849 +                       {
10850 +                       fprintf(stderr,
10851 +                           "%s: no rsa\n", PK11_DBG);
10852 +                       }
10853 +#else
10854 +                       } /* if */
10855 +#endif /* DEBUG_SLOT_SELECTION */
10856 +               } /* for */
10858 +       if (found_candidate_slot == CK_TRUE)
10859 +               {
10860 +               pubkey_SLOTID = best_slot_sofar;
10861 +               }
10863 +       /*SLOTID = pSlotList[0];*/
10865 +#ifdef DEBUG_SLOT_SELECTION
10866 +       fprintf(stderr,
10867 +           "%s: chosen pubkey slot: %d\n", PK11_DBG, pubkey_SLOTID);
10868 +       fprintf(stderr,
10869 +           "%s: chosen rand slot: %d\n", PK11_DBG, rand_SLOTID);
10870 +       fprintf(stderr,
10871 +           "%s: pk11_have_rsa %d\n", PK11_DBG, pk11_have_rsa);
10872 +       fprintf(stderr,
10873 +           "%s: pk11_have_random %d\n", PK11_DBG, pk11_have_random);
10874 +#endif /* DEBUG_SLOT_SELECTION */
10876 +       if (pSlotList != NULL)
10877 +               OPENSSL_free(pSlotList);
10879 +       if (any_slot_found != NULL)
10880 +               *any_slot_found = 1;
10881 +       return (1);
10882 +       }
10884 +#endif /* OPENSSL_NO_HW_PK11SO */
10885 +#endif /* OPENSSL_NO_HW_PK11 */
10886 +#endif /* OPENSSL_NO_HW */
10887 Index: openssl/crypto/engine/hw_pk11so.h
10888 diff -u /dev/null openssl/crypto/engine/hw_pk11so.h:1.4
10889 --- /dev/null   Fri Jan  2 14:59:08 2015
10890 +++ openssl/crypto/engine/hw_pk11so.h   Wed Jun 15 21:12:20 2011
10891 @@ -0,0 +1,32 @@
10892 +/* Redefine all pk11/PK11 external symbols to pk11so/PK11SO */
10894 +#define token_lock                     pk11so_token_lock
10895 +#define find_lock                      pk11so_find_lock
10896 +#define active_list                    pk11so_active_list
10897 +#define pubkey_token_flags             pk11so_pubkey_token_flags
10898 +#define pubkey_SLOTID                  pk11so_pubkey_SLOTID
10899 +#define ERR_pk11_error                 ERR_pk11so_error
10900 +#define PK11err_add_data               PK11SOerr_add_data
10901 +#define pk11_get_session               pk11so_get_session
10902 +#define pk11_return_session            pk11so_return_session
10903 +#define pk11_active_add                        pk11so_active_add
10904 +#define pk11_active_delete             pk11so_active_delete
10905 +#define pk11_active_remove             pk11so_active_remove
10906 +#define pk11_free_active_list          pk11so_free_active_list
10907 +#define pk11_destroy_rsa_key_objects   pk11so_destroy_rsa_key_objects
10908 +#define pk11_destroy_rsa_object_pub    pk11so_destroy_rsa_object_pub
10909 +#define pk11_destroy_rsa_object_priv   pk11so_destroy_rsa_object_priv
10910 +#define pk11_load_privkey              pk11so_load_privkey
10911 +#define pk11_load_pubkey               pk11so_load_pubkey
10912 +#define PK11_RSA                       PK11SO_RSA
10913 +#define pk11_destroy_dsa_key_objects   pk11so_destroy_dsa_key_objects
10914 +#define pk11_destroy_dsa_object_pub    pk11so_destroy_dsa_object_pub
10915 +#define pk11_destroy_dsa_object_priv   pk11so_destroy_dsa_object_priv
10916 +#define PK11_DSA                       PK11SO_DSA
10917 +#define pk11_destroy_dh_key_objects    pk11so_destroy_dh_key_objects
10918 +#define pk11_destroy_dh_object         pk11so_destroy_dh_object
10919 +#define PK11_DH                                PK11SO_DH
10920 +#define pk11_token_relogin             pk11so_token_relogin
10921 +#define pFuncList                      pk11so_pFuncList
10922 +#define pk11_pin                       pk11so_pin
10923 +#define ENGINE_load_pk11               ENGINE_load_pk11so
10924 Index: openssl/crypto/engine/hw_pk11so_pub.c
10925 diff -u /dev/null openssl/crypto/engine/hw_pk11so_pub.c:1.10
10926 --- /dev/null   Fri Jan  2 14:59:08 2015
10927 +++ openssl/crypto/engine/hw_pk11so_pub.c       Fri Oct  4 14:05:38 2013
10928 @@ -0,0 +1,1642 @@
10930 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
10931 + * Use is subject to license terms.
10932 + */
10934 +/* crypto/engine/hw_pk11_pub.c */
10936 + * This product includes software developed by the OpenSSL Project for
10937 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
10938 + *
10939 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
10940 + * Afchine Madjlessi.
10941 + */
10943 + * ====================================================================
10944 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
10945 + *
10946 + * Redistribution and use in source and binary forms, with or without
10947 + * modification, are permitted provided that the following conditions
10948 + * are met:
10949 + *
10950 + * 1. Redistributions of source code must retain the above copyright
10951 + *    notice, this list of conditions and the following disclaimer.
10952 + *
10953 + * 2. Redistributions in binary form must reproduce the above copyright
10954 + *    notice, this list of conditions and the following disclaimer in
10955 + *    the documentation and/or other materials provided with the
10956 + *    distribution.
10957 + *
10958 + * 3. All advertising materials mentioning features or use of this
10959 + *    software must display the following acknowledgment:
10960 + *    "This product includes software developed by the OpenSSL Project
10961 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
10962 + *
10963 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
10964 + *    endorse or promote products derived from this software without
10965 + *    prior written permission. For written permission, please contact
10966 + *    licensing@OpenSSL.org.
10967 + *
10968 + * 5. Products derived from this software may not be called "OpenSSL"
10969 + *    nor may "OpenSSL" appear in their names without prior written
10970 + *    permission of the OpenSSL Project.
10971 + *
10972 + * 6. Redistributions of any form whatsoever must retain the following
10973 + *    acknowledgment:
10974 + *    "This product includes software developed by the OpenSSL Project
10975 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
10976 + *
10977 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
10978 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
10979 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
10980 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
10981 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
10982 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
10983 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
10984 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
10985 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
10986 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
10987 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
10988 + * OF THE POSSIBILITY OF SUCH DAMAGE.
10989 + * ====================================================================
10990 + *
10991 + * This product includes cryptographic software written by Eric Young
10992 + * (eay@cryptsoft.com).  This product includes software written by Tim
10993 + * Hudson (tjh@cryptsoft.com).
10994 + *
10995 + */
10997 +/* Modified to keep only RNG and RSA Sign */
10999 +#ifdef OPENSSL_NO_RSA
11000 +#error RSA is disabled
11001 +#endif
11003 +#include <stdio.h>
11004 +#include <stdlib.h>
11005 +#include <string.h>
11006 +#include <sys/types.h>
11008 +#include <openssl/e_os2.h>
11009 +#include <openssl/crypto.h>
11010 +#include <cryptlib.h>
11011 +#include <openssl/engine.h>
11012 +#include <openssl/dso.h>
11013 +#include <openssl/err.h>
11014 +#include <openssl/bn.h>
11015 +#include <openssl/pem.h>
11016 +#include <openssl/rsa.h>
11017 +#include <openssl/rand.h>
11018 +#include <openssl/objects.h>
11019 +#include <openssl/x509.h>
11021 +#ifdef OPENSSL_SYS_WIN32
11022 +#define NOPTHREADS
11023 +typedef int pid_t;
11024 +#define HAVE_GETPASSPHRASE
11025 +static char *getpassphrase(const char *prompt);
11026 +#ifndef NULL_PTR
11027 +#define NULL_PTR NULL
11028 +#endif
11029 +#define CK_DEFINE_FUNCTION(returnType, name) \
11030 +       returnType __declspec(dllexport) name
11031 +#define CK_DECLARE_FUNCTION(returnType, name) \
11032 +       returnType __declspec(dllimport) name
11033 +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
11034 +       returnType __declspec(dllimport) (* name)
11035 +#else
11036 +#include <unistd.h>
11037 +#endif
11039 +#ifndef NOPTHREADS
11040 +#include <pthread.h>
11041 +#endif
11043 +#ifndef OPENSSL_NO_HW
11044 +#ifndef OPENSSL_NO_HW_PK11
11045 +#ifndef OPENSSL_NO_HW_PK11SO
11047 +#ifdef OPENSSL_SYS_WIN32
11048 +#pragma pack(push, cryptoki, 1)
11049 +#include "cryptoki.h"
11050 +#include "pkcs11.h"
11051 +#pragma pack(pop, cryptoki)
11052 +#else
11053 +#include "cryptoki.h"
11054 +#include "pkcs11.h"
11055 +#endif
11056 +#include "hw_pk11so.h"
11057 +#include "hw_pk11_err.h"
11059 +static CK_BBOOL pk11_login_done = CK_FALSE;
11060 +extern CK_SLOT_ID pubkey_SLOTID;
11061 +#ifndef NOPTHREADS
11062 +extern pthread_mutex_t *token_lock;
11063 +#endif
11065 +#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun)))
11066 +#define getpassphrase(x)       getpass(x)
11067 +#endif
11069 +/* RSA stuff */
11070 +static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
11071 +       unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
11072 +EVP_PKEY *pk11_load_privkey(ENGINE*, const char *privkey_file,
11073 +       UI_METHOD *ui_method, void *callback_data);
11074 +EVP_PKEY *pk11_load_pubkey(ENGINE*, const char *pubkey_file,
11075 +       UI_METHOD *ui_method, void *callback_data);
11077 +static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA* rsa, RSA** key_ptr,
11078 +       BIGNUM **rsa_n_num, BIGNUM **rsa_e_num, CK_SESSION_HANDLE session);
11079 +static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa, RSA** key_ptr,
11080 +       BIGNUM **rsa_d_num, BIGNUM **rsa_n_num, BIGNUM **rsa_e_num,
11081 +       CK_SESSION_HANDLE session);
11083 +static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa);
11084 +static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa);
11086 +static int find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
11087 +       CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey);
11088 +static int init_template_value(BIGNUM *bn, CK_VOID_PTR *pValue,
11089 +       CK_ULONG *ulValueLen);
11090 +static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn);
11092 +static int pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
11093 +       CK_BBOOL is_private);
11095 +/* Read mode string to be used for fopen() */
11096 +#if SOLARIS_OPENSSL
11097 +static char *read_mode_flags = "rF";
11098 +#else
11099 +static char *read_mode_flags = "r";
11100 +#endif
11103 + * increment/create reference for an asymmetric key handle via active list
11104 + * manipulation. If active list operation fails, unlock (if locked), set error
11105 + * variable and jump to the specified label.
11106 + */
11107 +#define        KEY_HANDLE_REFHOLD(key_handle, alg_type, unlock, var, label)    \
11108 +       {                                                               \
11109 +       if (pk11_active_add(key_handle, alg_type) < 0)                  \
11110 +               {                                                       \
11111 +               var = TRUE;                                             \
11112 +               if (unlock)                                             \
11113 +                       UNLOCK_OBJSTORE(alg_type);                      \
11114 +               goto label;                                             \
11115 +               }                                                       \
11116 +       }
11119 + * Find active list entry according to object handle and return pointer to the
11120 + * entry otherwise return NULL.
11121 + *
11122 + * This function presumes it is called with lock protecting the active list
11123 + * held.
11124 + */
11125 +static PK11_active *pk11_active_find(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
11126 +       {
11127 +       PK11_active *entry;
11129 +       for (entry = active_list[type]; entry != NULL; entry = entry->next)
11130 +               if (entry->h == h)
11131 +                       return (entry);
11133 +       return (NULL);
11134 +       }
11137 + * Search for an entry in the active list using PKCS#11 object handle as a
11138 + * search key and return refcnt of the found/created entry or -1 in case of
11139 + * failure.
11140 + *
11141 + * This function presumes it is called with lock protecting the active list
11142 + * held.
11143 + */
11144 +int
11145 +pk11_active_add(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
11146 +       {
11147 +       PK11_active *entry = NULL;
11149 +       if (h == CK_INVALID_HANDLE)
11150 +               {
11151 +               PK11err(PK11_F_ACTIVE_ADD, PK11_R_INVALID_HANDLE);
11152 +               return (-1);
11153 +               }
11155 +       /* search for entry in the active list */
11156 +       if ((entry = pk11_active_find(h, type)) != NULL)
11157 +               entry->refcnt++;
11158 +       else
11159 +               {
11160 +               /* not found, create new entry and add it to the list */
11161 +               entry = OPENSSL_malloc(sizeof (PK11_active));
11162 +               if (entry == NULL)
11163 +                       {
11164 +                       PK11err(PK11_F_ACTIVE_ADD, PK11_R_MALLOC_FAILURE);
11165 +                       return (-1);
11166 +                       }
11167 +               entry->h = h;
11168 +               entry->refcnt = 1;
11169 +               entry->prev = NULL;
11170 +               entry->next = NULL;
11171 +               /* connect the newly created entry to the list */
11172 +               if (active_list[type] == NULL)
11173 +                       active_list[type] = entry;
11174 +               else /* make the entry first in the list */
11175 +                       {
11176 +                       entry->next = active_list[type];
11177 +                       active_list[type]->prev = entry;
11178 +                       active_list[type] = entry;
11179 +                       }
11180 +               }
11182 +       return (entry->refcnt);
11183 +       }
11186 + * Remove active list entry from the list and free it.
11187 + *
11188 + * This function presumes it is called with lock protecting the active list
11189 + * held.
11190 + */
11191 +void
11192 +pk11_active_remove(PK11_active *entry, PK11_OPTYPE type)
11193 +       {
11194 +       PK11_active *prev_entry;
11196 +       /* remove the entry from the list and free it */
11197 +       if ((prev_entry = entry->prev) != NULL)
11198 +               {
11199 +               prev_entry->next = entry->next;
11200 +               if (entry->next != NULL)
11201 +                       entry->next->prev = prev_entry;
11202 +               }
11203 +       else
11204 +               {
11205 +               active_list[type] = entry->next;
11206 +               /* we were the first but not the only one */
11207 +               if (entry->next != NULL)
11208 +                       entry->next->prev = NULL;
11209 +               }
11211 +       /* sanitization */
11212 +       entry->h = CK_INVALID_HANDLE;
11213 +       entry->prev = NULL;
11214 +       entry->next = NULL;
11215 +       OPENSSL_free(entry);
11216 +       }
11218 +/* Free all entries from the active list. */
11219 +void
11220 +pk11_free_active_list(PK11_OPTYPE type)
11221 +       {
11222 +       PK11_active *entry;
11224 +       /* only for asymmetric types since only they have C_Find* locks. */
11225 +       switch (type)
11226 +               {
11227 +               case OP_RSA:
11228 +                       break;
11229 +               default:
11230 +                       return;
11231 +               }
11233 +       /* see find_lock array definition for more info on object locking */
11234 +       LOCK_OBJSTORE(type);
11235 +       while ((entry = active_list[type]) != NULL)
11236 +               pk11_active_remove(entry, type);
11237 +       UNLOCK_OBJSTORE(type);
11238 +       }
11241 + * Search for active list entry associated with given PKCS#11 object handle,
11242 + * decrement its refcnt and if it drops to 0, disconnect the entry and free it.
11243 + *
11244 + * Return 1 if the PKCS#11 object associated with the entry has no references,
11245 + * return 0 if there is at least one reference, -1 on error.
11246 + *
11247 + * This function presumes it is called with lock protecting the active list
11248 + * held.
11249 + */
11250 +int
11251 +pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
11252 +       {
11253 +       PK11_active *entry = NULL;
11255 +       if ((entry = pk11_active_find(h, type)) == NULL)
11256 +               {
11257 +               PK11err(PK11_F_ACTIVE_DELETE, PK11_R_INVALID_HANDLE);
11258 +               return (-1);
11259 +               }
11261 +       OPENSSL_assert(entry->refcnt > 0);
11262 +       entry->refcnt--;
11263 +       if (entry->refcnt == 0)
11264 +               {
11265 +               pk11_active_remove(entry, type);
11266 +               return (1);
11267 +               }
11269 +       return (0);
11270 +       }
11272 +/* Our internal RSA_METHOD that we provide pointers to */
11273 +static RSA_METHOD pk11_rsa;
11275 +RSA_METHOD *
11276 +PK11_RSA(void)
11277 +       {
11278 +       const RSA_METHOD *rsa;
11280 +       if (pk11_rsa.name == NULL)
11281 +               {
11282 +               rsa = RSA_PKCS1_SSLeay();
11283 +               memcpy(&pk11_rsa, rsa, sizeof(*rsa));
11284 +               pk11_rsa.name = "PKCS#11 RSA method";
11285 +               pk11_rsa.rsa_sign = pk11_RSA_sign;
11286 +               }
11287 +       return (&pk11_rsa);
11288 +       }
11290 +/* Size of an SSL signature: MD5+SHA1 */
11291 +#define        SSL_SIG_LENGTH          36
11293 +static CK_BBOOL mytrue = TRUE;
11294 +static CK_BBOOL myfalse = FALSE;
11297 + * Standard engine interface function. Majority codes here are from
11298 + * rsa/rsa_sign.c. We replaced the decrypt function call by C_Sign of PKCS#11.
11299 + * See more details in rsa/rsa_sign.c
11300 + */
11301 +static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
11302 +       unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
11303 +       {
11304 +       X509_SIG sig;
11305 +       ASN1_TYPE parameter;
11306 +       int i, j = 0;
11307 +       unsigned char *p, *s = NULL;
11308 +       X509_ALGOR algor;
11309 +       ASN1_OCTET_STRING digest;
11310 +       CK_RV rv;
11311 +       CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
11312 +       CK_MECHANISM *p_mech = &mech_rsa;
11313 +       CK_OBJECT_HANDLE h_priv_key;
11314 +       PK11_SESSION *sp = NULL;
11315 +       int ret = 0;
11316 +       unsigned long ulsiglen;
11318 +       /* Encode the digest */
11319 +       /* Special case: SSL signature, just check the length */
11320 +       if (type == NID_md5_sha1)
11321 +               {
11322 +               if (m_len != SSL_SIG_LENGTH)
11323 +                       {
11324 +                       PK11err(PK11_F_RSA_SIGN,
11325 +                               PK11_R_INVALID_MESSAGE_LENGTH);
11326 +                       goto err;
11327 +                       }
11328 +               i = SSL_SIG_LENGTH;
11329 +               s = (unsigned char *)m;
11330 +               }
11331 +       else
11332 +               {
11333 +               sig.algor = &algor;
11334 +               sig.algor->algorithm = OBJ_nid2obj(type);
11335 +               if (sig.algor->algorithm == NULL)
11336 +                       {
11337 +                       PK11err(PK11_F_RSA_SIGN,
11338 +                               PK11_R_UNKNOWN_ALGORITHM_TYPE);
11339 +                       goto err;
11340 +                       }
11341 +               if (sig.algor->algorithm->length == 0)
11342 +                       {
11343 +                       PK11err(PK11_F_RSA_SIGN,
11344 +                               PK11_R_UNKNOWN_ASN1_OBJECT_ID);
11345 +                       goto err;
11346 +                       }
11347 +               parameter.type = V_ASN1_NULL;
11348 +               parameter.value.ptr = NULL;
11349 +               sig.algor->parameter = &parameter;
11351 +               sig.digest = &digest;
11352 +               sig.digest->data = (unsigned char *)m;
11353 +               sig.digest->length = m_len;
11355 +               i = i2d_X509_SIG(&sig, NULL);
11356 +               }
11358 +       j = RSA_size(rsa);
11359 +       if ((i - RSA_PKCS1_PADDING) > j)
11360 +               {
11361 +               PK11err(PK11_F_RSA_SIGN, PK11_R_DIGEST_TOO_BIG);
11362 +               goto err;
11363 +               }
11365 +       if (type != NID_md5_sha1)
11366 +               {
11367 +               s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
11368 +               if (s == NULL)
11369 +                       {
11370 +                       PK11err(PK11_F_RSA_SIGN, PK11_R_MALLOC_FAILURE);
11371 +                       goto err;
11372 +                       }
11373 +               p = s;
11374 +               (void) i2d_X509_SIG(&sig, &p);
11375 +               }
11377 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
11378 +               goto err;
11380 +       (void) check_new_rsa_key_priv(sp, rsa);
11382 +       h_priv_key = sp->opdata_rsa_priv_key;
11383 +       if (h_priv_key == CK_INVALID_HANDLE)
11384 +               h_priv_key = sp->opdata_rsa_priv_key =
11385 +                       pk11_get_private_rsa_key((RSA *)rsa,
11386 +                           &sp->opdata_rsa_priv, &sp->opdata_rsa_d_num,
11387 +                           &sp->opdata_rsa_pn_num, &sp->opdata_rsa_pe_num,
11388 +                           sp->session);
11390 +       if (h_priv_key != CK_INVALID_HANDLE)
11391 +               {
11392 +               rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
11394 +               if (rv != CKR_OK)
11395 +                       {
11396 +                       PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGNINIT, rv);
11397 +                       goto err;
11398 +                       }
11400 +               ulsiglen = j;
11401 +               rv = pFuncList->C_Sign(sp->session, s, i, sigret,
11402 +                       (CK_ULONG_PTR) &ulsiglen);
11403 +               *siglen = ulsiglen;
11405 +               if (rv != CKR_OK)
11406 +                       {
11407 +                       PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGN, rv);
11408 +                       goto err;
11409 +                       }
11410 +               ret = 1;
11411 +               }
11413 +err:
11414 +       if ((type != NID_md5_sha1) && (s != NULL))
11415 +               {
11416 +               (void) memset(s, 0, (unsigned int)(j + 1));
11417 +               OPENSSL_free(s);
11418 +               }
11420 +       pk11_return_session(sp, OP_RSA);
11421 +       return (ret);
11422 +       }
11424 +static int hndidx_rsa = -1;
11426 +#define        MAXATTR 1024
11429 + * Load RSA private key from a file or get its PKCS#11 handle if stored in the
11430 + * PKCS#11 token.
11431 + */
11432 +/* ARGSUSED */
11433 +EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *privkey_file,
11434 +       UI_METHOD *ui_method, void *callback_data)
11435 +       {
11436 +       EVP_PKEY *pkey = NULL;
11437 +       FILE *privkey;
11438 +       CK_OBJECT_HANDLE  h_priv_key = CK_INVALID_HANDLE;
11439 +       RSA *rsa = NULL;
11440 +       PK11_SESSION *sp;
11441 +       /* Anything else below is needed for the key by reference extension. */
11442 +       CK_RV rv;
11443 +       CK_BBOOL is_token = TRUE;
11444 +       CK_BBOOL rollback = FALSE;
11445 +       CK_BYTE attr_data[2][MAXATTR];
11446 +       CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
11447 +       CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;    /* key in keystore */
11449 +       /* we look for private keys only */
11450 +       CK_ATTRIBUTE search_templ[] =
11451 +               {
11452 +               {CKA_TOKEN, &is_token, sizeof(is_token)},
11453 +               {CKA_CLASS, &key_class, sizeof(key_class)},
11454 +               {CKA_LABEL, NULL, 0}
11455 +               };
11457 +       /*
11458 +        * These public attributes are needed to initialize the OpenSSL RSA
11459 +        * structure with something we can use to look up the key. Note that we
11460 +        * never ask for private components.
11461 +        */
11462 +       CK_ATTRIBUTE get_templ[] =
11463 +               {
11464 +               {CKA_MODULUS, (void *)attr_data[0], MAXATTR},           /* n */
11465 +               {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},   /* e */
11466 +               };
11468 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
11469 +               return (NULL);
11471 +       /*
11472 +        * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
11473 +        */
11474 +       if (strstr(privkey_file, "pkcs11:") == privkey_file)
11475 +               {
11476 +               search_templ[2].pValue = strstr(privkey_file, ":") + 1;
11477 +               search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
11479 +               if (pk11_token_login(sp->session, &pk11_login_done,
11480 +                   CK_TRUE) == 0)
11481 +                       goto err;
11483 +               /* see find_lock array definition
11484 +                  for more info on object locking */
11485 +               LOCK_OBJSTORE(OP_RSA);
11487 +               /*
11488 +                * Now let's try to find the key in the token. It is a failure
11489 +                * if we can't find it.
11490 +                */
11491 +               if (find_one_object(OP_RSA, sp->session, search_templ, 3,
11492 +                   &ks_key) == 0)
11493 +                       {
11494 +                       UNLOCK_OBJSTORE(OP_RSA);
11495 +                       goto err;
11496 +                       }
11498 +               if (hndidx_rsa == -1)
11499 +                       hndidx_rsa = RSA_get_ex_new_index(0,
11500 +                                       "pkcs11 RSA HSM key handle",
11501 +                                       NULL, NULL, NULL);
11503 +               /*
11504 +                * We might have a cache hit which we could confirm
11505 +                * according to the 'n'/'e' params, RSA public pointer
11506 +                * as NULL, and non-NULL RSA private pointer. However,
11507 +                * it is easier just to recreate everything. We expect
11508 +                * the keys to be loaded once and used many times. We
11509 +                * do not check the return value because even in case
11510 +                * of failure the sp structure will have both key
11511 +                * pointer and object handle cleaned and
11512 +                * pk11_destroy_object() reports the failure to the
11513 +                * OpenSSL error message buffer.
11514 +                */
11515 +               (void) pk11_destroy_rsa_object_priv(sp, FALSE);
11517 +               sp->opdata_rsa_priv_key = ks_key;
11518 +               /* This object shall not be deleted on a cache miss. */
11519 +               sp->priv_persistent = CK_TRUE;
11521 +               /*
11522 +                * Cache the RSA private structure pointer. We do not
11523 +                * use it now for key-by-ref keys but let's do it for
11524 +                * consistency reasons.
11525 +                */
11526 +               if ((rsa = sp->opdata_rsa_priv = RSA_new_method(e)) == NULL)
11527 +                       {
11528 +                       UNLOCK_OBJSTORE(OP_RSA);
11529 +                       goto err;
11530 +                       }
11532 +               /*
11533 +                * Now we have to initialize an OpenSSL RSA structure,
11534 +                * everything else is 0 or NULL.
11535 +                */
11536 +               rsa->flags = RSA_FLAG_SIGN_VER | RSA_FLAG_EXT_PKEY;
11537 +               RSA_set_ex_data(rsa, hndidx_rsa, (void *) ks_key);
11539 +               if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
11540 +                   get_templ, 2)) != CKR_OK)
11541 +                       {
11542 +                       UNLOCK_OBJSTORE(OP_RSA);
11543 +                       PK11err_add_data(PK11_F_LOAD_PRIVKEY,
11544 +                                        PK11_R_GETATTRIBUTVALUE, rv);
11545 +                       goto err;
11546 +                       }
11548 +               /*
11549 +                * We do not use pk11_get_private_rsa_key() here so we
11550 +                * must take care of handle management ourselves.
11551 +                */
11552 +               KEY_HANDLE_REFHOLD(ks_key, OP_RSA, TRUE, rollback, err);
11554 +               /*
11555 +                * Those are the sensitive components we do not want to export
11556 +                * from the token at all: rsa->(d|p|q|dmp1|dmq1|iqmp).
11557 +                */
11558 +               attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
11559 +               attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
11560 +               /*
11561 +                * Must have 'n'/'e' components in the session structure as
11562 +                * well. They serve as a public look-up key for the private key
11563 +                * in the keystore.
11564 +                */
11565 +               attr_to_BN(&get_templ[0], attr_data[0],
11566 +                       &sp->opdata_rsa_pn_num);
11567 +               attr_to_BN(&get_templ[1], attr_data[1],
11568 +                       &sp->opdata_rsa_pe_num);
11570 +               UNLOCK_OBJSTORE(OP_RSA);
11572 +               if ((pkey = EVP_PKEY_new()) == NULL)
11573 +                       goto err;
11575 +               if (EVP_PKEY_assign_RSA(pkey, rsa) == 0)
11576 +                       goto err;
11577 +               }
11578 +       else if ((privkey = fopen(privkey_file, read_mode_flags)) != NULL)
11579 +               {
11580 +               pkey = PEM_read_PrivateKey(privkey, NULL, NULL, NULL);
11581 +               (void) fclose(privkey);
11582 +               if (pkey != NULL)
11583 +                       {
11584 +                       rsa = EVP_PKEY_get1_RSA(pkey);
11585 +                       if (rsa != NULL)
11586 +                               {
11587 +                               /*
11588 +                                * This will always destroy the RSA
11589 +                                * object since we have a new RSA
11590 +                                * structure here.
11591 +                                */
11592 +                               (void) check_new_rsa_key_priv(sp, rsa);
11593 +                               sp->priv_persistent = CK_FALSE;
11595 +                               h_priv_key = sp->opdata_rsa_priv_key =
11596 +                                   pk11_get_private_rsa_key(rsa,
11597 +                                   &sp->opdata_rsa_priv,
11598 +                                   &sp->opdata_rsa_d_num,
11599 +                                   &sp->opdata_rsa_pn_num,
11600 +                                   &sp->opdata_rsa_pe_num, sp->session);
11601 +                               if (h_priv_key == CK_INVALID_HANDLE)
11602 +                                       goto err;
11603 +                               }
11604 +                       else
11605 +                               goto err;
11606 +                       }
11607 +               }
11609 +       pk11_return_session(sp, OP_RSA);
11610 +       return (pkey);
11611 +err:
11612 +       pk11_return_session(sp, OP_RSA);
11613 +       if (rsa != NULL)
11614 +               RSA_free(rsa);
11615 +       if (pkey != NULL)
11616 +               {
11617 +               EVP_PKEY_free(pkey);
11618 +               pkey = NULL;
11619 +               }
11620 +       rollback = rollback;
11621 +       return (pkey);
11622 +       }
11625 + * Load RSA public key from a file or get its PKCS#11 handle if stored in the
11626 + * PKCS#11 token.
11627 + */
11628 +/* ARGSUSED */
11629 +EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
11630 +       UI_METHOD *ui_method, void *callback_data)
11631 +       {
11632 +       EVP_PKEY *pkey = NULL;
11633 +       FILE *pubkey;
11634 +       CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
11635 +       RSA *rsa = NULL;
11636 +       PK11_SESSION *sp;
11637 +       /* Anything else below is needed for the key by reference extension. */
11638 +       CK_RV rv;
11639 +       CK_BBOOL is_token = TRUE;
11640 +       CK_BYTE attr_data[2][MAXATTR];
11641 +       CK_OBJECT_CLASS key_class = CKO_PUBLIC_KEY;
11642 +       CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;    /* key in keystore */
11644 +       /* we look for public keys only */
11645 +       CK_ATTRIBUTE search_templ[] =
11646 +               {
11647 +               {CKA_TOKEN, &is_token, sizeof(is_token)},
11648 +               {CKA_CLASS, &key_class, sizeof(key_class)},
11649 +               {CKA_LABEL, NULL, 0}
11650 +               };
11652 +       /*
11653 +        * These public attributes are needed to initialize OpenSSL RSA
11654 +        * structure with something we can use to look up the key.
11655 +        */
11656 +       CK_ATTRIBUTE get_templ[] =
11657 +               {
11658 +               {CKA_MODULUS, (void *)attr_data[0], MAXATTR},           /* n */
11659 +               {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], MAXATTR},   /* e */
11660 +               };
11662 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
11663 +               return (NULL);
11665 +       /*
11666 +        * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
11667 +        */
11668 +       if (strstr(pubkey_file, "pkcs11:") == pubkey_file)
11669 +               {
11670 +               search_templ[2].pValue = strstr(pubkey_file, ":") + 1;
11671 +               search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
11673 +               if (pk11_token_login(sp->session, &pk11_login_done,
11674 +                   CK_FALSE) == 0)
11675 +                       goto err;
11677 +               /* see find_lock array definition
11678 +                  for more info on object locking */
11679 +               LOCK_OBJSTORE(OP_RSA);
11681 +               /*
11682 +                * Now let's try to find the key in the token. It is a failure
11683 +                * if we can't find it.
11684 +                */
11685 +               if (find_one_object(OP_RSA, sp->session, search_templ, 3,
11686 +                   &ks_key) == 0)
11687 +                       {
11688 +                       UNLOCK_OBJSTORE(OP_RSA);
11689 +                       goto err;
11690 +                       }
11692 +               /*
11693 +                * We load a new public key so we will create a new RSA
11694 +                * structure. No cache hit is possible.
11695 +                */
11696 +               (void) pk11_destroy_rsa_object_pub(sp, FALSE);
11698 +               sp->opdata_rsa_pub_key = ks_key;
11699 +               /* This object shall not be deleted on a cache miss. */
11700 +               sp->pub_persistent = CK_TRUE;
11702 +               /*
11703 +                * Cache the RSA public structure pointer.
11704 +                */
11705 +               if ((rsa = sp->opdata_rsa_pub = RSA_new_method(e)) == NULL)
11706 +                       {
11707 +                       UNLOCK_OBJSTORE(OP_RSA);
11708 +                       goto err;
11709 +                       }
11711 +               /*
11712 +                * Now we have to initialize an OpenSSL RSA structure,
11713 +                * everything else is 0 or NULL.
11714 +                */
11715 +               rsa->flags = RSA_FLAG_SIGN_VER;
11717 +               if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
11718 +                   get_templ, 2)) != CKR_OK)
11719 +                       {
11720 +                       UNLOCK_OBJSTORE(OP_RSA);
11721 +                       PK11err_add_data(PK11_F_LOAD_PUBKEY,
11722 +                                        PK11_R_GETATTRIBUTVALUE, rv);
11723 +                       goto err;
11724 +                       }
11726 +               attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
11727 +               attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
11729 +               UNLOCK_OBJSTORE(OP_RSA);
11731 +               if ((pkey = EVP_PKEY_new()) == NULL)
11732 +                       goto err;
11734 +               if (EVP_PKEY_assign_RSA(pkey, rsa) == 0)
11735 +                       goto err;
11737 +               /*
11738 +                * Create a session object from it so that when calling
11739 +                * pk11_get_public_rsa_key() the next time, we can find it. The
11740 +                * reason why we do that is that we cannot tell from the RSA
11741 +                * structure (OpenSSL RSA structure does not have any room for
11742 +                * additional data used by the engine, for example) if it bears
11743 +                * a public key stored in the keystore or not so it's better if
11744 +                * we always have a session key. Note that this is different
11745 +                * from what we do for the private keystore objects but in that
11746 +                * case, we can tell from the RSA structure that the keystore
11747 +                * object is in play - the 'd' component is NULL in that case.
11748 +                */
11749 +               h_pub_key = sp->opdata_rsa_pub_key =
11750 +                   pk11_get_public_rsa_key(rsa,
11751 +                   &sp->opdata_rsa_pub, &sp->opdata_rsa_n_num,
11752 +                   &sp->opdata_rsa_e_num, sp->session);
11753 +               if (h_pub_key == CK_INVALID_HANDLE)
11754 +                       goto err;
11755 +               }
11756 +       else if ((pubkey = fopen(pubkey_file, read_mode_flags)) != NULL)
11757 +               {
11758 +               pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL);
11759 +               (void) fclose(pubkey);
11760 +               if (pkey != NULL)
11761 +                       {
11762 +                       rsa = EVP_PKEY_get1_RSA(pkey);
11763 +                       if (rsa != NULL)
11764 +                               {
11765 +                               /*
11766 +                                * This will always destroy the RSA
11767 +                                * object since we have a new RSA
11768 +                                * structure here.
11769 +                                */
11770 +                               (void) check_new_rsa_key_pub(sp, rsa);
11771 +                               sp->pub_persistent = CK_FALSE;
11773 +                               h_pub_key = sp->opdata_rsa_pub_key =
11774 +                                   pk11_get_public_rsa_key(rsa,
11775 +                                   &sp->opdata_rsa_pub, &sp->opdata_rsa_n_num,
11776 +                                   &sp->opdata_rsa_e_num, sp->session);
11777 +                               if (h_pub_key == CK_INVALID_HANDLE)
11778 +                                       goto err;
11779 +                               }
11780 +                       else
11781 +                               goto err;
11782 +                       }
11783 +               }
11785 +       pk11_return_session(sp, OP_RSA);
11786 +       return (pkey);
11787 +err:
11788 +       pk11_return_session(sp, OP_RSA);
11789 +       if (rsa != NULL)
11790 +               RSA_free(rsa);
11791 +       if (pkey != NULL)
11792 +               {
11793 +               EVP_PKEY_free(pkey);
11794 +               pkey = NULL;
11795 +               }
11796 +       return (pkey);
11797 +       }
11800 + * Create a public key object in a session from a given rsa structure.
11801 + * The *rsa_n_num and *rsa_e_num pointers are non-NULL for RSA public keys.
11802 + */
11803 +static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA *rsa,
11804 +    RSA **key_ptr, BIGNUM **rsa_n_num, BIGNUM **rsa_e_num,
11805 +    CK_SESSION_HANDLE session)
11806 +       {
11807 +       CK_RV rv;
11808 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
11809 +       CK_ULONG found;
11810 +       CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
11811 +       CK_KEY_TYPE k_type = CKK_RSA;
11812 +       CK_ULONG ul_key_attr_count = 8;
11813 +       CK_BBOOL rollback = FALSE;
11815 +       CK_ATTRIBUTE  a_key_template[] =
11816 +               {
11817 +               {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
11818 +               {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
11819 +               {CKA_TOKEN, &myfalse, sizeof (myfalse)},
11820 +               {CKA_ENCRYPT, &mytrue, sizeof (mytrue)},
11821 +               {CKA_VERIFY, &mytrue, sizeof (mytrue)},
11822 +               {CKA_VERIFY_RECOVER, &mytrue, sizeof (mytrue)},
11823 +               {CKA_MODULUS, (void *)NULL, 0},
11824 +               {CKA_PUBLIC_EXPONENT, (void *)NULL, 0}
11825 +               };
11827 +       int i;
11829 +       a_key_template[0].pValue = &o_key;
11830 +       a_key_template[1].pValue = &k_type;
11832 +       a_key_template[6].ulValueLen = BN_num_bytes(rsa->n);
11833 +       a_key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
11834 +               (size_t)a_key_template[6].ulValueLen);
11835 +       if (a_key_template[6].pValue == NULL)
11836 +               {
11837 +               PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
11838 +               goto malloc_err;
11839 +               }
11841 +       BN_bn2bin(rsa->n, a_key_template[6].pValue);
11843 +       a_key_template[7].ulValueLen = BN_num_bytes(rsa->e);
11844 +       a_key_template[7].pValue = (CK_VOID_PTR)OPENSSL_malloc(
11845 +               (size_t)a_key_template[7].ulValueLen);
11846 +       if (a_key_template[7].pValue == NULL)
11847 +               {
11848 +               PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
11849 +               goto malloc_err;
11850 +               }
11852 +       BN_bn2bin(rsa->e, a_key_template[7].pValue);
11854 +       /* see find_lock array definition for more info on object locking */
11855 +       LOCK_OBJSTORE(OP_RSA);
11857 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template,
11858 +               ul_key_attr_count);
11860 +       if (rv != CKR_OK)
11861 +               {
11862 +               PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
11863 +                   PK11_R_FINDOBJECTSINIT, rv);
11864 +               goto err;
11865 +               }
11867 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
11869 +       if (rv != CKR_OK)
11870 +               {
11871 +               (void) pFuncList->C_FindObjectsFinal(session);
11872 +               PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
11873 +                   PK11_R_FINDOBJECTS, rv);
11874 +               goto err;
11875 +               }
11877 +       rv = pFuncList->C_FindObjectsFinal(session);
11879 +       if (rv != CKR_OK)
11880 +               {
11881 +               PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
11882 +                   PK11_R_FINDOBJECTSFINAL, rv);
11883 +               goto err;
11884 +               }
11886 +       if (found == 0)
11887 +               {
11888 +               rv = pFuncList->C_CreateObject(session,
11889 +                       a_key_template, ul_key_attr_count, &h_key);
11890 +               if (rv != CKR_OK)
11891 +                       {
11892 +                       PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
11893 +                           PK11_R_CREATEOBJECT, rv);
11894 +                       goto err;
11895 +                       }
11896 +               }
11898 +       if (rsa_n_num != NULL)
11899 +               if ((*rsa_n_num = BN_dup(rsa->n)) == NULL)
11900 +                       {
11901 +                       PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
11902 +                       rollback = TRUE;
11903 +                       goto err;
11904 +                       }
11905 +       if (rsa_e_num != NULL)
11906 +               if ((*rsa_e_num = BN_dup(rsa->e)) == NULL)
11907 +                       {
11908 +                       PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
11909 +                       BN_free(*rsa_n_num);
11910 +                       *rsa_n_num = NULL;
11911 +                       rollback = TRUE;
11912 +                       goto err;
11913 +                       }
11915 +       /* LINTED: E_CONSTANT_CONDITION */
11916 +       KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
11917 +       if (key_ptr != NULL)
11918 +               *key_ptr = rsa;
11920 +err:
11921 +       if (rollback)
11922 +               {
11923 +               /*
11924 +                * We do not care about the return value from C_DestroyObject()
11925 +                * since we are doing rollback.
11926 +                */
11927 +               if (found == 0)
11928 +                       (void) pFuncList->C_DestroyObject(session, h_key);
11929 +               h_key = CK_INVALID_HANDLE;
11930 +               }
11932 +       UNLOCK_OBJSTORE(OP_RSA);
11934 +malloc_err:
11935 +       for (i = 6; i <= 7; i++)
11936 +               {
11937 +               if (a_key_template[i].pValue != NULL)
11938 +                       {
11939 +                       OPENSSL_free(a_key_template[i].pValue);
11940 +                       a_key_template[i].pValue = NULL;
11941 +                       }
11942 +               }
11944 +       return (h_key);
11945 +       }
11948 + * Create a private key object in the session from a given rsa structure.
11949 + * The *rsa_d_num pointer is non-NULL for RSA private keys.
11950 + */
11951 +static CK_OBJECT_HANDLE
11952 +pk11_get_private_rsa_key(RSA *rsa, RSA **key_ptr, BIGNUM **rsa_d_num,
11953 +    BIGNUM **rsa_n_num, BIGNUM **rsa_e_num, CK_SESSION_HANDLE session)
11954 +       {
11955 +       CK_RV rv;
11956 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
11957 +       int i;
11958 +       CK_ULONG found;
11959 +       CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
11960 +       CK_KEY_TYPE k_type = CKK_RSA;
11961 +       CK_ULONG ul_key_attr_count = 14;
11962 +       CK_BBOOL rollback = FALSE;
11964 +       /* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys */
11965 +       CK_ATTRIBUTE  a_key_template[] =
11966 +               {
11967 +               {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
11968 +               {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
11969 +               {CKA_TOKEN, &myfalse, sizeof (myfalse)},
11970 +               {CKA_SENSITIVE, &myfalse, sizeof (myfalse)},
11971 +               {CKA_DECRYPT, &mytrue, sizeof (mytrue)},
11972 +               {CKA_SIGN, &mytrue, sizeof (mytrue)},
11973 +               {CKA_MODULUS, (void *)NULL, 0},
11974 +               {CKA_PUBLIC_EXPONENT, (void *)NULL, 0},
11975 +               {CKA_PRIVATE_EXPONENT, (void *)NULL, 0},
11976 +               {CKA_PRIME_1, (void *)NULL, 0},
11977 +               {CKA_PRIME_2, (void *)NULL, 0},
11978 +               {CKA_EXPONENT_1, (void *)NULL, 0},
11979 +               {CKA_EXPONENT_2, (void *)NULL, 0},
11980 +               {CKA_COEFFICIENT, (void *)NULL, 0},
11981 +               };
11983 +       if ((rsa->flags & RSA_FLAG_EXT_PKEY) != 0) {
11984 +               h_key = (CK_OBJECT_HANDLE)RSA_get_ex_data(rsa, hndidx_rsa);
11985 +               LOCK_OBJSTORE(OP_RSA);
11986 +               goto set;
11987 +       }
11988 +       
11989 +       a_key_template[0].pValue = &o_key;
11990 +       a_key_template[1].pValue = &k_type;
11992 +       /* Put the private key components into the template */
11993 +       if (init_template_value(rsa->n, &a_key_template[6].pValue,
11994 +               &a_key_template[6].ulValueLen) == 0 ||
11995 +           init_template_value(rsa->e, &a_key_template[7].pValue,
11996 +               &a_key_template[7].ulValueLen) == 0 ||
11997 +           init_template_value(rsa->d, &a_key_template[8].pValue,
11998 +               &a_key_template[8].ulValueLen) == 0 ||
11999 +           init_template_value(rsa->p, &a_key_template[9].pValue,
12000 +               &a_key_template[9].ulValueLen) == 0 ||
12001 +           init_template_value(rsa->q, &a_key_template[10].pValue,
12002 +               &a_key_template[10].ulValueLen) == 0 ||
12003 +           init_template_value(rsa->dmp1, &a_key_template[11].pValue,
12004 +               &a_key_template[11].ulValueLen) == 0 ||
12005 +           init_template_value(rsa->dmq1, &a_key_template[12].pValue,
12006 +               &a_key_template[12].ulValueLen) == 0 ||
12007 +           init_template_value(rsa->iqmp, &a_key_template[13].pValue,
12008 +               &a_key_template[13].ulValueLen) == 0)
12009 +               {
12010 +               PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
12011 +               goto malloc_err;
12012 +               }
12014 +       /* see find_lock array definition for more info on object locking */
12015 +       LOCK_OBJSTORE(OP_RSA);
12017 +       /*
12018 +        * We are getting the private key but the private 'd'
12019 +        * component is NULL.  That means this is key by reference RSA
12020 +        * key. In that case, we can use only public components for
12021 +        * searching for the private key handle.
12022 +        */
12023 +       if (rsa->d == NULL)
12024 +               {
12025 +               ul_key_attr_count = 8;
12026 +               /*
12027 +                * We will perform the search in the token, not in the existing
12028 +                * session keys.
12029 +                */
12030 +               a_key_template[2].pValue = &mytrue;
12031 +               }
12033 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template,
12034 +               ul_key_attr_count);
12036 +       if (rv != CKR_OK)
12037 +               {
12038 +               PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
12039 +                   PK11_R_FINDOBJECTSINIT, rv);
12040 +               goto err;
12041 +               }
12043 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
12045 +       if (rv != CKR_OK)
12046 +               {
12047 +               (void) pFuncList->C_FindObjectsFinal(session);
12048 +               PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
12049 +                   PK11_R_FINDOBJECTS, rv);
12050 +               goto err;
12051 +               }
12053 +       rv = pFuncList->C_FindObjectsFinal(session);
12055 +       if (rv != CKR_OK)
12056 +               {
12057 +               PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
12058 +                   PK11_R_FINDOBJECTSFINAL, rv);
12059 +               goto err;
12060 +               }
12062 +       if (found == 0)
12063 +               {
12064 +               /*
12065 +                * We have an RSA structure with 'n'/'e' components
12066 +                * only so we tried to find the private key in the
12067 +                * keystore. If it was really a token key we have a
12068 +                * problem. Note that for other key types we just
12069 +                * create a new session key using the private
12070 +                * components from the RSA structure.
12071 +                */
12072 +               if (rsa->d == NULL)
12073 +                       {
12074 +                       PK11err(PK11_F_GET_PRIV_RSA_KEY,
12075 +                           PK11_R_PRIV_KEY_NOT_FOUND);
12076 +                       goto err;
12077 +                       }
12079 +               rv = pFuncList->C_CreateObject(session,
12080 +                       a_key_template, ul_key_attr_count, &h_key);
12081 +               if (rv != CKR_OK)
12082 +                       {
12083 +                       PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
12084 +                               PK11_R_CREATEOBJECT, rv);
12085 +                       goto err;
12086 +                       }
12087 +               }
12089 +set:
12090 +       if (rsa_d_num != NULL)
12091 +               {
12092 +               /*
12093 +                * When RSA keys by reference code is used, we never
12094 +                * extract private components from the keystore. In
12095 +                * that case 'd' was set to NULL and we expect the
12096 +                * application to properly cope with that. It is
12097 +                * documented in openssl(5). In general, if keys by
12098 +                * reference are used we expect it to be used
12099 +                * exclusively using the high level API and then there
12100 +                * is no problem. If the application expects the
12101 +                * private components to be read from the keystore
12102 +                * then that is not a supported way of usage.
12103 +                */
12104 +               if (rsa->d != NULL && (*rsa_d_num = BN_dup(rsa->d)) == NULL)
12105 +                       {
12106 +                       PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
12107 +                       rollback = TRUE;
12108 +                       goto err;
12109 +                       }
12110 +               else
12111 +                       *rsa_d_num = NULL;
12112 +               }
12114 +       /*
12115 +        * For the key by reference code, we need public components as well
12116 +        * since 'd' component is always NULL. For that reason, we always cache
12117 +        * 'n'/'e' components as well.
12118 +        */
12119 +       *rsa_n_num = BN_dup(rsa->n);
12120 +       *rsa_e_num = BN_dup(rsa->e);
12122 +       /* LINTED: E_CONSTANT_CONDITION */
12123 +       KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
12124 +       if (key_ptr != NULL)
12125 +               *key_ptr = rsa;
12127 +err:
12128 +       if (rollback)
12129 +               {
12130 +               /*
12131 +                * We do not care about the return value from C_DestroyObject()
12132 +                * since we are doing rollback.
12133 +                */
12134 +               if (found == 0 &&
12135 +                   (rsa->flags & RSA_FLAG_EXT_PKEY) == 0)
12136 +                       (void) pFuncList->C_DestroyObject(session, h_key);
12137 +               h_key = CK_INVALID_HANDLE;
12138 +               }
12140 +       UNLOCK_OBJSTORE(OP_RSA);
12142 +malloc_err:
12143 +       /*
12144 +        * 6 to 13 entries in the key template are key components.
12145 +        * They need to be freed upon exit or error.
12146 +        */
12147 +       for (i = 6; i <= 13; i++)
12148 +               {
12149 +               if (a_key_template[i].pValue != NULL)
12150 +                       {
12151 +                       (void) memset(a_key_template[i].pValue, 0,
12152 +                               a_key_template[i].ulValueLen);
12153 +                       OPENSSL_free(a_key_template[i].pValue);
12154 +                       a_key_template[i].pValue = NULL;
12155 +                       }
12156 +               }
12158 +       return (h_key);
12159 +       }
12162 + * Check for cache miss and clean the object pointer and handle
12163 + * in such case. Return 1 for cache hit, 0 for cache miss.
12164 + */
12165 +static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa)
12166 +       {
12167 +       /*
12168 +        * Provide protection against RSA structure reuse by making the
12169 +        * check for cache hit stronger. Only public components of RSA
12170 +        * key matter here so it is sufficient to compare them with values
12171 +        * cached in PK11_SESSION structure.
12172 +        *
12173 +        * We must check the handle as well since with key by reference, public
12174 +        * components 'n'/'e' are cached in private keys as well. That means we
12175 +        * could have a cache hit in a private key when looking for a public
12176 +        * key. That would not work, you cannot have one PKCS#11 object for
12177 +        * both data signing and verifying.
12178 +        */
12179 +       if ((sp->opdata_rsa_pub != rsa) ||
12180 +           (BN_cmp(sp->opdata_rsa_n_num, rsa->n) != 0) ||
12181 +           (BN_cmp(sp->opdata_rsa_e_num, rsa->e) != 0) ||
12182 +           (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE))
12183 +               {
12184 +               /*
12185 +                * We do not check the return value because even in case of
12186 +                * failure the sp structure will have both key pointer
12187 +                * and object handle cleaned and pk11_destroy_object()
12188 +                * reports the failure to the OpenSSL error message buffer.
12189 +                */
12190 +               (void) pk11_destroy_rsa_object_pub(sp, TRUE);
12191 +               return (0);
12192 +               }
12193 +       return (1);
12194 +       }
12197 + * Check for cache miss and clean the object pointer and handle
12198 + * in such case. Return 1 for cache hit, 0 for cache miss.
12199 + */
12200 +static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa)
12201 +       {
12202 +       /*
12203 +        * Provide protection against RSA structure reuse by making
12204 +        * the check for cache hit stronger. Comparing public exponent
12205 +        * of RSA key with value cached in PK11_SESSION structure
12206 +        * should be sufficient. Note that we want to compare the
12207 +        * public component since with the keys by reference
12208 +        * mechanism, private components are not in the RSA
12209 +        * structure. Also, see check_new_rsa_key_pub() about why we
12210 +        * compare the handle as well.
12211 +        */
12212 +       if ((sp->opdata_rsa_priv != rsa) ||
12213 +           (BN_cmp(sp->opdata_rsa_pn_num, rsa->n) != 0) ||
12214 +           (BN_cmp(sp->opdata_rsa_pe_num, rsa->e) != 0) ||
12215 +           (sp->opdata_rsa_pn_num == NULL) ||
12216 +           (sp->opdata_rsa_pe_num == NULL) ||
12217 +           (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE))
12218 +               {
12219 +               /*
12220 +                * We do not check the return value because even in case of
12221 +                * failure the sp structure will have both key pointer
12222 +                * and object handle cleaned and pk11_destroy_object()
12223 +                * reports the failure to the OpenSSL error message buffer.
12224 +                */
12225 +               (void) pk11_destroy_rsa_object_priv(sp, TRUE);
12226 +               return (0);
12227 +               }
12228 +       return (1);
12229 +       }
12232 + * Local function to simplify key template population
12233 + * Return 0 -- error, 1 -- no error
12234 + */
12235 +static int
12236 +init_template_value(BIGNUM *bn, CK_VOID_PTR *p_value,
12237 +       CK_ULONG *ul_value_len)
12238 +       {
12239 +       CK_ULONG len = 0;
12241 +       /*
12242 +        * This function can be used on non-initialized BIGNUMs. It is
12243 +        * easier to check that here than individually in the callers.
12244 +        */
12245 +       if (bn != NULL)
12246 +               len = BN_num_bytes(bn);
12248 +       if (bn == NULL || len == 0)
12249 +               return (1);
12251 +       *ul_value_len = len;
12252 +       *p_value = (CK_VOID_PTR)OPENSSL_malloc((size_t)*ul_value_len);
12253 +       if (*p_value == NULL)
12254 +               return (0);
12256 +       BN_bn2bin(bn, *p_value);
12258 +       return (1);
12259 +       }
12261 +static void
12262 +attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn)
12263 +       {
12264 +       if (attr->ulValueLen > 0)
12265 +               *bn = BN_bin2bn(attr_data, attr->ulValueLen, NULL);
12266 +       }
12269 + * Find one object in the token. It is an error if we can not find the
12270 + * object or if we find more objects based on the template we got.
12271 + * Assume object store locked.
12272 + *
12273 + * Returns:
12274 + *     1 OK
12275 + *     0 no object or more than 1 object found
12276 + */
12277 +static int
12278 +find_one_object(PK11_OPTYPE op, CK_SESSION_HANDLE s,
12279 +    CK_ATTRIBUTE_PTR ptempl, CK_ULONG nattr, CK_OBJECT_HANDLE_PTR pkey)
12280 +       {
12281 +       CK_RV rv;
12282 +       CK_ULONG objcnt;
12284 +       if ((rv = pFuncList->C_FindObjectsInit(s, ptempl, nattr)) != CKR_OK)
12285 +               {
12286 +               PK11err_add_data(PK11_F_FIND_ONE_OBJECT,
12287 +                   PK11_R_FINDOBJECTSINIT, rv);
12288 +               return (0);
12289 +               }
12291 +       rv = pFuncList->C_FindObjects(s, pkey, 1, &objcnt);
12292 +       if (rv != CKR_OK)
12293 +               {
12294 +               (void) pFuncList->C_FindObjectsFinal(s);
12295 +               PK11err_add_data(PK11_F_FIND_ONE_OBJECT, PK11_R_FINDOBJECTS,
12296 +                   rv);
12297 +               return (0);
12298 +               }
12300 +       (void) pFuncList->C_FindObjectsFinal(s);
12302 +       if (objcnt > 1)
12303 +               {
12304 +               PK11err(PK11_F_FIND_ONE_OBJECT,
12305 +                   PK11_R_MORE_THAN_ONE_OBJECT_FOUND);
12306 +               return (0);
12307 +               }
12308 +       else if (objcnt == 0)
12309 +               {
12310 +               PK11err(PK11_F_FIND_ONE_OBJECT, PK11_R_NO_OBJECT_FOUND);
12311 +               return (0);
12312 +               }
12313 +       return (1);
12314 +       }
12316 +/* from uri stuff */
12318 +extern char *pk11_pin;
12320 +static int pk11_get_pin(void);
12322 +static int
12323 +pk11_get_pin(void)
12325 +       char *pin;
12327 +       /* The getpassphrase() function is not MT safe. */
12328 +#ifndef NOPTHREADS
12329 +       OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
12330 +#else
12331 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
12332 +#endif
12333 +       pin = getpassphrase("Enter PIN: ");
12334 +       if (pin == NULL)
12335 +               {
12336 +               PK11err(PK11_F_GET_PIN, PK11_R_COULD_NOT_READ_PIN);
12337 +#ifndef NOPTHREADS
12338 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12339 +#else
12340 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12341 +#endif
12342 +               return (0);
12343 +               }
12344 +       pk11_pin = BUF_strdup(pin);
12345 +       if (pk11_pin == NULL)
12346 +               {
12347 +               PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_MALLOC_FAILURE);
12348 +#ifndef NOPTHREADS
12349 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12350 +#else
12351 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12352 +#endif
12353 +               return (0);
12354 +               }
12355 +       memset(pin, 0, strlen(pin));
12356 +#ifndef NOPTHREADS
12357 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12358 +#else
12359 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12360 +#endif
12361 +       return (1);
12362 +       }
12365 + * Log in to the keystore if we are supposed to do that at all. Take care of
12366 + * reading and caching the PIN etc. Log in only once even when called from
12367 + * multiple threads.
12368 + *
12369 + * Returns:
12370 + *     1 on success
12371 + *     0 on failure
12372 + */
12373 +static int
12374 +pk11_token_login(CK_SESSION_HANDLE session, CK_BBOOL *login_done,
12375 +    CK_BBOOL is_private)
12376 +       {
12377 +       CK_RV rv;
12379 +#if 0
12380 +       /* doesn't work on the AEP Keyper??? */
12381 +       if ((pubkey_token_flags & CKF_TOKEN_INITIALIZED) == 0)
12382 +               {
12383 +               PK11err(PK11_F_TOKEN_LOGIN,
12384 +                   PK11_R_TOKEN_NOT_INITIALIZED);
12385 +               return (0);
12386 +               }
12387 +#endif
12389 +       /*
12390 +        * If login is required or needed but the PIN has not been
12391 +        * even initialized we can bail out right now. Note that we
12392 +        * are supposed to always log in if we are going to access
12393 +        * private keys. However, we may need to log in even for
12394 +        * accessing public keys in case that the CKF_LOGIN_REQUIRED
12395 +        * flag is set.
12396 +        */
12397 +       if (((pubkey_token_flags & CKF_LOGIN_REQUIRED) ||
12398 +            (is_private == CK_TRUE)) &&
12399 +           (~pubkey_token_flags & CKF_USER_PIN_INITIALIZED))
12400 +               {
12401 +               PK11err(PK11_F_TOKEN_LOGIN, PK11_R_TOKEN_PIN_NOT_SET);
12402 +               return (0);
12403 +               }
12405 +       /*
12406 +        * Note on locking: it is possible that more than one thread
12407 +        * gets into pk11_get_pin() so we must deal with that. We
12408 +        * cannot avoid it since we cannot guard fork() in there with
12409 +        * a lock because we could end up in a dead lock in the
12410 +        * child. Why? Remember we are in a multithreaded environment
12411 +        * so we must lock all mutexes in the prefork function to
12412 +        * avoid a situation in which a thread that did not call
12413 +        * fork() held a lock, making future unlocking impossible. We
12414 +        * lock right before C_Login().
12415 +        */
12416 +       if ((pubkey_token_flags & CKF_LOGIN_REQUIRED) ||
12417 +           (is_private == CK_TRUE))
12418 +               {
12419 +               if (*login_done == CK_FALSE)
12420 +                       {
12421 +                       if ((pk11_pin == NULL) && (pk11_get_pin() == 0))
12422 +                               {
12423 +                               PK11err(PK11_F_TOKEN_LOGIN,
12424 +                                   PK11_R_TOKEN_PIN_NOT_PROVIDED);
12425 +                               return (0);
12426 +                               }
12427 +                       }
12429 +               /*
12430 +                * Note that what we are logging into is the keystore from
12431 +                * pubkey_SLOTID because we work with OP_RSA session type here.
12432 +                * That also means that we can work with only one keystore in
12433 +                * the engine.
12434 +                *
12435 +                * We must make sure we do not try to login more than once.
12436 +                * Also, see the comment above on locking strategy.
12437 +                */
12439 +#ifndef NOPTHREADS
12440 +               OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
12441 +#else
12442 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
12443 +#endif
12444 +               if (*login_done == CK_FALSE)
12445 +                       {
12446 +                       if ((rv = pFuncList->C_Login(session,
12447 +                           CKU_USER, (CK_UTF8CHAR*)pk11_pin,
12448 +                           strlen(pk11_pin))) != CKR_OK)
12449 +                               {
12450 +                               PK11err_add_data(PK11_F_TOKEN_LOGIN,
12451 +                                   PK11_R_TOKEN_LOGIN_FAILED, rv);
12452 +                               goto err_locked;
12453 +                               }
12455 +                       *login_done = CK_TRUE;
12457 +                       }
12458 +#ifndef NOPTHREADS
12459 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12460 +#else
12461 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12462 +#endif
12463 +               }
12464 +       else
12465 +               {
12466 +                       /*
12467 +                        * If token does not require login we take it as the
12468 +                        * login was done.
12469 +                        */
12470 +                       *login_done = CK_TRUE;
12471 +               }
12473 +       return (1);
12475 +err_locked:
12476 +       if (pk11_pin) {
12477 +               memset(pk11_pin, 0, strlen(pk11_pin));
12478 +               OPENSSL_free((void*)pk11_pin);
12479 +       }
12480 +       pk11_pin = NULL;
12481 +#ifndef NOPTHREADS
12482 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12483 +#else
12484 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12485 +#endif
12486 +       return (0);
12487 +       }
12490 + * Log in to the keystore in the child if we were logged in in the
12491 + * parent. There are similarities in the code with pk11_token_login()
12492 + * but still it is quite different so we need a separate function for
12493 + * this.
12494 + *
12495 + * Note that this function is called under the locked session mutex when fork is
12496 + * detected. That means that C_Login() will be called from the child just once.
12497 + *
12498 + * Returns:
12499 + *     1 on success
12500 + *     0 on failure
12501 + */
12502 +int
12503 +pk11_token_relogin(CK_SESSION_HANDLE session)
12504 +       {
12505 +       CK_RV rv;
12507 +       if ((pk11_pin == NULL) && (pk11_get_pin() == 0))
12508 +               return (0);
12510 +#ifndef NOPTHREADS
12511 +       OPENSSL_assert(pthread_mutex_lock(token_lock) == 0);
12512 +#else
12513 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
12514 +#endif
12515 +       if ((rv = pFuncList->C_Login(session, CKU_USER,
12516 +           (CK_UTF8CHAR_PTR)pk11_pin, strlen(pk11_pin))) != CKR_OK)
12517 +               {
12518 +               PK11err_add_data(PK11_F_TOKEN_RELOGIN,
12519 +                   PK11_R_TOKEN_LOGIN_FAILED, rv);
12520 +#ifndef NOPTHREADS
12521 +               OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12522 +#else
12523 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12524 +#endif
12525 +               return (0);
12526 +               }
12527 +#ifndef NOPTHREADS
12528 +       OPENSSL_assert(pthread_mutex_unlock(token_lock) == 0);
12529 +#else
12530 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
12531 +#endif
12533 +       return (1);
12534 +       }
12536 +#ifdef OPENSSL_SYS_WIN32
12537 +char *getpassphrase(const char *prompt)
12538 +       {
12539 +       static char buf[128];
12540 +       HANDLE h;
12541 +       DWORD cc, mode;
12542 +       int cnt;
12544 +       h = GetStdHandle(STD_INPUT_HANDLE);
12545 +       fputs(prompt, stderr);
12546 +       fflush(stderr);
12547 +       fflush(stdout);
12548 +       FlushConsoleInputBuffer(h);
12549 +       GetConsoleMode(h, &mode);
12550 +       SetConsoleMode(h, ENABLE_PROCESSED_INPUT);
12552 +       for (cnt = 0; cnt < sizeof(buf) - 1; cnt++)
12553 +               {
12554 +               ReadFile(h, buf + cnt, 1, &cc, NULL);
12555 +               if (buf[cnt] == '\r')
12556 +                       break;
12557 +               fputc('*', stdout);
12558 +               fflush(stderr);
12559 +               fflush(stdout);
12560 +               }
12562 +       SetConsoleMode(h, mode);
12563 +       buf[cnt] = '\0';
12564 +       fputs("\n", stderr);
12565 +       return buf;
12566 +       }
12567 +#endif /* OPENSSL_SYS_WIN32 */
12568 +#endif /* OPENSSL_NO_HW_PK11SO */
12569 +#endif /* OPENSSL_NO_HW_PK11 */
12570 +#endif /* OPENSSL_NO_HW */
12571 Index: openssl/crypto/engine/pkcs11.h
12572 diff -u /dev/null openssl/crypto/engine/pkcs11.h:1.1.1.1
12573 --- /dev/null   Fri Jan  2 14:59:08 2015
12574 +++ openssl/crypto/engine/pkcs11.h      Wed Oct 24 23:27:09 2007
12575 @@ -0,0 +1,299 @@
12576 +/* pkcs11.h include file for PKCS #11. */
12577 +/* Revision: 1.1.1.1  */
12579 +/* License to copy and use this software is granted provided that it is
12580 + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
12581 + * (Cryptoki)" in all material mentioning or referencing this software.
12583 + * License is also granted to make and use derivative works provided that
12584 + * such works are identified as "derived from the RSA Security Inc. PKCS #11
12585 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
12586 + * referencing the derived work.
12588 + * RSA Security Inc. makes no representations concerning either the 
12589 + * merchantability of this software or the suitability of this software for
12590 + * any particular purpose. It is provided "as is" without express or implied
12591 + * warranty of any kind.
12592 + */
12594 +#ifndef _PKCS11_H_
12595 +#define _PKCS11_H_ 1
12597 +#ifdef __cplusplus
12598 +extern "C" {
12599 +#endif
12601 +/* Before including this file (pkcs11.h) (or pkcs11t.h by
12602 + * itself), 6 platform-specific macros must be defined.  These
12603 + * macros are described below, and typical definitions for them
12604 + * are also given.  Be advised that these definitions can depend
12605 + * on both the platform and the compiler used (and possibly also
12606 + * on whether a Cryptoki library is linked statically or
12607 + * dynamically).
12608 + *
12609 + * In addition to defining these 6 macros, the packing convention
12610 + * for Cryptoki structures should be set.  The Cryptoki
12611 + * convention on packing is that structures should be 1-byte
12612 + * aligned.
12613 + *
12614 + * If you're using Microsoft Developer Studio 5.0 to produce
12615 + * Win32 stuff, this might be done by using the following
12616 + * preprocessor directive before including pkcs11.h or pkcs11t.h:
12617 + *
12618 + * #pragma pack(push, cryptoki, 1)
12619 + *
12620 + * and using the following preprocessor directive after including
12621 + * pkcs11.h or pkcs11t.h:
12622 + *
12623 + * #pragma pack(pop, cryptoki)
12624 + *
12625 + * If you're using an earlier version of Microsoft Developer
12626 + * Studio to produce Win16 stuff, this might be done by using
12627 + * the following preprocessor directive before including
12628 + * pkcs11.h or pkcs11t.h:
12629 + *
12630 + * #pragma pack(1)
12631 + *
12632 + * In a UNIX environment, you're on your own for this.  You might
12633 + * not need to do (or be able to do!) anything.
12634 + *
12635 + *
12636 + * Now for the macros:
12637 + *
12638 + *
12639 + * 1. CK_PTR: The indirection string for making a pointer to an
12640 + * object.  It can be used like this:
12641 + *
12642 + * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
12643 + *
12644 + * If you're using Microsoft Developer Studio 5.0 to produce
12645 + * Win32 stuff, it might be defined by:
12646 + *
12647 + * #define CK_PTR *
12648 + *
12649 + * If you're using an earlier version of Microsoft Developer
12650 + * Studio to produce Win16 stuff, it might be defined by:
12651 + *
12652 + * #define CK_PTR far *
12653 + *
12654 + * In a typical UNIX environment, it might be defined by:
12655 + *
12656 + * #define CK_PTR *
12657 + *
12658 + *
12659 + * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
12660 + * an exportable Cryptoki library function definition out of a
12661 + * return type and a function name.  It should be used in the
12662 + * following fashion to define the exposed Cryptoki functions in
12663 + * a Cryptoki library:
12664 + *
12665 + * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
12666 + *   CK_VOID_PTR pReserved
12667 + * )
12668 + * {
12669 + *   ...
12670 + * }
12671 + *
12672 + * If you're using Microsoft Developer Studio 5.0 to define a
12673 + * function in a Win32 Cryptoki .dll, it might be defined by:
12674 + *
12675 + * #define CK_DEFINE_FUNCTION(returnType, name) \
12676 + *   returnType __declspec(dllexport) name
12677 + *
12678 + * If you're using an earlier version of Microsoft Developer
12679 + * Studio to define a function in a Win16 Cryptoki .dll, it
12680 + * might be defined by:
12681 + *
12682 + * #define CK_DEFINE_FUNCTION(returnType, name) \
12683 + *   returnType __export _far _pascal name
12684 + *
12685 + * In a UNIX environment, it might be defined by:
12686 + *
12687 + * #define CK_DEFINE_FUNCTION(returnType, name) \
12688 + *   returnType name
12689 + *
12690 + *
12691 + * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
12692 + * an importable Cryptoki library function declaration out of a
12693 + * return type and a function name.  It should be used in the
12694 + * following fashion:
12695 + *
12696 + * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
12697 + *   CK_VOID_PTR pReserved
12698 + * );
12699 + *
12700 + * If you're using Microsoft Developer Studio 5.0 to declare a
12701 + * function in a Win32 Cryptoki .dll, it might be defined by:
12702 + *
12703 + * #define CK_DECLARE_FUNCTION(returnType, name) \
12704 + *   returnType __declspec(dllimport) name
12705 + *
12706 + * If you're using an earlier version of Microsoft Developer
12707 + * Studio to declare a function in a Win16 Cryptoki .dll, it
12708 + * might be defined by:
12709 + *
12710 + * #define CK_DECLARE_FUNCTION(returnType, name) \
12711 + *   returnType __export _far _pascal name
12712 + *
12713 + * In a UNIX environment, it might be defined by:
12714 + *
12715 + * #define CK_DECLARE_FUNCTION(returnType, name) \
12716 + *   returnType name
12717 + *
12718 + *
12719 + * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
12720 + * which makes a Cryptoki API function pointer declaration or
12721 + * function pointer type declaration out of a return type and a
12722 + * function name.  It should be used in the following fashion:
12723 + *
12724 + * // Define funcPtr to be a pointer to a Cryptoki API function
12725 + * // taking arguments args and returning CK_RV.
12726 + * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
12727 + *
12728 + * or
12729 + *
12730 + * // Define funcPtrType to be the type of a pointer to a
12731 + * // Cryptoki API function taking arguments args and returning
12732 + * // CK_RV, and then define funcPtr to be a variable of type
12733 + * // funcPtrType.
12734 + * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
12735 + * funcPtrType funcPtr;
12736 + *
12737 + * If you're using Microsoft Developer Studio 5.0 to access
12738 + * functions in a Win32 Cryptoki .dll, in might be defined by:
12739 + *
12740 + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
12741 + *   returnType __declspec(dllimport) (* name)
12742 + *
12743 + * If you're using an earlier version of Microsoft Developer
12744 + * Studio to access functions in a Win16 Cryptoki .dll, it might
12745 + * be defined by:
12746 + *
12747 + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
12748 + *   returnType __export _far _pascal (* name)
12749 + *
12750 + * In a UNIX environment, it might be defined by:
12751 + *
12752 + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
12753 + *   returnType (* name)
12754 + *
12755 + *
12756 + * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
12757 + * a function pointer type for an application callback out of
12758 + * a return type for the callback and a name for the callback.
12759 + * It should be used in the following fashion:
12760 + *
12761 + * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
12762 + *
12763 + * to declare a function pointer, myCallback, to a callback
12764 + * which takes arguments args and returns a CK_RV.  It can also
12765 + * be used like this:
12766 + *
12767 + * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
12768 + * myCallbackType myCallback;
12769 + *
12770 + * If you're using Microsoft Developer Studio 5.0 to do Win32
12771 + * Cryptoki development, it might be defined by:
12772 + *
12773 + * #define CK_CALLBACK_FUNCTION(returnType, name) \
12774 + *   returnType (* name)
12775 + *
12776 + * If you're using an earlier version of Microsoft Developer
12777 + * Studio to do Win16 development, it might be defined by:
12778 + *
12779 + * #define CK_CALLBACK_FUNCTION(returnType, name) \
12780 + *   returnType _far _pascal (* name)
12781 + *
12782 + * In a UNIX environment, it might be defined by:
12783 + *
12784 + * #define CK_CALLBACK_FUNCTION(returnType, name) \
12785 + *   returnType (* name)
12786 + *
12787 + *
12788 + * 6. NULL_PTR: This macro is the value of a NULL pointer.
12789 + *
12790 + * In any ANSI/ISO C environment (and in many others as well),
12791 + * this should best be defined by
12792 + *
12793 + * #ifndef NULL_PTR
12794 + * #define NULL_PTR 0
12795 + * #endif
12796 + */
12799 +/* All the various Cryptoki types and #define'd values are in the
12800 + * file pkcs11t.h. */
12801 +#include "pkcs11t.h"
12803 +#define __PASTE(x,y)      x##y
12806 +/* ==============================================================
12807 + * Define the "extern" form of all the entry points.
12808 + * ==============================================================
12809 + */
12811 +#define CK_NEED_ARG_LIST  1
12812 +#define CK_PKCS11_FUNCTION_INFO(name) \
12813 +  extern CK_DECLARE_FUNCTION(CK_RV, name)
12815 +/* pkcs11f.h has all the information about the Cryptoki
12816 + * function prototypes. */
12817 +#include "pkcs11f.h"
12819 +#undef CK_NEED_ARG_LIST
12820 +#undef CK_PKCS11_FUNCTION_INFO
12823 +/* ==============================================================
12824 + * Define the typedef form of all the entry points.  That is, for
12825 + * each Cryptoki function C_XXX, define a type CK_C_XXX which is
12826 + * a pointer to that kind of function.
12827 + * ==============================================================
12828 + */
12830 +#define CK_NEED_ARG_LIST  1
12831 +#define CK_PKCS11_FUNCTION_INFO(name) \
12832 +  typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
12834 +/* pkcs11f.h has all the information about the Cryptoki
12835 + * function prototypes. */
12836 +#include "pkcs11f.h"
12838 +#undef CK_NEED_ARG_LIST
12839 +#undef CK_PKCS11_FUNCTION_INFO
12842 +/* ==============================================================
12843 + * Define structed vector of entry points.  A CK_FUNCTION_LIST
12844 + * contains a CK_VERSION indicating a library's Cryptoki version
12845 + * and then a whole slew of function pointers to the routines in
12846 + * the library.  This type was declared, but not defined, in
12847 + * pkcs11t.h.
12848 + * ==============================================================
12849 + */
12851 +#define CK_PKCS11_FUNCTION_INFO(name) \
12852 +  __PASTE(CK_,name) name;
12853 +  
12854 +struct CK_FUNCTION_LIST {
12856 +  CK_VERSION    version;  /* Cryptoki version */
12858 +/* Pile all the function pointers into the CK_FUNCTION_LIST. */
12859 +/* pkcs11f.h has all the information about the Cryptoki
12860 + * function prototypes. */
12861 +#include "pkcs11f.h"
12865 +#undef CK_PKCS11_FUNCTION_INFO
12868 +#undef __PASTE
12870 +#ifdef __cplusplus
12872 +#endif
12874 +#endif
12875 Index: openssl/crypto/engine/pkcs11f.h
12876 diff -u /dev/null openssl/crypto/engine/pkcs11f.h:1.1.1.1
12877 --- /dev/null   Fri Jan  2 14:59:08 2015
12878 +++ openssl/crypto/engine/pkcs11f.h     Wed Oct 24 23:27:09 2007
12879 @@ -0,0 +1,912 @@
12880 +/* pkcs11f.h include file for PKCS #11. */
12881 +/* Revision: 1.1.1.1  */
12883 +/* License to copy and use this software is granted provided that it is
12884 + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
12885 + * (Cryptoki)" in all material mentioning or referencing this software.
12887 + * License is also granted to make and use derivative works provided that
12888 + * such works are identified as "derived from the RSA Security Inc. PKCS #11
12889 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
12890 + * referencing the derived work.
12892 + * RSA Security Inc. makes no representations concerning either the 
12893 + * merchantability of this software or the suitability of this software for
12894 + * any particular purpose. It is provided "as is" without express or implied
12895 + * warranty of any kind.
12896 + */
12898 +/* This header file contains pretty much everything about all the */
12899 +/* Cryptoki function prototypes.  Because this information is */
12900 +/* used for more than just declaring function prototypes, the */
12901 +/* order of the functions appearing herein is important, and */
12902 +/* should not be altered. */
12904 +/* General-purpose */
12906 +/* C_Initialize initializes the Cryptoki library. */
12907 +CK_PKCS11_FUNCTION_INFO(C_Initialize)
12908 +#ifdef CK_NEED_ARG_LIST
12910 +  CK_VOID_PTR   pInitArgs  /* if this is not NULL_PTR, it gets
12911 +                            * cast to CK_C_INITIALIZE_ARGS_PTR
12912 +                            * and dereferenced */
12914 +#endif
12917 +/* C_Finalize indicates that an application is done with the
12918 + * Cryptoki library. */
12919 +CK_PKCS11_FUNCTION_INFO(C_Finalize)
12920 +#ifdef CK_NEED_ARG_LIST
12922 +  CK_VOID_PTR   pReserved  /* reserved.  Should be NULL_PTR */
12924 +#endif
12927 +/* C_GetInfo returns general information about Cryptoki. */
12928 +CK_PKCS11_FUNCTION_INFO(C_GetInfo)
12929 +#ifdef CK_NEED_ARG_LIST
12931 +  CK_INFO_PTR   pInfo  /* location that receives information */
12933 +#endif
12936 +/* C_GetFunctionList returns the function list. */
12937 +CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
12938 +#ifdef CK_NEED_ARG_LIST
12940 +  CK_FUNCTION_LIST_PTR_PTR ppFunctionList  /* receives pointer to
12941 +                                            * function list */
12943 +#endif
12947 +/* Slot and token management */
12949 +/* C_GetSlotList obtains a list of slots in the system. */
12950 +CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
12951 +#ifdef CK_NEED_ARG_LIST
12953 +  CK_BBOOL       tokenPresent,  /* only slots with tokens? */
12954 +  CK_SLOT_ID_PTR pSlotList,     /* receives array of slot IDs */
12955 +  CK_ULONG_PTR   pulCount       /* receives number of slots */
12957 +#endif
12960 +/* C_GetSlotInfo obtains information about a particular slot in
12961 + * the system. */
12962 +CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
12963 +#ifdef CK_NEED_ARG_LIST
12965 +  CK_SLOT_ID       slotID,  /* the ID of the slot */
12966 +  CK_SLOT_INFO_PTR pInfo    /* receives the slot information */
12968 +#endif
12971 +/* C_GetTokenInfo obtains information about a particular token
12972 + * in the system. */
12973 +CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
12974 +#ifdef CK_NEED_ARG_LIST
12976 +  CK_SLOT_ID        slotID,  /* ID of the token's slot */
12977 +  CK_TOKEN_INFO_PTR pInfo    /* receives the token information */
12979 +#endif
12982 +/* C_GetMechanismList obtains a list of mechanism types
12983 + * supported by a token. */
12984 +CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
12985 +#ifdef CK_NEED_ARG_LIST
12987 +  CK_SLOT_ID            slotID,          /* ID of token's slot */
12988 +  CK_MECHANISM_TYPE_PTR pMechanismList,  /* gets mech. array */
12989 +  CK_ULONG_PTR          pulCount         /* gets # of mechs. */
12991 +#endif
12994 +/* C_GetMechanismInfo obtains information about a particular
12995 + * mechanism possibly supported by a token. */
12996 +CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
12997 +#ifdef CK_NEED_ARG_LIST
12999 +  CK_SLOT_ID            slotID,  /* ID of the token's slot */
13000 +  CK_MECHANISM_TYPE     type,    /* type of mechanism */
13001 +  CK_MECHANISM_INFO_PTR pInfo    /* receives mechanism info */
13003 +#endif
13006 +/* C_InitToken initializes a token. */
13007 +CK_PKCS11_FUNCTION_INFO(C_InitToken)
13008 +#ifdef CK_NEED_ARG_LIST
13009 +/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
13011 +  CK_SLOT_ID      slotID,    /* ID of the token's slot */
13012 +  CK_UTF8CHAR_PTR pPin,      /* the SO's initial PIN */
13013 +  CK_ULONG        ulPinLen,  /* length in bytes of the PIN */
13014 +  CK_UTF8CHAR_PTR pLabel     /* 32-byte token label (blank padded) */
13016 +#endif
13019 +/* C_InitPIN initializes the normal user's PIN. */
13020 +CK_PKCS11_FUNCTION_INFO(C_InitPIN)
13021 +#ifdef CK_NEED_ARG_LIST
13023 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13024 +  CK_UTF8CHAR_PTR   pPin,      /* the normal user's PIN */
13025 +  CK_ULONG          ulPinLen   /* length in bytes of the PIN */
13027 +#endif
13030 +/* C_SetPIN modifies the PIN of the user who is logged in. */
13031 +CK_PKCS11_FUNCTION_INFO(C_SetPIN)
13032 +#ifdef CK_NEED_ARG_LIST
13034 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13035 +  CK_UTF8CHAR_PTR   pOldPin,   /* the old PIN */
13036 +  CK_ULONG          ulOldLen,  /* length of the old PIN */
13037 +  CK_UTF8CHAR_PTR   pNewPin,   /* the new PIN */
13038 +  CK_ULONG          ulNewLen   /* length of the new PIN */
13040 +#endif
13044 +/* Session management */
13046 +/* C_OpenSession opens a session between an application and a
13047 + * token. */
13048 +CK_PKCS11_FUNCTION_INFO(C_OpenSession)
13049 +#ifdef CK_NEED_ARG_LIST
13051 +  CK_SLOT_ID            slotID,        /* the slot's ID */
13052 +  CK_FLAGS              flags,         /* from CK_SESSION_INFO */
13053 +  CK_VOID_PTR           pApplication,  /* passed to callback */
13054 +  CK_NOTIFY             Notify,        /* callback function */
13055 +  CK_SESSION_HANDLE_PTR phSession      /* gets session handle */
13057 +#endif
13060 +/* C_CloseSession closes a session between an application and a
13061 + * token. */
13062 +CK_PKCS11_FUNCTION_INFO(C_CloseSession)
13063 +#ifdef CK_NEED_ARG_LIST
13065 +  CK_SESSION_HANDLE hSession  /* the session's handle */
13067 +#endif
13070 +/* C_CloseAllSessions closes all sessions with a token. */
13071 +CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
13072 +#ifdef CK_NEED_ARG_LIST
13074 +  CK_SLOT_ID     slotID  /* the token's slot */
13076 +#endif
13079 +/* C_GetSessionInfo obtains information about the session. */
13080 +CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
13081 +#ifdef CK_NEED_ARG_LIST
13083 +  CK_SESSION_HANDLE   hSession,  /* the session's handle */
13084 +  CK_SESSION_INFO_PTR pInfo      /* receives session info */
13086 +#endif
13089 +/* C_GetOperationState obtains the state of the cryptographic operation
13090 + * in a session. */
13091 +CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
13092 +#ifdef CK_NEED_ARG_LIST
13094 +  CK_SESSION_HANDLE hSession,             /* session's handle */
13095 +  CK_BYTE_PTR       pOperationState,      /* gets state */
13096 +  CK_ULONG_PTR      pulOperationStateLen  /* gets state length */
13098 +#endif
13101 +/* C_SetOperationState restores the state of the cryptographic
13102 + * operation in a session. */
13103 +CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
13104 +#ifdef CK_NEED_ARG_LIST
13106 +  CK_SESSION_HANDLE hSession,            /* session's handle */
13107 +  CK_BYTE_PTR      pOperationState,      /* holds state */
13108 +  CK_ULONG         ulOperationStateLen,  /* holds state length */
13109 +  CK_OBJECT_HANDLE hEncryptionKey,       /* en/decryption key */
13110 +  CK_OBJECT_HANDLE hAuthenticationKey    /* sign/verify key */
13112 +#endif
13115 +/* C_Login logs a user into a token. */
13116 +CK_PKCS11_FUNCTION_INFO(C_Login)
13117 +#ifdef CK_NEED_ARG_LIST
13119 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13120 +  CK_USER_TYPE      userType,  /* the user type */
13121 +  CK_UTF8CHAR_PTR   pPin,      /* the user's PIN */
13122 +  CK_ULONG          ulPinLen   /* the length of the PIN */
13124 +#endif
13127 +/* C_Logout logs a user out from a token. */
13128 +CK_PKCS11_FUNCTION_INFO(C_Logout)
13129 +#ifdef CK_NEED_ARG_LIST
13131 +  CK_SESSION_HANDLE hSession  /* the session's handle */
13133 +#endif
13137 +/* Object management */
13139 +/* C_CreateObject creates a new object. */
13140 +CK_PKCS11_FUNCTION_INFO(C_CreateObject)
13141 +#ifdef CK_NEED_ARG_LIST
13143 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
13144 +  CK_ATTRIBUTE_PTR  pTemplate,   /* the object's template */
13145 +  CK_ULONG          ulCount,     /* attributes in template */
13146 +  CK_OBJECT_HANDLE_PTR phObject  /* gets new object's handle. */
13148 +#endif
13151 +/* C_CopyObject copies an object, creating a new object for the
13152 + * copy. */
13153 +CK_PKCS11_FUNCTION_INFO(C_CopyObject)
13154 +#ifdef CK_NEED_ARG_LIST
13156 +  CK_SESSION_HANDLE    hSession,    /* the session's handle */
13157 +  CK_OBJECT_HANDLE     hObject,     /* the object's handle */
13158 +  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new object */
13159 +  CK_ULONG             ulCount,     /* attributes in template */
13160 +  CK_OBJECT_HANDLE_PTR phNewObject  /* receives handle of copy */
13162 +#endif
13165 +/* C_DestroyObject destroys an object. */
13166 +CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
13167 +#ifdef CK_NEED_ARG_LIST
13169 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13170 +  CK_OBJECT_HANDLE  hObject    /* the object's handle */
13172 +#endif
13175 +/* C_GetObjectSize gets the size of an object in bytes. */
13176 +CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
13177 +#ifdef CK_NEED_ARG_LIST
13179 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13180 +  CK_OBJECT_HANDLE  hObject,   /* the object's handle */
13181 +  CK_ULONG_PTR      pulSize    /* receives size of object */
13183 +#endif
13186 +/* C_GetAttributeValue obtains the value of one or more object
13187 + * attributes. */
13188 +CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
13189 +#ifdef CK_NEED_ARG_LIST
13191 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
13192 +  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
13193 +  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs; gets vals */
13194 +  CK_ULONG          ulCount     /* attributes in template */
13196 +#endif
13199 +/* C_SetAttributeValue modifies the value of one or more object
13200 + * attributes */
13201 +CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
13202 +#ifdef CK_NEED_ARG_LIST
13204 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
13205 +  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
13206 +  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs and values */
13207 +  CK_ULONG          ulCount     /* attributes in template */
13209 +#endif
13212 +/* C_FindObjectsInit initializes a search for token and session
13213 + * objects that match a template. */
13214 +CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
13215 +#ifdef CK_NEED_ARG_LIST
13217 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
13218 +  CK_ATTRIBUTE_PTR  pTemplate,  /* attribute values to match */
13219 +  CK_ULONG          ulCount     /* attrs in search template */
13221 +#endif
13224 +/* C_FindObjects continues a search for token and session
13225 + * objects that match a template, obtaining additional object
13226 + * handles. */
13227 +CK_PKCS11_FUNCTION_INFO(C_FindObjects)
13228 +#ifdef CK_NEED_ARG_LIST
13230 + CK_SESSION_HANDLE    hSession,          /* session's handle */
13231 + CK_OBJECT_HANDLE_PTR phObject,          /* gets obj. handles */
13232 + CK_ULONG             ulMaxObjectCount,  /* max handles to get */
13233 + CK_ULONG_PTR         pulObjectCount     /* actual # returned */
13235 +#endif
13238 +/* C_FindObjectsFinal finishes a search for token and session
13239 + * objects. */
13240 +CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
13241 +#ifdef CK_NEED_ARG_LIST
13243 +  CK_SESSION_HANDLE hSession  /* the session's handle */
13245 +#endif
13249 +/* Encryption and decryption */
13251 +/* C_EncryptInit initializes an encryption operation. */
13252 +CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
13253 +#ifdef CK_NEED_ARG_LIST
13255 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
13256 +  CK_MECHANISM_PTR  pMechanism,  /* the encryption mechanism */
13257 +  CK_OBJECT_HANDLE  hKey         /* handle of encryption key */
13259 +#endif
13262 +/* C_Encrypt encrypts single-part data. */
13263 +CK_PKCS11_FUNCTION_INFO(C_Encrypt)
13264 +#ifdef CK_NEED_ARG_LIST
13266 +  CK_SESSION_HANDLE hSession,            /* session's handle */
13267 +  CK_BYTE_PTR       pData,               /* the plaintext data */
13268 +  CK_ULONG          ulDataLen,           /* bytes of plaintext */
13269 +  CK_BYTE_PTR       pEncryptedData,      /* gets ciphertext */
13270 +  CK_ULONG_PTR      pulEncryptedDataLen  /* gets c-text size */
13272 +#endif
13275 +/* C_EncryptUpdate continues a multiple-part encryption
13276 + * operation. */
13277 +CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
13278 +#ifdef CK_NEED_ARG_LIST
13280 +  CK_SESSION_HANDLE hSession,           /* session's handle */
13281 +  CK_BYTE_PTR       pPart,              /* the plaintext data */
13282 +  CK_ULONG          ulPartLen,          /* plaintext data len */
13283 +  CK_BYTE_PTR       pEncryptedPart,     /* gets ciphertext */
13284 +  CK_ULONG_PTR      pulEncryptedPartLen /* gets c-text size */
13286 +#endif
13289 +/* C_EncryptFinal finishes a multiple-part encryption
13290 + * operation. */
13291 +CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
13292 +#ifdef CK_NEED_ARG_LIST
13294 +  CK_SESSION_HANDLE hSession,                /* session handle */
13295 +  CK_BYTE_PTR       pLastEncryptedPart,      /* last c-text */
13296 +  CK_ULONG_PTR      pulLastEncryptedPartLen  /* gets last size */
13298 +#endif
13301 +/* C_DecryptInit initializes a decryption operation. */
13302 +CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
13303 +#ifdef CK_NEED_ARG_LIST
13305 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
13306 +  CK_MECHANISM_PTR  pMechanism,  /* the decryption mechanism */
13307 +  CK_OBJECT_HANDLE  hKey         /* handle of decryption key */
13309 +#endif
13312 +/* C_Decrypt decrypts encrypted data in a single part. */
13313 +CK_PKCS11_FUNCTION_INFO(C_Decrypt)
13314 +#ifdef CK_NEED_ARG_LIST
13316 +  CK_SESSION_HANDLE hSession,           /* session's handle */
13317 +  CK_BYTE_PTR       pEncryptedData,     /* ciphertext */
13318 +  CK_ULONG          ulEncryptedDataLen, /* ciphertext length */
13319 +  CK_BYTE_PTR       pData,              /* gets plaintext */
13320 +  CK_ULONG_PTR      pulDataLen          /* gets p-text size */
13322 +#endif
13325 +/* C_DecryptUpdate continues a multiple-part decryption
13326 + * operation. */
13327 +CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
13328 +#ifdef CK_NEED_ARG_LIST
13330 +  CK_SESSION_HANDLE hSession,            /* session's handle */
13331 +  CK_BYTE_PTR       pEncryptedPart,      /* encrypted data */
13332 +  CK_ULONG          ulEncryptedPartLen,  /* input length */
13333 +  CK_BYTE_PTR       pPart,               /* gets plaintext */
13334 +  CK_ULONG_PTR      pulPartLen           /* p-text size */
13336 +#endif
13339 +/* C_DecryptFinal finishes a multiple-part decryption
13340 + * operation. */
13341 +CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
13342 +#ifdef CK_NEED_ARG_LIST
13344 +  CK_SESSION_HANDLE hSession,       /* the session's handle */
13345 +  CK_BYTE_PTR       pLastPart,      /* gets plaintext */
13346 +  CK_ULONG_PTR      pulLastPartLen  /* p-text size */
13348 +#endif
13352 +/* Message digesting */
13354 +/* C_DigestInit initializes a message-digesting operation. */
13355 +CK_PKCS11_FUNCTION_INFO(C_DigestInit)
13356 +#ifdef CK_NEED_ARG_LIST
13358 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
13359 +  CK_MECHANISM_PTR  pMechanism  /* the digesting mechanism */
13361 +#endif
13364 +/* C_Digest digests data in a single part. */
13365 +CK_PKCS11_FUNCTION_INFO(C_Digest)
13366 +#ifdef CK_NEED_ARG_LIST
13368 +  CK_SESSION_HANDLE hSession,     /* the session's handle */
13369 +  CK_BYTE_PTR       pData,        /* data to be digested */
13370 +  CK_ULONG          ulDataLen,    /* bytes of data to digest */
13371 +  CK_BYTE_PTR       pDigest,      /* gets the message digest */
13372 +  CK_ULONG_PTR      pulDigestLen  /* gets digest length */
13374 +#endif
13377 +/* C_DigestUpdate continues a multiple-part message-digesting
13378 + * operation. */
13379 +CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
13380 +#ifdef CK_NEED_ARG_LIST
13382 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13383 +  CK_BYTE_PTR       pPart,     /* data to be digested */
13384 +  CK_ULONG          ulPartLen  /* bytes of data to be digested */
13386 +#endif
13389 +/* C_DigestKey continues a multi-part message-digesting
13390 + * operation, by digesting the value of a secret key as part of
13391 + * the data already digested. */
13392 +CK_PKCS11_FUNCTION_INFO(C_DigestKey)
13393 +#ifdef CK_NEED_ARG_LIST
13395 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13396 +  CK_OBJECT_HANDLE  hKey       /* secret key to digest */
13398 +#endif
13401 +/* C_DigestFinal finishes a multiple-part message-digesting
13402 + * operation. */
13403 +CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
13404 +#ifdef CK_NEED_ARG_LIST
13406 +  CK_SESSION_HANDLE hSession,     /* the session's handle */
13407 +  CK_BYTE_PTR       pDigest,      /* gets the message digest */
13408 +  CK_ULONG_PTR      pulDigestLen  /* gets byte count of digest */
13410 +#endif
13414 +/* Signing and MACing */
13416 +/* C_SignInit initializes a signature (private key encryption)
13417 + * operation, where the signature is (will be) an appendix to
13418 + * the data, and plaintext cannot be recovered from the
13419 + *signature. */
13420 +CK_PKCS11_FUNCTION_INFO(C_SignInit)
13421 +#ifdef CK_NEED_ARG_LIST
13423 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
13424 +  CK_MECHANISM_PTR  pMechanism,  /* the signature mechanism */
13425 +  CK_OBJECT_HANDLE  hKey         /* handle of signature key */
13427 +#endif
13430 +/* C_Sign signs (encrypts with private key) data in a single
13431 + * part, where the signature is (will be) an appendix to the
13432 + * data, and plaintext cannot be recovered from the signature. */
13433 +CK_PKCS11_FUNCTION_INFO(C_Sign)
13434 +#ifdef CK_NEED_ARG_LIST
13436 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
13437 +  CK_BYTE_PTR       pData,           /* the data to sign */
13438 +  CK_ULONG          ulDataLen,       /* count of bytes to sign */
13439 +  CK_BYTE_PTR       pSignature,      /* gets the signature */
13440 +  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
13442 +#endif
13445 +/* C_SignUpdate continues a multiple-part signature operation,
13446 + * where the signature is (will be) an appendix to the data, 
13447 + * and plaintext cannot be recovered from the signature. */
13448 +CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
13449 +#ifdef CK_NEED_ARG_LIST
13451 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13452 +  CK_BYTE_PTR       pPart,     /* the data to sign */
13453 +  CK_ULONG          ulPartLen  /* count of bytes to sign */
13455 +#endif
13458 +/* C_SignFinal finishes a multiple-part signature operation, 
13459 + * returning the signature. */
13460 +CK_PKCS11_FUNCTION_INFO(C_SignFinal)
13461 +#ifdef CK_NEED_ARG_LIST
13463 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
13464 +  CK_BYTE_PTR       pSignature,      /* gets the signature */
13465 +  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
13467 +#endif
13470 +/* C_SignRecoverInit initializes a signature operation, where
13471 + * the data can be recovered from the signature. */
13472 +CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
13473 +#ifdef CK_NEED_ARG_LIST
13475 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
13476 +  CK_MECHANISM_PTR  pMechanism, /* the signature mechanism */
13477 +  CK_OBJECT_HANDLE  hKey        /* handle of the signature key */
13479 +#endif
13482 +/* C_SignRecover signs data in a single operation, where the
13483 + * data can be recovered from the signature. */
13484 +CK_PKCS11_FUNCTION_INFO(C_SignRecover)
13485 +#ifdef CK_NEED_ARG_LIST
13487 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
13488 +  CK_BYTE_PTR       pData,           /* the data to sign */
13489 +  CK_ULONG          ulDataLen,       /* count of bytes to sign */
13490 +  CK_BYTE_PTR       pSignature,      /* gets the signature */
13491 +  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
13493 +#endif
13497 +/* Verifying signatures and MACs */
13499 +/* C_VerifyInit initializes a verification operation, where the
13500 + * signature is an appendix to the data, and plaintext cannot
13501 + *  cannot be recovered from the signature (e.g. DSA). */
13502 +CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
13503 +#ifdef CK_NEED_ARG_LIST
13505 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
13506 +  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
13507 +  CK_OBJECT_HANDLE  hKey         /* verification key */ 
13509 +#endif
13512 +/* C_Verify verifies a signature in a single-part operation, 
13513 + * where the signature is an appendix to the data, and plaintext
13514 + * cannot be recovered from the signature. */
13515 +CK_PKCS11_FUNCTION_INFO(C_Verify)
13516 +#ifdef CK_NEED_ARG_LIST
13518 +  CK_SESSION_HANDLE hSession,       /* the session's handle */
13519 +  CK_BYTE_PTR       pData,          /* signed data */
13520 +  CK_ULONG          ulDataLen,      /* length of signed data */
13521 +  CK_BYTE_PTR       pSignature,     /* signature */
13522 +  CK_ULONG          ulSignatureLen  /* signature length*/
13524 +#endif
13527 +/* C_VerifyUpdate continues a multiple-part verification
13528 + * operation, where the signature is an appendix to the data, 
13529 + * and plaintext cannot be recovered from the signature. */
13530 +CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
13531 +#ifdef CK_NEED_ARG_LIST
13533 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13534 +  CK_BYTE_PTR       pPart,     /* signed data */
13535 +  CK_ULONG          ulPartLen  /* length of signed data */
13537 +#endif
13540 +/* C_VerifyFinal finishes a multiple-part verification
13541 + * operation, checking the signature. */
13542 +CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
13543 +#ifdef CK_NEED_ARG_LIST
13545 +  CK_SESSION_HANDLE hSession,       /* the session's handle */
13546 +  CK_BYTE_PTR       pSignature,     /* signature to verify */
13547 +  CK_ULONG          ulSignatureLen  /* signature length */
13549 +#endif
13552 +/* C_VerifyRecoverInit initializes a signature verification
13553 + * operation, where the data is recovered from the signature. */
13554 +CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
13555 +#ifdef CK_NEED_ARG_LIST
13557 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
13558 +  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
13559 +  CK_OBJECT_HANDLE  hKey         /* verification key */
13561 +#endif
13564 +/* C_VerifyRecover verifies a signature in a single-part
13565 + * operation, where the data is recovered from the signature. */
13566 +CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
13567 +#ifdef CK_NEED_ARG_LIST
13569 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
13570 +  CK_BYTE_PTR       pSignature,      /* signature to verify */
13571 +  CK_ULONG          ulSignatureLen,  /* signature length */
13572 +  CK_BYTE_PTR       pData,           /* gets signed data */
13573 +  CK_ULONG_PTR      pulDataLen       /* gets signed data len */
13575 +#endif
13579 +/* Dual-function cryptographic operations */
13581 +/* C_DigestEncryptUpdate continues a multiple-part digesting
13582 + * and encryption operation. */
13583 +CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
13584 +#ifdef CK_NEED_ARG_LIST
13586 +  CK_SESSION_HANDLE hSession,            /* session's handle */
13587 +  CK_BYTE_PTR       pPart,               /* the plaintext data */
13588 +  CK_ULONG          ulPartLen,           /* plaintext length */
13589 +  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
13590 +  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
13592 +#endif
13595 +/* C_DecryptDigestUpdate continues a multiple-part decryption and
13596 + * digesting operation. */
13597 +CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
13598 +#ifdef CK_NEED_ARG_LIST
13600 +  CK_SESSION_HANDLE hSession,            /* session's handle */
13601 +  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
13602 +  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
13603 +  CK_BYTE_PTR       pPart,               /* gets plaintext */
13604 +  CK_ULONG_PTR      pulPartLen           /* gets plaintext len */
13606 +#endif
13609 +/* C_SignEncryptUpdate continues a multiple-part signing and
13610 + * encryption operation. */
13611 +CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
13612 +#ifdef CK_NEED_ARG_LIST
13614 +  CK_SESSION_HANDLE hSession,            /* session's handle */
13615 +  CK_BYTE_PTR       pPart,               /* the plaintext data */
13616 +  CK_ULONG          ulPartLen,           /* plaintext length */
13617 +  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
13618 +  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
13620 +#endif
13623 +/* C_DecryptVerifyUpdate continues a multiple-part decryption and
13624 + * verify operation. */
13625 +CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
13626 +#ifdef CK_NEED_ARG_LIST
13628 +  CK_SESSION_HANDLE hSession,            /* session's handle */
13629 +  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
13630 +  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
13631 +  CK_BYTE_PTR       pPart,               /* gets plaintext */
13632 +  CK_ULONG_PTR      pulPartLen           /* gets p-text length */
13634 +#endif
13638 +/* Key management */
13640 +/* C_GenerateKey generates a secret key, creating a new key
13641 + * object. */
13642 +CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
13643 +#ifdef CK_NEED_ARG_LIST
13645 +  CK_SESSION_HANDLE    hSession,    /* the session's handle */
13646 +  CK_MECHANISM_PTR     pMechanism,  /* key generation mech. */
13647 +  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new key */
13648 +  CK_ULONG             ulCount,     /* # of attrs in template */
13649 +  CK_OBJECT_HANDLE_PTR phKey        /* gets handle of new key */
13651 +#endif
13654 +/* C_GenerateKeyPair generates a public-key/private-key pair, 
13655 + * creating new key objects. */
13656 +CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
13657 +#ifdef CK_NEED_ARG_LIST
13659 +  CK_SESSION_HANDLE    hSession,                    /* session
13660 +                                                     * handle */
13661 +  CK_MECHANISM_PTR     pMechanism,                  /* key-gen
13662 +                                                     * mech. */
13663 +  CK_ATTRIBUTE_PTR     pPublicKeyTemplate,          /* template
13664 +                                                     * for pub.
13665 +                                                     * key */
13666 +  CK_ULONG             ulPublicKeyAttributeCount,   /* # pub.
13667 +                                                     * attrs. */
13668 +  CK_ATTRIBUTE_PTR     pPrivateKeyTemplate,         /* template
13669 +                                                     * for priv.
13670 +                                                     * key */
13671 +  CK_ULONG             ulPrivateKeyAttributeCount,  /* # priv.
13672 +                                                     * attrs. */
13673 +  CK_OBJECT_HANDLE_PTR phPublicKey,                 /* gets pub.
13674 +                                                     * key
13675 +                                                     * handle */
13676 +  CK_OBJECT_HANDLE_PTR phPrivateKey                 /* gets
13677 +                                                     * priv. key
13678 +                                                     * handle */
13680 +#endif
13683 +/* C_WrapKey wraps (i.e., encrypts) a key. */
13684 +CK_PKCS11_FUNCTION_INFO(C_WrapKey)
13685 +#ifdef CK_NEED_ARG_LIST
13687 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
13688 +  CK_MECHANISM_PTR  pMechanism,      /* the wrapping mechanism */
13689 +  CK_OBJECT_HANDLE  hWrappingKey,    /* wrapping key */
13690 +  CK_OBJECT_HANDLE  hKey,            /* key to be wrapped */
13691 +  CK_BYTE_PTR       pWrappedKey,     /* gets wrapped key */
13692 +  CK_ULONG_PTR      pulWrappedKeyLen /* gets wrapped key size */
13694 +#endif
13697 +/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
13698 + * key object. */
13699 +CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
13700 +#ifdef CK_NEED_ARG_LIST
13702 +  CK_SESSION_HANDLE    hSession,          /* session's handle */
13703 +  CK_MECHANISM_PTR     pMechanism,        /* unwrapping mech. */
13704 +  CK_OBJECT_HANDLE     hUnwrappingKey,    /* unwrapping key */
13705 +  CK_BYTE_PTR          pWrappedKey,       /* the wrapped key */
13706 +  CK_ULONG             ulWrappedKeyLen,   /* wrapped key len */
13707 +  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
13708 +  CK_ULONG             ulAttributeCount,  /* template length */
13709 +  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
13711 +#endif
13714 +/* C_DeriveKey derives a key from a base key, creating a new key
13715 + * object. */
13716 +CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
13717 +#ifdef CK_NEED_ARG_LIST
13719 +  CK_SESSION_HANDLE    hSession,          /* session's handle */
13720 +  CK_MECHANISM_PTR     pMechanism,        /* key deriv. mech. */
13721 +  CK_OBJECT_HANDLE     hBaseKey,          /* base key */
13722 +  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
13723 +  CK_ULONG             ulAttributeCount,  /* template length */
13724 +  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
13726 +#endif
13730 +/* Random number generation */
13732 +/* C_SeedRandom mixes additional seed material into the token's
13733 + * random number generator. */
13734 +CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
13735 +#ifdef CK_NEED_ARG_LIST
13737 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
13738 +  CK_BYTE_PTR       pSeed,     /* the seed material */
13739 +  CK_ULONG          ulSeedLen  /* length of seed material */
13741 +#endif
13744 +/* C_GenerateRandom generates random data. */
13745 +CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
13746 +#ifdef CK_NEED_ARG_LIST
13748 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
13749 +  CK_BYTE_PTR       RandomData,  /* receives the random data */
13750 +  CK_ULONG          ulRandomLen  /* # of bytes to generate */
13752 +#endif
13756 +/* Parallel function management */
13758 +/* C_GetFunctionStatus is a legacy function; it obtains an
13759 + * updated status of a function running in parallel with an
13760 + * application. */
13761 +CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
13762 +#ifdef CK_NEED_ARG_LIST
13764 +  CK_SESSION_HANDLE hSession  /* the session's handle */
13766 +#endif
13769 +/* C_CancelFunction is a legacy function; it cancels a function
13770 + * running in parallel. */
13771 +CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
13772 +#ifdef CK_NEED_ARG_LIST
13774 +  CK_SESSION_HANDLE hSession  /* the session's handle */
13776 +#endif
13780 +/* Functions added in for Cryptoki Version 2.01 or later */
13782 +/* C_WaitForSlotEvent waits for a slot event (token insertion,
13783 + * removal, etc.) to occur. */
13784 +CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
13785 +#ifdef CK_NEED_ARG_LIST
13787 +  CK_FLAGS flags,        /* blocking/nonblocking flag */
13788 +  CK_SLOT_ID_PTR pSlot,  /* location that receives the slot ID */
13789 +  CK_VOID_PTR pRserved   /* reserved.  Should be NULL_PTR */
13791 +#endif
13792 Index: openssl/crypto/engine/pkcs11t.h
13793 diff -u /dev/null openssl/crypto/engine/pkcs11t.h:1.2
13794 --- /dev/null   Fri Jan  2 14:59:08 2015
13795 +++ openssl/crypto/engine/pkcs11t.h     Sat Aug 30 11:58:07 2008
13796 @@ -0,0 +1,1885 @@
13797 +/* pkcs11t.h include file for PKCS #11. */
13798 +/* Revision: 1.2  */
13800 +/* License to copy and use this software is granted provided that it is
13801 + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
13802 + * (Cryptoki)" in all material mentioning or referencing this software.
13804 + * License is also granted to make and use derivative works provided that
13805 + * such works are identified as "derived from the RSA Security Inc. PKCS #11
13806 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
13807 + * referencing the derived work.
13809 + * RSA Security Inc. makes no representations concerning either the
13810 + * merchantability of this software or the suitability of this software for
13811 + * any particular purpose. It is provided "as is" without express or implied
13812 + * warranty of any kind.
13813 + */
13815 +/* See top of pkcs11.h for information about the macros that
13816 + * must be defined and the structure-packing conventions that
13817 + * must be set before including this file. */
13819 +#ifndef _PKCS11T_H_
13820 +#define _PKCS11T_H_ 1
13822 +#define CRYPTOKI_VERSION_MAJOR 2
13823 +#define CRYPTOKI_VERSION_MINOR 20
13824 +#define CRYPTOKI_VERSION_AMENDMENT 3
13826 +#define CK_TRUE 1
13827 +#define CK_FALSE 0
13829 +#ifndef CK_DISABLE_TRUE_FALSE
13830 +#ifndef FALSE
13831 +#define FALSE CK_FALSE
13832 +#endif
13834 +#ifndef TRUE
13835 +#define TRUE CK_TRUE
13836 +#endif
13837 +#endif
13839 +/* an unsigned 8-bit value */
13840 +typedef unsigned char     CK_BYTE;
13842 +/* an unsigned 8-bit character */
13843 +typedef CK_BYTE           CK_CHAR;
13845 +/* an 8-bit UTF-8 character */
13846 +typedef CK_BYTE           CK_UTF8CHAR;
13848 +/* a BYTE-sized Boolean flag */
13849 +typedef CK_BYTE           CK_BBOOL;
13851 +/* an unsigned value, at least 32 bits long */
13852 +typedef unsigned long int CK_ULONG;
13854 +/* a signed value, the same size as a CK_ULONG */
13855 +/* CK_LONG is new for v2.0 */
13856 +typedef long int          CK_LONG;
13858 +/* at least 32 bits; each bit is a Boolean flag */
13859 +typedef CK_ULONG          CK_FLAGS;
13862 +/* some special values for certain CK_ULONG variables */
13863 +#define CK_UNAVAILABLE_INFORMATION (~0UL)
13864 +#define CK_EFFECTIVELY_INFINITE    0
13867 +typedef CK_BYTE     CK_PTR   CK_BYTE_PTR;
13868 +typedef CK_CHAR     CK_PTR   CK_CHAR_PTR;
13869 +typedef CK_UTF8CHAR CK_PTR   CK_UTF8CHAR_PTR;
13870 +typedef CK_ULONG    CK_PTR   CK_ULONG_PTR;
13871 +typedef void        CK_PTR   CK_VOID_PTR;
13873 +/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
13874 +typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
13877 +/* The following value is always invalid if used as a session */
13878 +/* handle or object handle */
13879 +#define CK_INVALID_HANDLE 0
13882 +typedef struct CK_VERSION {
13883 +  CK_BYTE       major;  /* integer portion of version number */
13884 +  CK_BYTE       minor;  /* 1/100ths portion of version number */
13885 +} CK_VERSION;
13887 +typedef CK_VERSION CK_PTR CK_VERSION_PTR;
13890 +typedef struct CK_INFO {
13891 +  /* manufacturerID and libraryDecription have been changed from
13892 +   * CK_CHAR to CK_UTF8CHAR for v2.10 */
13893 +  CK_VERSION    cryptokiVersion;     /* Cryptoki interface ver */
13894 +  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
13895 +  CK_FLAGS      flags;               /* must be zero */
13897 +  /* libraryDescription and libraryVersion are new for v2.0 */
13898 +  CK_UTF8CHAR   libraryDescription[32];  /* blank padded */
13899 +  CK_VERSION    libraryVersion;          /* version of library */
13900 +} CK_INFO;
13902 +typedef CK_INFO CK_PTR    CK_INFO_PTR;
13905 +/* CK_NOTIFICATION enumerates the types of notifications that
13906 + * Cryptoki provides to an application */
13907 +/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
13908 + * for v2.0 */
13909 +typedef CK_ULONG CK_NOTIFICATION;
13910 +#define CKN_SURRENDER       0
13912 +/* The following notification is new for PKCS #11 v2.20 amendment 3 */
13913 +#define CKN_OTP_CHANGED     1
13916 +typedef CK_ULONG          CK_SLOT_ID;
13918 +typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
13921 +/* CK_SLOT_INFO provides information about a slot */
13922 +typedef struct CK_SLOT_INFO {
13923 +  /* slotDescription and manufacturerID have been changed from
13924 +   * CK_CHAR to CK_UTF8CHAR for v2.10 */
13925 +  CK_UTF8CHAR   slotDescription[64];  /* blank padded */
13926 +  CK_UTF8CHAR   manufacturerID[32];   /* blank padded */
13927 +  CK_FLAGS      flags;
13929 +  /* hardwareVersion and firmwareVersion are new for v2.0 */
13930 +  CK_VERSION    hardwareVersion;  /* version of hardware */
13931 +  CK_VERSION    firmwareVersion;  /* version of firmware */
13932 +} CK_SLOT_INFO;
13934 +/* flags: bit flags that provide capabilities of the slot
13935 + *      Bit Flag              Mask        Meaning
13936 + */
13937 +#define CKF_TOKEN_PRESENT     0x00000001  /* a token is there */
13938 +#define CKF_REMOVABLE_DEVICE  0x00000002  /* removable devices*/
13939 +#define CKF_HW_SLOT           0x00000004  /* hardware slot */
13941 +typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
13944 +/* CK_TOKEN_INFO provides information about a token */
13945 +typedef struct CK_TOKEN_INFO {
13946 +  /* label, manufacturerID, and model have been changed from
13947 +   * CK_CHAR to CK_UTF8CHAR for v2.10 */
13948 +  CK_UTF8CHAR   label[32];           /* blank padded */
13949 +  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
13950 +  CK_UTF8CHAR   model[16];           /* blank padded */
13951 +  CK_CHAR       serialNumber[16];    /* blank padded */
13952 +  CK_FLAGS      flags;               /* see below */
13954 +  /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
13955 +   * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
13956 +   * changed from CK_USHORT to CK_ULONG for v2.0 */
13957 +  CK_ULONG      ulMaxSessionCount;     /* max open sessions */
13958 +  CK_ULONG      ulSessionCount;        /* sess. now open */
13959 +  CK_ULONG      ulMaxRwSessionCount;   /* max R/W sessions */
13960 +  CK_ULONG      ulRwSessionCount;      /* R/W sess. now open */
13961 +  CK_ULONG      ulMaxPinLen;           /* in bytes */
13962 +  CK_ULONG      ulMinPinLen;           /* in bytes */
13963 +  CK_ULONG      ulTotalPublicMemory;   /* in bytes */
13964 +  CK_ULONG      ulFreePublicMemory;    /* in bytes */
13965 +  CK_ULONG      ulTotalPrivateMemory;  /* in bytes */
13966 +  CK_ULONG      ulFreePrivateMemory;   /* in bytes */
13968 +  /* hardwareVersion, firmwareVersion, and time are new for
13969 +   * v2.0 */
13970 +  CK_VERSION    hardwareVersion;       /* version of hardware */
13971 +  CK_VERSION    firmwareVersion;       /* version of firmware */
13972 +  CK_CHAR       utcTime[16];           /* time */
13973 +} CK_TOKEN_INFO;
13975 +/* The flags parameter is defined as follows:
13976 + *      Bit Flag                    Mask        Meaning
13977 + */
13978 +#define CKF_RNG                     0x00000001  /* has random #
13979 +                                                 * generator */
13980 +#define CKF_WRITE_PROTECTED         0x00000002  /* token is
13981 +                                                 * write-
13982 +                                                 * protected */
13983 +#define CKF_LOGIN_REQUIRED          0x00000004  /* user must
13984 +                                                 * login */
13985 +#define CKF_USER_PIN_INITIALIZED    0x00000008  /* normal user's
13986 +                                                 * PIN is set */
13988 +/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0.  If it is set,
13989 + * that means that *every* time the state of cryptographic
13990 + * operations of a session is successfully saved, all keys
13991 + * needed to continue those operations are stored in the state */
13992 +#define CKF_RESTORE_KEY_NOT_NEEDED  0x00000020
13994 +/* CKF_CLOCK_ON_TOKEN is new for v2.0.  If it is set, that means
13995 + * that the token has some sort of clock.  The time on that
13996 + * clock is returned in the token info structure */
13997 +#define CKF_CLOCK_ON_TOKEN          0x00000040
13999 +/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0.  If it is
14000 + * set, that means that there is some way for the user to login
14001 + * without sending a PIN through the Cryptoki library itself */
14002 +#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
14004 +/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0.  If it is true,
14005 + * that means that a single session with the token can perform
14006 + * dual simultaneous cryptographic operations (digest and
14007 + * encrypt; decrypt and digest; sign and encrypt; and decrypt
14008 + * and sign) */
14009 +#define CKF_DUAL_CRYPTO_OPERATIONS  0x00000200
14011 +/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
14012 + * token has been initialized using C_InitializeToken or an
14013 + * equivalent mechanism outside the scope of PKCS #11.
14014 + * Calling C_InitializeToken when this flag is set will cause
14015 + * the token to be reinitialized. */
14016 +#define CKF_TOKEN_INITIALIZED       0x00000400
14018 +/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
14019 + * true, the token supports secondary authentication for
14020 + * private key objects. This flag is deprecated in v2.11 and
14021 +   onwards. */
14022 +#define CKF_SECONDARY_AUTHENTICATION  0x00000800
14024 +/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
14025 + * incorrect user login PIN has been entered at least once
14026 + * since the last successful authentication. */
14027 +#define CKF_USER_PIN_COUNT_LOW       0x00010000
14029 +/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
14030 + * supplying an incorrect user PIN will it to become locked. */
14031 +#define CKF_USER_PIN_FINAL_TRY       0x00020000
14033 +/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
14034 + * user PIN has been locked. User login to the token is not
14035 + * possible. */
14036 +#define CKF_USER_PIN_LOCKED          0x00040000
14038 +/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
14039 + * the user PIN value is the default value set by token
14040 + * initialization or manufacturing, or the PIN has been
14041 + * expired by the card. */
14042 +#define CKF_USER_PIN_TO_BE_CHANGED   0x00080000
14044 +/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
14045 + * incorrect SO login PIN has been entered at least once since
14046 + * the last successful authentication. */
14047 +#define CKF_SO_PIN_COUNT_LOW         0x00100000
14049 +/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
14050 + * supplying an incorrect SO PIN will it to become locked. */
14051 +#define CKF_SO_PIN_FINAL_TRY         0x00200000
14053 +/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
14054 + * PIN has been locked. SO login to the token is not possible.
14055 + */
14056 +#define CKF_SO_PIN_LOCKED            0x00400000
14058 +/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
14059 + * the SO PIN value is the default value set by token
14060 + * initialization or manufacturing, or the PIN has been
14061 + * expired by the card. */
14062 +#define CKF_SO_PIN_TO_BE_CHANGED     0x00800000
14064 +typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
14067 +/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
14068 + * identifies a session */
14069 +typedef CK_ULONG          CK_SESSION_HANDLE;
14071 +typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
14074 +/* CK_USER_TYPE enumerates the types of Cryptoki users */
14075 +/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
14076 + * v2.0 */
14077 +typedef CK_ULONG          CK_USER_TYPE;
14078 +/* Security Officer */
14079 +#define CKU_SO    0
14080 +/* Normal user */
14081 +#define CKU_USER  1
14082 +/* Context specific (added in v2.20) */
14083 +#define CKU_CONTEXT_SPECIFIC   2
14085 +/* CK_STATE enumerates the session states */
14086 +/* CK_STATE has been changed from an enum to a CK_ULONG for
14087 + * v2.0 */
14088 +typedef CK_ULONG          CK_STATE;
14089 +#define CKS_RO_PUBLIC_SESSION  0
14090 +#define CKS_RO_USER_FUNCTIONS  1
14091 +#define CKS_RW_PUBLIC_SESSION  2
14092 +#define CKS_RW_USER_FUNCTIONS  3
14093 +#define CKS_RW_SO_FUNCTIONS    4
14096 +/* CK_SESSION_INFO provides information about a session */
14097 +typedef struct CK_SESSION_INFO {
14098 +  CK_SLOT_ID    slotID;
14099 +  CK_STATE      state;
14100 +  CK_FLAGS      flags;          /* see below */
14102 +  /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
14103 +   * v2.0 */
14104 +  CK_ULONG      ulDeviceError;  /* device-dependent error code */
14105 +} CK_SESSION_INFO;
14107 +/* The flags are defined in the following table:
14108 + *      Bit Flag                Mask        Meaning
14109 + */
14110 +#define CKF_RW_SESSION          0x00000002  /* session is r/w */
14111 +#define CKF_SERIAL_SESSION      0x00000004  /* no parallel */
14113 +typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
14116 +/* CK_OBJECT_HANDLE is a token-specific identifier for an
14117 + * object  */
14118 +typedef CK_ULONG          CK_OBJECT_HANDLE;
14120 +typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
14123 +/* CK_OBJECT_CLASS is a value that identifies the classes (or
14124 + * types) of objects that Cryptoki recognizes.  It is defined
14125 + * as follows: */
14126 +/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
14127 + * v2.0 */
14128 +typedef CK_ULONG          CK_OBJECT_CLASS;
14130 +/* The following classes of objects are defined: */
14131 +/* CKO_HW_FEATURE is new for v2.10 */
14132 +/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
14133 +/* CKO_MECHANISM is new for v2.20 */
14134 +#define CKO_DATA              0x00000000
14135 +#define CKO_CERTIFICATE       0x00000001
14136 +#define CKO_PUBLIC_KEY        0x00000002
14137 +#define CKO_PRIVATE_KEY       0x00000003
14138 +#define CKO_SECRET_KEY        0x00000004
14139 +#define CKO_HW_FEATURE        0x00000005
14140 +#define CKO_DOMAIN_PARAMETERS 0x00000006
14141 +#define CKO_MECHANISM         0x00000007
14143 +/* CKO_OTP_KEY is new for PKCS #11 v2.20 amendment 1 */
14144 +#define CKO_OTP_KEY           0x00000008
14146 +#define CKO_VENDOR_DEFINED    0x80000000
14148 +typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
14150 +/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
14151 + * value that identifies the hardware feature type of an object
14152 + * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
14153 +typedef CK_ULONG          CK_HW_FEATURE_TYPE;
14155 +/* The following hardware feature types are defined */
14156 +/* CKH_USER_INTERFACE is new for v2.20 */
14157 +#define CKH_MONOTONIC_COUNTER  0x00000001
14158 +#define CKH_CLOCK           0x00000002
14159 +#define CKH_USER_INTERFACE  0x00000003
14160 +#define CKH_VENDOR_DEFINED  0x80000000
14162 +/* CK_KEY_TYPE is a value that identifies a key type */
14163 +/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
14164 +typedef CK_ULONG          CK_KEY_TYPE;
14166 +/* the following key types are defined: */
14167 +#define CKK_RSA             0x00000000
14168 +#define CKK_DSA             0x00000001
14169 +#define CKK_DH              0x00000002
14171 +/* CKK_ECDSA and CKK_KEA are new for v2.0 */
14172 +/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
14173 +#define CKK_ECDSA           0x00000003
14174 +#define CKK_EC              0x00000003
14175 +#define CKK_X9_42_DH        0x00000004
14176 +#define CKK_KEA             0x00000005
14178 +#define CKK_GENERIC_SECRET  0x00000010
14179 +#define CKK_RC2             0x00000011
14180 +#define CKK_RC4             0x00000012
14181 +#define CKK_DES             0x00000013
14182 +#define CKK_DES2            0x00000014
14183 +#define CKK_DES3            0x00000015
14185 +/* all these key types are new for v2.0 */
14186 +#define CKK_CAST            0x00000016
14187 +#define CKK_CAST3           0x00000017
14188 +/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
14189 +#define CKK_CAST5           0x00000018
14190 +#define CKK_CAST128         0x00000018
14191 +#define CKK_RC5             0x00000019
14192 +#define CKK_IDEA            0x0000001A
14193 +#define CKK_SKIPJACK        0x0000001B
14194 +#define CKK_BATON           0x0000001C
14195 +#define CKK_JUNIPER         0x0000001D
14196 +#define CKK_CDMF            0x0000001E
14197 +#define CKK_AES             0x0000001F
14199 +/* BlowFish and TwoFish are new for v2.20 */
14200 +#define CKK_BLOWFISH        0x00000020
14201 +#define CKK_TWOFISH         0x00000021
14203 +/* SecurID, HOTP, and ACTI are new for PKCS #11 v2.20 amendment 1 */
14204 +#define CKK_SECURID         0x00000022
14205 +#define CKK_HOTP            0x00000023
14206 +#define CKK_ACTI            0x00000024
14208 +/* Camellia is new for PKCS #11 v2.20 amendment 3 */
14209 +#define CKK_CAMELLIA                   0x00000025
14210 +/* ARIA is new for PKCS #11 v2.20 amendment 3 */
14211 +#define CKK_ARIA                       0x00000026
14214 +#define CKK_VENDOR_DEFINED  0x80000000
14217 +/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
14218 + * type */
14219 +/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
14220 + * for v2.0 */
14221 +typedef CK_ULONG          CK_CERTIFICATE_TYPE;
14223 +/* The following certificate types are defined: */
14224 +/* CKC_X_509_ATTR_CERT is new for v2.10 */
14225 +/* CKC_WTLS is new for v2.20 */
14226 +#define CKC_X_509           0x00000000
14227 +#define CKC_X_509_ATTR_CERT 0x00000001
14228 +#define CKC_WTLS            0x00000002
14229 +#define CKC_VENDOR_DEFINED  0x80000000
14232 +/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
14233 + * type */
14234 +/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
14235 + * v2.0 */
14236 +typedef CK_ULONG          CK_ATTRIBUTE_TYPE;
14238 +/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
14239 +   consists of an array of values. */
14240 +#define CKF_ARRAY_ATTRIBUTE    0x40000000
14242 +/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1
14243 +   and relates to the CKA_OTP_FORMAT attribute */
14244 +#define CK_OTP_FORMAT_DECIMAL      0
14245 +#define CK_OTP_FORMAT_HEXADECIMAL  1
14246 +#define CK_OTP_FORMAT_ALPHANUMERIC 2
14247 +#define CK_OTP_FORMAT_BINARY       3
14249 +/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1
14250 +   and relates to the CKA_OTP_..._REQUIREMENT attributes */
14251 +#define CK_OTP_PARAM_IGNORED       0
14252 +#define CK_OTP_PARAM_OPTIONAL      1
14253 +#define CK_OTP_PARAM_MANDATORY     2
14255 +/* The following attribute types are defined: */
14256 +#define CKA_CLASS              0x00000000
14257 +#define CKA_TOKEN              0x00000001
14258 +#define CKA_PRIVATE            0x00000002
14259 +#define CKA_LABEL              0x00000003
14260 +#define CKA_APPLICATION        0x00000010
14261 +#define CKA_VALUE              0x00000011
14263 +/* CKA_OBJECT_ID is new for v2.10 */
14264 +#define CKA_OBJECT_ID          0x00000012
14266 +#define CKA_CERTIFICATE_TYPE   0x00000080
14267 +#define CKA_ISSUER             0x00000081
14268 +#define CKA_SERIAL_NUMBER      0x00000082
14270 +/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
14271 + * for v2.10 */
14272 +#define CKA_AC_ISSUER          0x00000083
14273 +#define CKA_OWNER              0x00000084
14274 +#define CKA_ATTR_TYPES         0x00000085
14276 +/* CKA_TRUSTED is new for v2.11 */
14277 +#define CKA_TRUSTED            0x00000086
14279 +/* CKA_CERTIFICATE_CATEGORY ...
14280 + * CKA_CHECK_VALUE are new for v2.20 */
14281 +#define CKA_CERTIFICATE_CATEGORY        0x00000087
14282 +#define CKA_JAVA_MIDP_SECURITY_DOMAIN   0x00000088
14283 +#define CKA_URL                         0x00000089
14284 +#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY  0x0000008A
14285 +#define CKA_HASH_OF_ISSUER_PUBLIC_KEY   0x0000008B
14286 +#define CKA_CHECK_VALUE                 0x00000090
14288 +#define CKA_KEY_TYPE           0x00000100
14289 +#define CKA_SUBJECT            0x00000101
14290 +#define CKA_ID                 0x00000102
14291 +#define CKA_SENSITIVE          0x00000103
14292 +#define CKA_ENCRYPT            0x00000104
14293 +#define CKA_DECRYPT            0x00000105
14294 +#define CKA_WRAP               0x00000106
14295 +#define CKA_UNWRAP             0x00000107
14296 +#define CKA_SIGN               0x00000108
14297 +#define CKA_SIGN_RECOVER       0x00000109
14298 +#define CKA_VERIFY             0x0000010A
14299 +#define CKA_VERIFY_RECOVER     0x0000010B
14300 +#define CKA_DERIVE             0x0000010C
14301 +#define CKA_START_DATE         0x00000110
14302 +#define CKA_END_DATE           0x00000111
14303 +#define CKA_MODULUS            0x00000120
14304 +#define CKA_MODULUS_BITS       0x00000121
14305 +#define CKA_PUBLIC_EXPONENT    0x00000122
14306 +#define CKA_PRIVATE_EXPONENT   0x00000123
14307 +#define CKA_PRIME_1            0x00000124
14308 +#define CKA_PRIME_2            0x00000125
14309 +#define CKA_EXPONENT_1         0x00000126
14310 +#define CKA_EXPONENT_2         0x00000127
14311 +#define CKA_COEFFICIENT        0x00000128
14312 +#define CKA_PRIME              0x00000130
14313 +#define CKA_SUBPRIME           0x00000131
14314 +#define CKA_BASE               0x00000132
14316 +/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
14317 +#define CKA_PRIME_BITS         0x00000133
14318 +#define CKA_SUBPRIME_BITS      0x00000134
14319 +#define CKA_SUB_PRIME_BITS     CKA_SUBPRIME_BITS
14320 +/* (To retain backwards-compatibility) */
14322 +#define CKA_VALUE_BITS         0x00000160
14323 +#define CKA_VALUE_LEN          0x00000161
14325 +/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
14326 + * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
14327 + * and CKA_EC_POINT are new for v2.0 */
14328 +#define CKA_EXTRACTABLE        0x00000162
14329 +#define CKA_LOCAL              0x00000163
14330 +#define CKA_NEVER_EXTRACTABLE  0x00000164
14331 +#define CKA_ALWAYS_SENSITIVE   0x00000165
14333 +/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
14334 +#define CKA_KEY_GEN_MECHANISM  0x00000166
14336 +#define CKA_MODIFIABLE         0x00000170
14338 +/* CKA_ECDSA_PARAMS is deprecated in v2.11,
14339 + * CKA_EC_PARAMS is preferred. */
14340 +#define CKA_ECDSA_PARAMS       0x00000180
14341 +#define CKA_EC_PARAMS          0x00000180
14343 +#define CKA_EC_POINT           0x00000181
14345 +/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
14346 + * are new for v2.10. Deprecated in v2.11 and onwards. */
14347 +#define CKA_SECONDARY_AUTH     0x00000200
14348 +#define CKA_AUTH_PIN_FLAGS     0x00000201
14350 +/* CKA_ALWAYS_AUTHENTICATE ...
14351 + * CKA_UNWRAP_TEMPLATE are new for v2.20 */
14352 +#define CKA_ALWAYS_AUTHENTICATE  0x00000202
14354 +#define CKA_WRAP_WITH_TRUSTED    0x00000210
14355 +#define CKA_WRAP_TEMPLATE        (CKF_ARRAY_ATTRIBUTE|0x00000211)
14356 +#define CKA_UNWRAP_TEMPLATE      (CKF_ARRAY_ATTRIBUTE|0x00000212)
14358 +/* CKA_OTP... atttributes are new for PKCS #11 v2.20 amendment 3. */
14359 +#define CKA_OTP_FORMAT                0x00000220
14360 +#define CKA_OTP_LENGTH                0x00000221
14361 +#define CKA_OTP_TIME_INTERVAL         0x00000222
14362 +#define CKA_OTP_USER_FRIENDLY_MODE    0x00000223
14363 +#define CKA_OTP_CHALLENGE_REQUIREMENT 0x00000224
14364 +#define CKA_OTP_TIME_REQUIREMENT      0x00000225
14365 +#define CKA_OTP_COUNTER_REQUIREMENT   0x00000226
14366 +#define CKA_OTP_PIN_REQUIREMENT       0x00000227
14367 +#define CKA_OTP_COUNTER               0x0000022E
14368 +#define CKA_OTP_TIME                  0x0000022F
14369 +#define CKA_OTP_USER_IDENTIFIER       0x0000022A
14370 +#define CKA_OTP_SERVICE_IDENTIFIER    0x0000022B
14371 +#define CKA_OTP_SERVICE_LOGO          0x0000022C
14372 +#define CKA_OTP_SERVICE_LOGO_TYPE     0x0000022D
14375 +/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
14376 + * are new for v2.10 */
14377 +#define CKA_HW_FEATURE_TYPE    0x00000300
14378 +#define CKA_RESET_ON_INIT      0x00000301
14379 +#define CKA_HAS_RESET          0x00000302
14381 +/* The following attributes are new for v2.20 */
14382 +#define CKA_PIXEL_X                     0x00000400
14383 +#define CKA_PIXEL_Y                     0x00000401
14384 +#define CKA_RESOLUTION                  0x00000402
14385 +#define CKA_CHAR_ROWS                   0x00000403
14386 +#define CKA_CHAR_COLUMNS                0x00000404
14387 +#define CKA_COLOR                       0x00000405
14388 +#define CKA_BITS_PER_PIXEL              0x00000406
14389 +#define CKA_CHAR_SETS                   0x00000480
14390 +#define CKA_ENCODING_METHODS            0x00000481
14391 +#define CKA_MIME_TYPES                  0x00000482
14392 +#define CKA_MECHANISM_TYPE              0x00000500
14393 +#define CKA_REQUIRED_CMS_ATTRIBUTES     0x00000501
14394 +#define CKA_DEFAULT_CMS_ATTRIBUTES      0x00000502
14395 +#define CKA_SUPPORTED_CMS_ATTRIBUTES    0x00000503
14396 +#define CKA_ALLOWED_MECHANISMS          (CKF_ARRAY_ATTRIBUTE|0x00000600)
14398 +#define CKA_VENDOR_DEFINED     0x80000000
14400 +/* CK_ATTRIBUTE is a structure that includes the type, length
14401 + * and value of an attribute */
14402 +typedef struct CK_ATTRIBUTE {
14403 +  CK_ATTRIBUTE_TYPE type;
14404 +  CK_VOID_PTR       pValue;
14406 +  /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
14407 +  CK_ULONG          ulValueLen;  /* in bytes */
14408 +} CK_ATTRIBUTE;
14410 +typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
14413 +/* CK_DATE is a structure that defines a date */
14414 +typedef struct CK_DATE{
14415 +  CK_CHAR       year[4];   /* the year ("1900" - "9999") */
14416 +  CK_CHAR       month[2];  /* the month ("01" - "12") */
14417 +  CK_CHAR       day[2];    /* the day   ("01" - "31") */
14418 +} CK_DATE;
14421 +/* CK_MECHANISM_TYPE is a value that identifies a mechanism
14422 + * type */
14423 +/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
14424 + * v2.0 */
14425 +typedef CK_ULONG          CK_MECHANISM_TYPE;
14427 +/* the following mechanism types are defined: */
14428 +#define CKM_RSA_PKCS_KEY_PAIR_GEN      0x00000000
14429 +#define CKM_RSA_PKCS                   0x00000001
14430 +#define CKM_RSA_9796                   0x00000002
14431 +#define CKM_RSA_X_509                  0x00000003
14433 +/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
14434 + * are new for v2.0.  They are mechanisms which hash and sign */
14435 +#define CKM_MD2_RSA_PKCS               0x00000004
14436 +#define CKM_MD5_RSA_PKCS               0x00000005
14437 +#define CKM_SHA1_RSA_PKCS              0x00000006
14439 +/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
14440 + * CKM_RSA_PKCS_OAEP are new for v2.10 */
14441 +#define CKM_RIPEMD128_RSA_PKCS         0x00000007
14442 +#define CKM_RIPEMD160_RSA_PKCS         0x00000008
14443 +#define CKM_RSA_PKCS_OAEP              0x00000009
14445 +/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
14446 + * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
14447 +#define CKM_RSA_X9_31_KEY_PAIR_GEN     0x0000000A
14448 +#define CKM_RSA_X9_31                  0x0000000B
14449 +#define CKM_SHA1_RSA_X9_31             0x0000000C
14450 +#define CKM_RSA_PKCS_PSS               0x0000000D
14451 +#define CKM_SHA1_RSA_PKCS_PSS          0x0000000E
14453 +#define CKM_DSA_KEY_PAIR_GEN           0x00000010
14454 +#define CKM_DSA                        0x00000011
14455 +#define CKM_DSA_SHA1                   0x00000012
14456 +#define CKM_DH_PKCS_KEY_PAIR_GEN       0x00000020
14457 +#define CKM_DH_PKCS_DERIVE             0x00000021
14459 +/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
14460 + * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
14461 + * v2.11 */
14462 +#define CKM_X9_42_DH_KEY_PAIR_GEN      0x00000030
14463 +#define CKM_X9_42_DH_DERIVE            0x00000031
14464 +#define CKM_X9_42_DH_HYBRID_DERIVE     0x00000032
14465 +#define CKM_X9_42_MQV_DERIVE           0x00000033
14467 +/* CKM_SHA256/384/512 are new for v2.20 */
14468 +#define CKM_SHA256_RSA_PKCS            0x00000040
14469 +#define CKM_SHA384_RSA_PKCS            0x00000041
14470 +#define CKM_SHA512_RSA_PKCS            0x00000042
14471 +#define CKM_SHA256_RSA_PKCS_PSS        0x00000043
14472 +#define CKM_SHA384_RSA_PKCS_PSS        0x00000044
14473 +#define CKM_SHA512_RSA_PKCS_PSS        0x00000045
14475 +/* SHA-224 RSA mechanisms are new for PKCS #11 v2.20 amendment 3 */
14476 +#define CKM_SHA224_RSA_PKCS            0x00000046
14477 +#define CKM_SHA224_RSA_PKCS_PSS        0x00000047
14479 +#define CKM_RC2_KEY_GEN                0x00000100
14480 +#define CKM_RC2_ECB                    0x00000101
14481 +#define CKM_RC2_CBC                    0x00000102
14482 +#define CKM_RC2_MAC                    0x00000103
14484 +/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
14485 +#define CKM_RC2_MAC_GENERAL            0x00000104
14486 +#define CKM_RC2_CBC_PAD                0x00000105
14488 +#define CKM_RC4_KEY_GEN                0x00000110
14489 +#define CKM_RC4                        0x00000111
14490 +#define CKM_DES_KEY_GEN                0x00000120
14491 +#define CKM_DES_ECB                    0x00000121
14492 +#define CKM_DES_CBC                    0x00000122
14493 +#define CKM_DES_MAC                    0x00000123
14495 +/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
14496 +#define CKM_DES_MAC_GENERAL            0x00000124
14497 +#define CKM_DES_CBC_PAD                0x00000125
14499 +#define CKM_DES2_KEY_GEN               0x00000130
14500 +#define CKM_DES3_KEY_GEN               0x00000131
14501 +#define CKM_DES3_ECB                   0x00000132
14502 +#define CKM_DES3_CBC                   0x00000133
14503 +#define CKM_DES3_MAC                   0x00000134
14505 +/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
14506 + * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
14507 + * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
14508 +#define CKM_DES3_MAC_GENERAL           0x00000135
14509 +#define CKM_DES3_CBC_PAD               0x00000136
14510 +#define CKM_CDMF_KEY_GEN               0x00000140
14511 +#define CKM_CDMF_ECB                   0x00000141
14512 +#define CKM_CDMF_CBC                   0x00000142
14513 +#define CKM_CDMF_MAC                   0x00000143
14514 +#define CKM_CDMF_MAC_GENERAL           0x00000144
14515 +#define CKM_CDMF_CBC_PAD               0x00000145
14517 +/* the following four DES mechanisms are new for v2.20 */
14518 +#define CKM_DES_OFB64                  0x00000150
14519 +#define CKM_DES_OFB8                   0x00000151
14520 +#define CKM_DES_CFB64                  0x00000152
14521 +#define CKM_DES_CFB8                   0x00000153
14523 +#define CKM_MD2                        0x00000200
14525 +/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
14526 +#define CKM_MD2_HMAC                   0x00000201
14527 +#define CKM_MD2_HMAC_GENERAL           0x00000202
14529 +#define CKM_MD5                        0x00000210
14531 +/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
14532 +#define CKM_MD5_HMAC                   0x00000211
14533 +#define CKM_MD5_HMAC_GENERAL           0x00000212
14535 +#define CKM_SHA_1                      0x00000220
14537 +/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
14538 +#define CKM_SHA_1_HMAC                 0x00000221
14539 +#define CKM_SHA_1_HMAC_GENERAL         0x00000222
14541 +/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
14542 + * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
14543 + * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
14544 +#define CKM_RIPEMD128                  0x00000230
14545 +#define CKM_RIPEMD128_HMAC             0x00000231
14546 +#define CKM_RIPEMD128_HMAC_GENERAL     0x00000232
14547 +#define CKM_RIPEMD160                  0x00000240
14548 +#define CKM_RIPEMD160_HMAC             0x00000241
14549 +#define CKM_RIPEMD160_HMAC_GENERAL     0x00000242
14551 +/* CKM_SHA256/384/512 are new for v2.20 */
14552 +#define CKM_SHA256                     0x00000250
14553 +#define CKM_SHA256_HMAC                0x00000251
14554 +#define CKM_SHA256_HMAC_GENERAL        0x00000252
14556 +/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
14557 +#define CKM_SHA224                     0x00000255
14558 +#define CKM_SHA224_HMAC                0x00000256
14559 +#define CKM_SHA224_HMAC_GENERAL        0x00000257
14561 +#define CKM_SHA384                     0x00000260
14562 +#define CKM_SHA384_HMAC                0x00000261
14563 +#define CKM_SHA384_HMAC_GENERAL        0x00000262
14564 +#define CKM_SHA512                     0x00000270
14565 +#define CKM_SHA512_HMAC                0x00000271
14566 +#define CKM_SHA512_HMAC_GENERAL        0x00000272
14568 +/* SecurID is new for PKCS #11 v2.20 amendment 1 */
14569 +#define CKM_SECURID_KEY_GEN            0x00000280
14570 +#define CKM_SECURID                    0x00000282
14572 +/* HOTP is new for PKCS #11 v2.20 amendment 1 */
14573 +#define CKM_HOTP_KEY_GEN    0x00000290
14574 +#define CKM_HOTP            0x00000291
14576 +/* ACTI is new for PKCS #11 v2.20 amendment 1 */
14577 +#define CKM_ACTI            0x000002A0
14578 +#define CKM_ACTI_KEY_GEN    0x000002A1
14580 +/* All of the following mechanisms are new for v2.0 */
14581 +/* Note that CAST128 and CAST5 are the same algorithm */
14582 +#define CKM_CAST_KEY_GEN               0x00000300
14583 +#define CKM_CAST_ECB                   0x00000301
14584 +#define CKM_CAST_CBC                   0x00000302
14585 +#define CKM_CAST_MAC                   0x00000303
14586 +#define CKM_CAST_MAC_GENERAL           0x00000304
14587 +#define CKM_CAST_CBC_PAD               0x00000305
14588 +#define CKM_CAST3_KEY_GEN              0x00000310
14589 +#define CKM_CAST3_ECB                  0x00000311
14590 +#define CKM_CAST3_CBC                  0x00000312
14591 +#define CKM_CAST3_MAC                  0x00000313
14592 +#define CKM_CAST3_MAC_GENERAL          0x00000314
14593 +#define CKM_CAST3_CBC_PAD              0x00000315
14594 +#define CKM_CAST5_KEY_GEN              0x00000320
14595 +#define CKM_CAST128_KEY_GEN            0x00000320
14596 +#define CKM_CAST5_ECB                  0x00000321
14597 +#define CKM_CAST128_ECB                0x00000321
14598 +#define CKM_CAST5_CBC                  0x00000322
14599 +#define CKM_CAST128_CBC                0x00000322
14600 +#define CKM_CAST5_MAC                  0x00000323
14601 +#define CKM_CAST128_MAC                0x00000323
14602 +#define CKM_CAST5_MAC_GENERAL          0x00000324
14603 +#define CKM_CAST128_MAC_GENERAL        0x00000324
14604 +#define CKM_CAST5_CBC_PAD              0x00000325
14605 +#define CKM_CAST128_CBC_PAD            0x00000325
14606 +#define CKM_RC5_KEY_GEN                0x00000330
14607 +#define CKM_RC5_ECB                    0x00000331
14608 +#define CKM_RC5_CBC                    0x00000332
14609 +#define CKM_RC5_MAC                    0x00000333
14610 +#define CKM_RC5_MAC_GENERAL            0x00000334
14611 +#define CKM_RC5_CBC_PAD                0x00000335
14612 +#define CKM_IDEA_KEY_GEN               0x00000340
14613 +#define CKM_IDEA_ECB                   0x00000341
14614 +#define CKM_IDEA_CBC                   0x00000342
14615 +#define CKM_IDEA_MAC                   0x00000343
14616 +#define CKM_IDEA_MAC_GENERAL           0x00000344
14617 +#define CKM_IDEA_CBC_PAD               0x00000345
14618 +#define CKM_GENERIC_SECRET_KEY_GEN     0x00000350
14619 +#define CKM_CONCATENATE_BASE_AND_KEY   0x00000360
14620 +#define CKM_CONCATENATE_BASE_AND_DATA  0x00000362
14621 +#define CKM_CONCATENATE_DATA_AND_BASE  0x00000363
14622 +#define CKM_XOR_BASE_AND_DATA          0x00000364
14623 +#define CKM_EXTRACT_KEY_FROM_KEY       0x00000365
14624 +#define CKM_SSL3_PRE_MASTER_KEY_GEN    0x00000370
14625 +#define CKM_SSL3_MASTER_KEY_DERIVE     0x00000371
14626 +#define CKM_SSL3_KEY_AND_MAC_DERIVE    0x00000372
14628 +/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
14629 + * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
14630 + * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
14631 +#define CKM_SSL3_MASTER_KEY_DERIVE_DH  0x00000373
14632 +#define CKM_TLS_PRE_MASTER_KEY_GEN     0x00000374
14633 +#define CKM_TLS_MASTER_KEY_DERIVE      0x00000375
14634 +#define CKM_TLS_KEY_AND_MAC_DERIVE     0x00000376
14635 +#define CKM_TLS_MASTER_KEY_DERIVE_DH   0x00000377
14637 +/* CKM_TLS_PRF is new for v2.20 */
14638 +#define CKM_TLS_PRF                    0x00000378
14640 +#define CKM_SSL3_MD5_MAC               0x00000380
14641 +#define CKM_SSL3_SHA1_MAC              0x00000381
14642 +#define CKM_MD5_KEY_DERIVATION         0x00000390
14643 +#define CKM_MD2_KEY_DERIVATION         0x00000391
14644 +#define CKM_SHA1_KEY_DERIVATION        0x00000392
14646 +/* CKM_SHA256/384/512 are new for v2.20 */
14647 +#define CKM_SHA256_KEY_DERIVATION      0x00000393
14648 +#define CKM_SHA384_KEY_DERIVATION      0x00000394
14649 +#define CKM_SHA512_KEY_DERIVATION      0x00000395
14651 +/* SHA-224 key derivation is new for PKCS #11 v2.20 amendment 3 */
14652 +#define CKM_SHA224_KEY_DERIVATION      0x00000396
14654 +#define CKM_PBE_MD2_DES_CBC            0x000003A0
14655 +#define CKM_PBE_MD5_DES_CBC            0x000003A1
14656 +#define CKM_PBE_MD5_CAST_CBC           0x000003A2
14657 +#define CKM_PBE_MD5_CAST3_CBC          0x000003A3
14658 +#define CKM_PBE_MD5_CAST5_CBC          0x000003A4
14659 +#define CKM_PBE_MD5_CAST128_CBC        0x000003A4
14660 +#define CKM_PBE_SHA1_CAST5_CBC         0x000003A5
14661 +#define CKM_PBE_SHA1_CAST128_CBC       0x000003A5
14662 +#define CKM_PBE_SHA1_RC4_128           0x000003A6
14663 +#define CKM_PBE_SHA1_RC4_40            0x000003A7
14664 +#define CKM_PBE_SHA1_DES3_EDE_CBC      0x000003A8
14665 +#define CKM_PBE_SHA1_DES2_EDE_CBC      0x000003A9
14666 +#define CKM_PBE_SHA1_RC2_128_CBC       0x000003AA
14667 +#define CKM_PBE_SHA1_RC2_40_CBC        0x000003AB
14669 +/* CKM_PKCS5_PBKD2 is new for v2.10 */
14670 +#define CKM_PKCS5_PBKD2                0x000003B0
14672 +#define CKM_PBA_SHA1_WITH_SHA1_HMAC    0x000003C0
14674 +/* WTLS mechanisms are new for v2.20 */
14675 +#define CKM_WTLS_PRE_MASTER_KEY_GEN         0x000003D0
14676 +#define CKM_WTLS_MASTER_KEY_DERIVE          0x000003D1
14677 +#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC   0x000003D2
14678 +#define CKM_WTLS_PRF                        0x000003D3
14679 +#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE  0x000003D4
14680 +#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE  0x000003D5
14682 +#define CKM_KEY_WRAP_LYNKS             0x00000400
14683 +#define CKM_KEY_WRAP_SET_OAEP          0x00000401
14685 +/* CKM_CMS_SIG is new for v2.20 */
14686 +#define CKM_CMS_SIG                    0x00000500
14688 +/* CKM_KIP mechanisms are new for PKCS #11 v2.20 amendment 2 */
14689 +#define CKM_KIP_DERIVE                 0x00000510
14690 +#define CKM_KIP_WRAP                   0x00000511
14691 +#define CKM_KIP_MAC                    0x00000512
14693 +/* Camellia is new for PKCS #11 v2.20 amendment 3 */
14694 +#define CKM_CAMELLIA_KEY_GEN           0x00000550
14695 +#define CKM_CAMELLIA_ECB               0x00000551
14696 +#define CKM_CAMELLIA_CBC               0x00000552
14697 +#define CKM_CAMELLIA_MAC               0x00000553
14698 +#define CKM_CAMELLIA_MAC_GENERAL       0x00000554
14699 +#define CKM_CAMELLIA_CBC_PAD           0x00000555
14700 +#define CKM_CAMELLIA_ECB_ENCRYPT_DATA  0x00000556
14701 +#define CKM_CAMELLIA_CBC_ENCRYPT_DATA  0x00000557
14702 +#define CKM_CAMELLIA_CTR               0x00000558
14704 +/* ARIA is new for PKCS #11 v2.20 amendment 3 */
14705 +#define CKM_ARIA_KEY_GEN               0x00000560
14706 +#define CKM_ARIA_ECB                   0x00000561
14707 +#define CKM_ARIA_CBC                   0x00000562
14708 +#define CKM_ARIA_MAC                   0x00000563
14709 +#define CKM_ARIA_MAC_GENERAL           0x00000564
14710 +#define CKM_ARIA_CBC_PAD               0x00000565
14711 +#define CKM_ARIA_ECB_ENCRYPT_DATA      0x00000566
14712 +#define CKM_ARIA_CBC_ENCRYPT_DATA      0x00000567
14714 +/* Fortezza mechanisms */
14715 +#define CKM_SKIPJACK_KEY_GEN           0x00001000
14716 +#define CKM_SKIPJACK_ECB64             0x00001001
14717 +#define CKM_SKIPJACK_CBC64             0x00001002
14718 +#define CKM_SKIPJACK_OFB64             0x00001003
14719 +#define CKM_SKIPJACK_CFB64             0x00001004
14720 +#define CKM_SKIPJACK_CFB32             0x00001005
14721 +#define CKM_SKIPJACK_CFB16             0x00001006
14722 +#define CKM_SKIPJACK_CFB8              0x00001007
14723 +#define CKM_SKIPJACK_WRAP              0x00001008
14724 +#define CKM_SKIPJACK_PRIVATE_WRAP      0x00001009
14725 +#define CKM_SKIPJACK_RELAYX            0x0000100a
14726 +#define CKM_KEA_KEY_PAIR_GEN           0x00001010
14727 +#define CKM_KEA_KEY_DERIVE             0x00001011
14728 +#define CKM_FORTEZZA_TIMESTAMP         0x00001020
14729 +#define CKM_BATON_KEY_GEN              0x00001030
14730 +#define CKM_BATON_ECB128               0x00001031
14731 +#define CKM_BATON_ECB96                0x00001032
14732 +#define CKM_BATON_CBC128               0x00001033
14733 +#define CKM_BATON_COUNTER              0x00001034
14734 +#define CKM_BATON_SHUFFLE              0x00001035
14735 +#define CKM_BATON_WRAP                 0x00001036
14737 +/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
14738 + * CKM_EC_KEY_PAIR_GEN is preferred */
14739 +#define CKM_ECDSA_KEY_PAIR_GEN         0x00001040
14740 +#define CKM_EC_KEY_PAIR_GEN            0x00001040
14742 +#define CKM_ECDSA                      0x00001041
14743 +#define CKM_ECDSA_SHA1                 0x00001042
14745 +/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
14746 + * are new for v2.11 */
14747 +#define CKM_ECDH1_DERIVE               0x00001050
14748 +#define CKM_ECDH1_COFACTOR_DERIVE      0x00001051
14749 +#define CKM_ECMQV_DERIVE               0x00001052
14751 +#define CKM_JUNIPER_KEY_GEN            0x00001060
14752 +#define CKM_JUNIPER_ECB128             0x00001061
14753 +#define CKM_JUNIPER_CBC128             0x00001062
14754 +#define CKM_JUNIPER_COUNTER            0x00001063
14755 +#define CKM_JUNIPER_SHUFFLE            0x00001064
14756 +#define CKM_JUNIPER_WRAP               0x00001065
14757 +#define CKM_FASTHASH                   0x00001070
14759 +/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
14760 + * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
14761 + * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
14762 + * new for v2.11 */
14763 +#define CKM_AES_KEY_GEN                0x00001080
14764 +#define CKM_AES_ECB                    0x00001081
14765 +#define CKM_AES_CBC                    0x00001082
14766 +#define CKM_AES_MAC                    0x00001083
14767 +#define CKM_AES_MAC_GENERAL            0x00001084
14768 +#define CKM_AES_CBC_PAD                0x00001085
14770 +/* AES counter mode is new for PKCS #11 v2.20 amendment 3 */
14771 +#define CKM_AES_CTR                    0x00001086
14773 +/* BlowFish and TwoFish are new for v2.20 */
14774 +#define CKM_BLOWFISH_KEY_GEN           0x00001090
14775 +#define CKM_BLOWFISH_CBC               0x00001091
14776 +#define CKM_TWOFISH_KEY_GEN            0x00001092
14777 +#define CKM_TWOFISH_CBC                0x00001093
14780 +/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */
14781 +#define CKM_DES_ECB_ENCRYPT_DATA       0x00001100
14782 +#define CKM_DES_CBC_ENCRYPT_DATA       0x00001101
14783 +#define CKM_DES3_ECB_ENCRYPT_DATA      0x00001102
14784 +#define CKM_DES3_CBC_ENCRYPT_DATA      0x00001103
14785 +#define CKM_AES_ECB_ENCRYPT_DATA       0x00001104
14786 +#define CKM_AES_CBC_ENCRYPT_DATA       0x00001105
14788 +#define CKM_DSA_PARAMETER_GEN          0x00002000
14789 +#define CKM_DH_PKCS_PARAMETER_GEN      0x00002001
14790 +#define CKM_X9_42_DH_PARAMETER_GEN     0x00002002
14792 +#define CKM_VENDOR_DEFINED             0x80000000
14794 +typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
14797 +/* CK_MECHANISM is a structure that specifies a particular
14798 + * mechanism  */
14799 +typedef struct CK_MECHANISM {
14800 +  CK_MECHANISM_TYPE mechanism;
14801 +  CK_VOID_PTR       pParameter;
14803 +  /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
14804 +   * v2.0 */
14805 +  CK_ULONG          ulParameterLen;  /* in bytes */
14806 +} CK_MECHANISM;
14808 +typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
14811 +/* CK_MECHANISM_INFO provides information about a particular
14812 + * mechanism */
14813 +typedef struct CK_MECHANISM_INFO {
14814 +    CK_ULONG    ulMinKeySize;
14815 +    CK_ULONG    ulMaxKeySize;
14816 +    CK_FLAGS    flags;
14817 +} CK_MECHANISM_INFO;
14819 +/* The flags are defined as follows:
14820 + *      Bit Flag               Mask        Meaning */
14821 +#define CKF_HW                 0x00000001  /* performed by HW */
14823 +/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
14824 + * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
14825 + * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
14826 + * and CKF_DERIVE are new for v2.0.  They specify whether or not
14827 + * a mechanism can be used for a particular task */
14828 +#define CKF_ENCRYPT            0x00000100
14829 +#define CKF_DECRYPT            0x00000200
14830 +#define CKF_DIGEST             0x00000400
14831 +#define CKF_SIGN               0x00000800
14832 +#define CKF_SIGN_RECOVER       0x00001000
14833 +#define CKF_VERIFY             0x00002000
14834 +#define CKF_VERIFY_RECOVER     0x00004000
14835 +#define CKF_GENERATE           0x00008000
14836 +#define CKF_GENERATE_KEY_PAIR  0x00010000
14837 +#define CKF_WRAP               0x00020000
14838 +#define CKF_UNWRAP             0x00040000
14839 +#define CKF_DERIVE             0x00080000
14841 +/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
14842 + * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
14843 + * describe a token's EC capabilities not available in mechanism
14844 + * information. */
14845 +#define CKF_EC_F_P             0x00100000
14846 +#define CKF_EC_F_2M            0x00200000
14847 +#define CKF_EC_ECPARAMETERS    0x00400000
14848 +#define CKF_EC_NAMEDCURVE      0x00800000
14849 +#define CKF_EC_UNCOMPRESS      0x01000000
14850 +#define CKF_EC_COMPRESS        0x02000000
14852 +#define CKF_EXTENSION          0x80000000 /* FALSE for this version */
14854 +typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
14857 +/* CK_RV is a value that identifies the return value of a
14858 + * Cryptoki function */
14859 +/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
14860 +typedef CK_ULONG          CK_RV;
14862 +#define CKR_OK                                0x00000000
14863 +#define CKR_CANCEL                            0x00000001
14864 +#define CKR_HOST_MEMORY                       0x00000002
14865 +#define CKR_SLOT_ID_INVALID                   0x00000003
14867 +/* CKR_FLAGS_INVALID was removed for v2.0 */
14869 +/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
14870 +#define CKR_GENERAL_ERROR                     0x00000005
14871 +#define CKR_FUNCTION_FAILED                   0x00000006
14873 +/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
14874 + * and CKR_CANT_LOCK are new for v2.01 */
14875 +#define CKR_ARGUMENTS_BAD                     0x00000007
14876 +#define CKR_NO_EVENT                          0x00000008
14877 +#define CKR_NEED_TO_CREATE_THREADS            0x00000009
14878 +#define CKR_CANT_LOCK                         0x0000000A
14880 +#define CKR_ATTRIBUTE_READ_ONLY               0x00000010
14881 +#define CKR_ATTRIBUTE_SENSITIVE               0x00000011
14882 +#define CKR_ATTRIBUTE_TYPE_INVALID            0x00000012
14883 +#define CKR_ATTRIBUTE_VALUE_INVALID           0x00000013
14884 +#define CKR_DATA_INVALID                      0x00000020
14885 +#define CKR_DATA_LEN_RANGE                    0x00000021
14886 +#define CKR_DEVICE_ERROR                      0x00000030
14887 +#define CKR_DEVICE_MEMORY                     0x00000031
14888 +#define CKR_DEVICE_REMOVED                    0x00000032
14889 +#define CKR_ENCRYPTED_DATA_INVALID            0x00000040
14890 +#define CKR_ENCRYPTED_DATA_LEN_RANGE          0x00000041
14891 +#define CKR_FUNCTION_CANCELED                 0x00000050
14892 +#define CKR_FUNCTION_NOT_PARALLEL             0x00000051
14894 +/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
14895 +#define CKR_FUNCTION_NOT_SUPPORTED            0x00000054
14897 +#define CKR_KEY_HANDLE_INVALID                0x00000060
14899 +/* CKR_KEY_SENSITIVE was removed for v2.0 */
14901 +#define CKR_KEY_SIZE_RANGE                    0x00000062
14902 +#define CKR_KEY_TYPE_INCONSISTENT             0x00000063
14904 +/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
14905 + * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
14906 + * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
14907 + * v2.0 */
14908 +#define CKR_KEY_NOT_NEEDED                    0x00000064
14909 +#define CKR_KEY_CHANGED                       0x00000065
14910 +#define CKR_KEY_NEEDED                        0x00000066
14911 +#define CKR_KEY_INDIGESTIBLE                  0x00000067
14912 +#define CKR_KEY_FUNCTION_NOT_PERMITTED        0x00000068
14913 +#define CKR_KEY_NOT_WRAPPABLE                 0x00000069
14914 +#define CKR_KEY_UNEXTRACTABLE                 0x0000006A
14916 +#define CKR_MECHANISM_INVALID                 0x00000070
14917 +#define CKR_MECHANISM_PARAM_INVALID           0x00000071
14919 +/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
14920 + * were removed for v2.0 */
14921 +#define CKR_OBJECT_HANDLE_INVALID             0x00000082
14922 +#define CKR_OPERATION_ACTIVE                  0x00000090
14923 +#define CKR_OPERATION_NOT_INITIALIZED         0x00000091
14924 +#define CKR_PIN_INCORRECT                     0x000000A0
14925 +#define CKR_PIN_INVALID                       0x000000A1
14926 +#define CKR_PIN_LEN_RANGE                     0x000000A2
14928 +/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
14929 +#define CKR_PIN_EXPIRED                       0x000000A3
14930 +#define CKR_PIN_LOCKED                        0x000000A4
14932 +#define CKR_SESSION_CLOSED                    0x000000B0
14933 +#define CKR_SESSION_COUNT                     0x000000B1
14934 +#define CKR_SESSION_HANDLE_INVALID            0x000000B3
14935 +#define CKR_SESSION_PARALLEL_NOT_SUPPORTED    0x000000B4
14936 +#define CKR_SESSION_READ_ONLY                 0x000000B5
14937 +#define CKR_SESSION_EXISTS                    0x000000B6
14939 +/* CKR_SESSION_READ_ONLY_EXISTS and
14940 + * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
14941 +#define CKR_SESSION_READ_ONLY_EXISTS          0x000000B7
14942 +#define CKR_SESSION_READ_WRITE_SO_EXISTS      0x000000B8
14944 +#define CKR_SIGNATURE_INVALID                 0x000000C0
14945 +#define CKR_SIGNATURE_LEN_RANGE               0x000000C1
14946 +#define CKR_TEMPLATE_INCOMPLETE               0x000000D0
14947 +#define CKR_TEMPLATE_INCONSISTENT             0x000000D1
14948 +#define CKR_TOKEN_NOT_PRESENT                 0x000000E0
14949 +#define CKR_TOKEN_NOT_RECOGNIZED              0x000000E1
14950 +#define CKR_TOKEN_WRITE_PROTECTED             0x000000E2
14951 +#define CKR_UNWRAPPING_KEY_HANDLE_INVALID     0x000000F0
14952 +#define CKR_UNWRAPPING_KEY_SIZE_RANGE         0x000000F1
14953 +#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT  0x000000F2
14954 +#define CKR_USER_ALREADY_LOGGED_IN            0x00000100
14955 +#define CKR_USER_NOT_LOGGED_IN                0x00000101
14956 +#define CKR_USER_PIN_NOT_INITIALIZED          0x00000102
14957 +#define CKR_USER_TYPE_INVALID                 0x00000103
14959 +/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
14960 + * are new to v2.01 */
14961 +#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN    0x00000104
14962 +#define CKR_USER_TOO_MANY_TYPES               0x00000105
14964 +#define CKR_WRAPPED_KEY_INVALID               0x00000110
14965 +#define CKR_WRAPPED_KEY_LEN_RANGE             0x00000112
14966 +#define CKR_WRAPPING_KEY_HANDLE_INVALID       0x00000113
14967 +#define CKR_WRAPPING_KEY_SIZE_RANGE           0x00000114
14968 +#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT    0x00000115
14969 +#define CKR_RANDOM_SEED_NOT_SUPPORTED         0x00000120
14971 +/* These are new to v2.0 */
14972 +#define CKR_RANDOM_NO_RNG                     0x00000121
14974 +/* These are new to v2.11 */
14975 +#define CKR_DOMAIN_PARAMS_INVALID             0x00000130
14977 +/* These are new to v2.0 */
14978 +#define CKR_BUFFER_TOO_SMALL                  0x00000150
14979 +#define CKR_SAVED_STATE_INVALID               0x00000160
14980 +#define CKR_INFORMATION_SENSITIVE             0x00000170
14981 +#define CKR_STATE_UNSAVEABLE                  0x00000180
14983 +/* These are new to v2.01 */
14984 +#define CKR_CRYPTOKI_NOT_INITIALIZED          0x00000190
14985 +#define CKR_CRYPTOKI_ALREADY_INITIALIZED      0x00000191
14986 +#define CKR_MUTEX_BAD                         0x000001A0
14987 +#define CKR_MUTEX_NOT_LOCKED                  0x000001A1
14989 +/* The following return values are new for PKCS #11 v2.20 amendment 3 */
14990 +#define CKR_NEW_PIN_MODE                      0x000001B0
14991 +#define CKR_NEXT_OTP                          0x000001B1
14993 +/* This is new to v2.20 */
14994 +#define CKR_FUNCTION_REJECTED                 0x00000200
14996 +#define CKR_VENDOR_DEFINED                    0x80000000
14999 +/* CK_NOTIFY is an application callback that processes events */
15000 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
15001 +  CK_SESSION_HANDLE hSession,     /* the session's handle */
15002 +  CK_NOTIFICATION   event,
15003 +  CK_VOID_PTR       pApplication  /* passed to C_OpenSession */
15007 +/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
15008 + * version and pointers of appropriate types to all the
15009 + * Cryptoki functions */
15010 +/* CK_FUNCTION_LIST is new for v2.0 */
15011 +typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
15013 +typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
15015 +typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
15018 +/* CK_CREATEMUTEX is an application callback for creating a
15019 + * mutex object */
15020 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
15021 +  CK_VOID_PTR_PTR ppMutex  /* location to receive ptr to mutex */
15025 +/* CK_DESTROYMUTEX is an application callback for destroying a
15026 + * mutex object */
15027 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
15028 +  CK_VOID_PTR pMutex  /* pointer to mutex */
15032 +/* CK_LOCKMUTEX is an application callback for locking a mutex */
15033 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
15034 +  CK_VOID_PTR pMutex  /* pointer to mutex */
15038 +/* CK_UNLOCKMUTEX is an application callback for unlocking a
15039 + * mutex */
15040 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
15041 +  CK_VOID_PTR pMutex  /* pointer to mutex */
15045 +/* CK_C_INITIALIZE_ARGS provides the optional arguments to
15046 + * C_Initialize */
15047 +typedef struct CK_C_INITIALIZE_ARGS {
15048 +  CK_CREATEMUTEX CreateMutex;
15049 +  CK_DESTROYMUTEX DestroyMutex;
15050 +  CK_LOCKMUTEX LockMutex;
15051 +  CK_UNLOCKMUTEX UnlockMutex;
15052 +  CK_FLAGS flags;
15053 +  CK_VOID_PTR pReserved;
15054 +} CK_C_INITIALIZE_ARGS;
15056 +/* flags: bit flags that provide capabilities of the slot
15057 + *      Bit Flag                           Mask       Meaning
15058 + */
15059 +#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
15060 +#define CKF_OS_LOCKING_OK                  0x00000002
15062 +typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
15065 +/* additional flags for parameters to functions */
15067 +/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
15068 +#define CKF_DONT_BLOCK     1
15070 +/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
15071 + * CK_RSA_PKCS_OAEP_MGF_TYPE  is used to indicate the Message
15072 + * Generation Function (MGF) applied to a message block when
15073 + * formatting a message block for the PKCS #1 OAEP encryption
15074 + * scheme. */
15075 +typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
15077 +typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
15079 +/* The following MGFs are defined */
15080 +/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512
15081 + * are new for v2.20 */
15082 +#define CKG_MGF1_SHA1         0x00000001
15083 +#define CKG_MGF1_SHA256       0x00000002
15084 +#define CKG_MGF1_SHA384       0x00000003
15085 +#define CKG_MGF1_SHA512       0x00000004
15086 +/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
15087 +#define CKG_MGF1_SHA224       0x00000005
15089 +/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
15090 + * CK_RSA_PKCS_OAEP_SOURCE_TYPE  is used to indicate the source
15091 + * of the encoding parameter when formatting a message block
15092 + * for the PKCS #1 OAEP encryption scheme. */
15093 +typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
15095 +typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
15097 +/* The following encoding parameter sources are defined */
15098 +#define CKZ_DATA_SPECIFIED    0x00000001
15100 +/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
15101 + * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
15102 + * CKM_RSA_PKCS_OAEP mechanism. */
15103 +typedef struct CK_RSA_PKCS_OAEP_PARAMS {
15104 +        CK_MECHANISM_TYPE hashAlg;
15105 +        CK_RSA_PKCS_MGF_TYPE mgf;
15106 +        CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
15107 +        CK_VOID_PTR pSourceData;
15108 +        CK_ULONG ulSourceDataLen;
15109 +} CK_RSA_PKCS_OAEP_PARAMS;
15111 +typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
15113 +/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11.
15114 + * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
15115 + * CKM_RSA_PKCS_PSS mechanism(s). */
15116 +typedef struct CK_RSA_PKCS_PSS_PARAMS {
15117 +        CK_MECHANISM_TYPE    hashAlg;
15118 +        CK_RSA_PKCS_MGF_TYPE mgf;
15119 +        CK_ULONG             sLen;
15120 +} CK_RSA_PKCS_PSS_PARAMS;
15122 +typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
15124 +/* CK_EC_KDF_TYPE is new for v2.11. */
15125 +typedef CK_ULONG CK_EC_KDF_TYPE;
15127 +/* The following EC Key Derivation Functions are defined */
15128 +#define CKD_NULL                 0x00000001
15129 +#define CKD_SHA1_KDF             0x00000002
15131 +/* CK_ECDH1_DERIVE_PARAMS is new for v2.11.
15132 + * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
15133 + * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
15134 + * where each party contributes one key pair.
15135 + */
15136 +typedef struct CK_ECDH1_DERIVE_PARAMS {
15137 +  CK_EC_KDF_TYPE kdf;
15138 +  CK_ULONG ulSharedDataLen;
15139 +  CK_BYTE_PTR pSharedData;
15140 +  CK_ULONG ulPublicDataLen;
15141 +  CK_BYTE_PTR pPublicData;
15142 +} CK_ECDH1_DERIVE_PARAMS;
15144 +typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
15147 +/* CK_ECDH2_DERIVE_PARAMS is new for v2.11.
15148 + * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
15149 + * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */
15150 +typedef struct CK_ECDH2_DERIVE_PARAMS {
15151 +  CK_EC_KDF_TYPE kdf;
15152 +  CK_ULONG ulSharedDataLen;
15153 +  CK_BYTE_PTR pSharedData;
15154 +  CK_ULONG ulPublicDataLen;
15155 +  CK_BYTE_PTR pPublicData;
15156 +  CK_ULONG ulPrivateDataLen;
15157 +  CK_OBJECT_HANDLE hPrivateData;
15158 +  CK_ULONG ulPublicDataLen2;
15159 +  CK_BYTE_PTR pPublicData2;
15160 +} CK_ECDH2_DERIVE_PARAMS;
15162 +typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
15164 +typedef struct CK_ECMQV_DERIVE_PARAMS {
15165 +  CK_EC_KDF_TYPE kdf;
15166 +  CK_ULONG ulSharedDataLen;
15167 +  CK_BYTE_PTR pSharedData;
15168 +  CK_ULONG ulPublicDataLen;
15169 +  CK_BYTE_PTR pPublicData;
15170 +  CK_ULONG ulPrivateDataLen;
15171 +  CK_OBJECT_HANDLE hPrivateData;
15172 +  CK_ULONG ulPublicDataLen2;
15173 +  CK_BYTE_PTR pPublicData2;
15174 +  CK_OBJECT_HANDLE publicKey;
15175 +} CK_ECMQV_DERIVE_PARAMS;
15177 +typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
15179 +/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
15180 + * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */
15181 +typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
15182 +typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
15184 +/* The following X9.42 DH key derivation functions are defined
15185 +   (besides CKD_NULL already defined : */
15186 +#define CKD_SHA1_KDF_ASN1        0x00000003
15187 +#define CKD_SHA1_KDF_CONCATENATE 0x00000004
15189 +/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11.
15190 + * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
15191 + * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
15192 + * contributes one key pair */
15193 +typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
15194 +  CK_X9_42_DH_KDF_TYPE kdf;
15195 +  CK_ULONG ulOtherInfoLen;
15196 +  CK_BYTE_PTR pOtherInfo;
15197 +  CK_ULONG ulPublicDataLen;
15198 +  CK_BYTE_PTR pPublicData;
15199 +} CK_X9_42_DH1_DERIVE_PARAMS;
15201 +typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
15203 +/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11.
15204 + * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
15205 + * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
15206 + * mechanisms, where each party contributes two key pairs */
15207 +typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
15208 +  CK_X9_42_DH_KDF_TYPE kdf;
15209 +  CK_ULONG ulOtherInfoLen;
15210 +  CK_BYTE_PTR pOtherInfo;
15211 +  CK_ULONG ulPublicDataLen;
15212 +  CK_BYTE_PTR pPublicData;
15213 +  CK_ULONG ulPrivateDataLen;
15214 +  CK_OBJECT_HANDLE hPrivateData;
15215 +  CK_ULONG ulPublicDataLen2;
15216 +  CK_BYTE_PTR pPublicData2;
15217 +} CK_X9_42_DH2_DERIVE_PARAMS;
15219 +typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
15221 +typedef struct CK_X9_42_MQV_DERIVE_PARAMS {
15222 +  CK_X9_42_DH_KDF_TYPE kdf;
15223 +  CK_ULONG ulOtherInfoLen;
15224 +  CK_BYTE_PTR pOtherInfo;
15225 +  CK_ULONG ulPublicDataLen;
15226 +  CK_BYTE_PTR pPublicData;
15227 +  CK_ULONG ulPrivateDataLen;
15228 +  CK_OBJECT_HANDLE hPrivateData;
15229 +  CK_ULONG ulPublicDataLen2;
15230 +  CK_BYTE_PTR pPublicData2;
15231 +  CK_OBJECT_HANDLE publicKey;
15232 +} CK_X9_42_MQV_DERIVE_PARAMS;
15234 +typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
15236 +/* CK_KEA_DERIVE_PARAMS provides the parameters to the
15237 + * CKM_KEA_DERIVE mechanism */
15238 +/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
15239 +typedef struct CK_KEA_DERIVE_PARAMS {
15240 +  CK_BBOOL      isSender;
15241 +  CK_ULONG      ulRandomLen;
15242 +  CK_BYTE_PTR   pRandomA;
15243 +  CK_BYTE_PTR   pRandomB;
15244 +  CK_ULONG      ulPublicDataLen;
15245 +  CK_BYTE_PTR   pPublicData;
15246 +} CK_KEA_DERIVE_PARAMS;
15248 +typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
15251 +/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
15252 + * CKM_RC2_MAC mechanisms.  An instance of CK_RC2_PARAMS just
15253 + * holds the effective keysize */
15254 +typedef CK_ULONG          CK_RC2_PARAMS;
15256 +typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
15259 +/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
15260 + * mechanism */
15261 +typedef struct CK_RC2_CBC_PARAMS {
15262 +  /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
15263 +   * v2.0 */
15264 +  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
15266 +  CK_BYTE       iv[8];            /* IV for CBC mode */
15267 +} CK_RC2_CBC_PARAMS;
15269 +typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
15272 +/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
15273 + * CKM_RC2_MAC_GENERAL mechanism */
15274 +/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
15275 +typedef struct CK_RC2_MAC_GENERAL_PARAMS {
15276 +  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
15277 +  CK_ULONG      ulMacLength;      /* Length of MAC in bytes */
15278 +} CK_RC2_MAC_GENERAL_PARAMS;
15280 +typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
15281 +  CK_RC2_MAC_GENERAL_PARAMS_PTR;
15284 +/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
15285 + * CKM_RC5_MAC mechanisms */
15286 +/* CK_RC5_PARAMS is new for v2.0 */
15287 +typedef struct CK_RC5_PARAMS {
15288 +  CK_ULONG      ulWordsize;  /* wordsize in bits */
15289 +  CK_ULONG      ulRounds;    /* number of rounds */
15290 +} CK_RC5_PARAMS;
15292 +typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
15295 +/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
15296 + * mechanism */
15297 +/* CK_RC5_CBC_PARAMS is new for v2.0 */
15298 +typedef struct CK_RC5_CBC_PARAMS {
15299 +  CK_ULONG      ulWordsize;  /* wordsize in bits */
15300 +  CK_ULONG      ulRounds;    /* number of rounds */
15301 +  CK_BYTE_PTR   pIv;         /* pointer to IV */
15302 +  CK_ULONG      ulIvLen;     /* length of IV in bytes */
15303 +} CK_RC5_CBC_PARAMS;
15305 +typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
15308 +/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
15309 + * CKM_RC5_MAC_GENERAL mechanism */
15310 +/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
15311 +typedef struct CK_RC5_MAC_GENERAL_PARAMS {
15312 +  CK_ULONG      ulWordsize;   /* wordsize in bits */
15313 +  CK_ULONG      ulRounds;     /* number of rounds */
15314 +  CK_ULONG      ulMacLength;  /* Length of MAC in bytes */
15315 +} CK_RC5_MAC_GENERAL_PARAMS;
15317 +typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
15318 +  CK_RC5_MAC_GENERAL_PARAMS_PTR;
15321 +/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
15322 + * ciphers' MAC_GENERAL mechanisms.  Its value is the length of
15323 + * the MAC */
15324 +/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
15325 +typedef CK_ULONG          CK_MAC_GENERAL_PARAMS;
15327 +typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
15329 +/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
15330 +typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
15331 +  CK_BYTE      iv[8];
15332 +  CK_BYTE_PTR  pData;
15333 +  CK_ULONG     length;
15334 +} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
15336 +typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
15338 +typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
15339 +  CK_BYTE      iv[16];
15340 +  CK_BYTE_PTR  pData;
15341 +  CK_ULONG     length;
15342 +} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
15344 +typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
15346 +/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
15347 + * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
15348 +/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
15349 +typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
15350 +  CK_ULONG      ulPasswordLen;
15351 +  CK_BYTE_PTR   pPassword;
15352 +  CK_ULONG      ulPublicDataLen;
15353 +  CK_BYTE_PTR   pPublicData;
15354 +  CK_ULONG      ulPAndGLen;
15355 +  CK_ULONG      ulQLen;
15356 +  CK_ULONG      ulRandomLen;
15357 +  CK_BYTE_PTR   pRandomA;
15358 +  CK_BYTE_PTR   pPrimeP;
15359 +  CK_BYTE_PTR   pBaseG;
15360 +  CK_BYTE_PTR   pSubprimeQ;
15361 +} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
15363 +typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
15364 +  CK_SKIPJACK_PRIVATE_WRAP_PTR;
15367 +/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
15368 + * CKM_SKIPJACK_RELAYX mechanism */
15369 +/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
15370 +typedef struct CK_SKIPJACK_RELAYX_PARAMS {
15371 +  CK_ULONG      ulOldWrappedXLen;
15372 +  CK_BYTE_PTR   pOldWrappedX;
15373 +  CK_ULONG      ulOldPasswordLen;
15374 +  CK_BYTE_PTR   pOldPassword;
15375 +  CK_ULONG      ulOldPublicDataLen;
15376 +  CK_BYTE_PTR   pOldPublicData;
15377 +  CK_ULONG      ulOldRandomLen;
15378 +  CK_BYTE_PTR   pOldRandomA;
15379 +  CK_ULONG      ulNewPasswordLen;
15380 +  CK_BYTE_PTR   pNewPassword;
15381 +  CK_ULONG      ulNewPublicDataLen;
15382 +  CK_BYTE_PTR   pNewPublicData;
15383 +  CK_ULONG      ulNewRandomLen;
15384 +  CK_BYTE_PTR   pNewRandomA;
15385 +} CK_SKIPJACK_RELAYX_PARAMS;
15387 +typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
15388 +  CK_SKIPJACK_RELAYX_PARAMS_PTR;
15391 +typedef struct CK_PBE_PARAMS {
15392 +  CK_BYTE_PTR      pInitVector;
15393 +  CK_UTF8CHAR_PTR  pPassword;
15394 +  CK_ULONG         ulPasswordLen;
15395 +  CK_BYTE_PTR      pSalt;
15396 +  CK_ULONG         ulSaltLen;
15397 +  CK_ULONG         ulIteration;
15398 +} CK_PBE_PARAMS;
15400 +typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
15403 +/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
15404 + * CKM_KEY_WRAP_SET_OAEP mechanism */
15405 +/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
15406 +typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
15407 +  CK_BYTE       bBC;     /* block contents byte */
15408 +  CK_BYTE_PTR   pX;      /* extra data */
15409 +  CK_ULONG      ulXLen;  /* length of extra data in bytes */
15410 +} CK_KEY_WRAP_SET_OAEP_PARAMS;
15412 +typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
15413 +  CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
15416 +typedef struct CK_SSL3_RANDOM_DATA {
15417 +  CK_BYTE_PTR  pClientRandom;
15418 +  CK_ULONG     ulClientRandomLen;
15419 +  CK_BYTE_PTR  pServerRandom;
15420 +  CK_ULONG     ulServerRandomLen;
15421 +} CK_SSL3_RANDOM_DATA;
15424 +typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
15425 +  CK_SSL3_RANDOM_DATA RandomInfo;
15426 +  CK_VERSION_PTR pVersion;
15427 +} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
15429 +typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
15430 +  CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
15433 +typedef struct CK_SSL3_KEY_MAT_OUT {
15434 +  CK_OBJECT_HANDLE hClientMacSecret;
15435 +  CK_OBJECT_HANDLE hServerMacSecret;
15436 +  CK_OBJECT_HANDLE hClientKey;
15437 +  CK_OBJECT_HANDLE hServerKey;
15438 +  CK_BYTE_PTR      pIVClient;
15439 +  CK_BYTE_PTR      pIVServer;
15440 +} CK_SSL3_KEY_MAT_OUT;
15442 +typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
15445 +typedef struct CK_SSL3_KEY_MAT_PARAMS {
15446 +  CK_ULONG                ulMacSizeInBits;
15447 +  CK_ULONG                ulKeySizeInBits;
15448 +  CK_ULONG                ulIVSizeInBits;
15449 +  CK_BBOOL                bIsExport;
15450 +  CK_SSL3_RANDOM_DATA     RandomInfo;
15451 +  CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
15452 +} CK_SSL3_KEY_MAT_PARAMS;
15454 +typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
15456 +/* CK_TLS_PRF_PARAMS is new for version 2.20 */
15457 +typedef struct CK_TLS_PRF_PARAMS {
15458 +  CK_BYTE_PTR  pSeed;
15459 +  CK_ULONG     ulSeedLen;
15460 +  CK_BYTE_PTR  pLabel;
15461 +  CK_ULONG     ulLabelLen;
15462 +  CK_BYTE_PTR  pOutput;
15463 +  CK_ULONG_PTR pulOutputLen;
15464 +} CK_TLS_PRF_PARAMS;
15466 +typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
15468 +/* WTLS is new for version 2.20 */
15469 +typedef struct CK_WTLS_RANDOM_DATA {
15470 +  CK_BYTE_PTR pClientRandom;
15471 +  CK_ULONG    ulClientRandomLen;
15472 +  CK_BYTE_PTR pServerRandom;
15473 +  CK_ULONG    ulServerRandomLen;
15474 +} CK_WTLS_RANDOM_DATA;
15476 +typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
15478 +typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
15479 +  CK_MECHANISM_TYPE   DigestMechanism;
15480 +  CK_WTLS_RANDOM_DATA RandomInfo;
15481 +  CK_BYTE_PTR         pVersion;
15482 +} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
15484 +typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
15485 +  CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
15487 +typedef struct CK_WTLS_PRF_PARAMS {
15488 +  CK_MECHANISM_TYPE DigestMechanism;
15489 +  CK_BYTE_PTR       pSeed;
15490 +  CK_ULONG          ulSeedLen;
15491 +  CK_BYTE_PTR       pLabel;
15492 +  CK_ULONG          ulLabelLen;
15493 +  CK_BYTE_PTR       pOutput;
15494 +  CK_ULONG_PTR      pulOutputLen;
15495 +} CK_WTLS_PRF_PARAMS;
15497 +typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
15499 +typedef struct CK_WTLS_KEY_MAT_OUT {
15500 +  CK_OBJECT_HANDLE hMacSecret;
15501 +  CK_OBJECT_HANDLE hKey;
15502 +  CK_BYTE_PTR      pIV;
15503 +} CK_WTLS_KEY_MAT_OUT;
15505 +typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
15507 +typedef struct CK_WTLS_KEY_MAT_PARAMS {
15508 +  CK_MECHANISM_TYPE       DigestMechanism;
15509 +  CK_ULONG                ulMacSizeInBits;
15510 +  CK_ULONG                ulKeySizeInBits;
15511 +  CK_ULONG                ulIVSizeInBits;
15512 +  CK_ULONG                ulSequenceNumber;
15513 +  CK_BBOOL                bIsExport;
15514 +  CK_WTLS_RANDOM_DATA     RandomInfo;
15515 +  CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
15516 +} CK_WTLS_KEY_MAT_PARAMS;
15518 +typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
15520 +/* CMS is new for version 2.20 */
15521 +typedef struct CK_CMS_SIG_PARAMS {
15522 +  CK_OBJECT_HANDLE      certificateHandle;
15523 +  CK_MECHANISM_PTR      pSigningMechanism;
15524 +  CK_MECHANISM_PTR      pDigestMechanism;
15525 +  CK_UTF8CHAR_PTR       pContentType;
15526 +  CK_BYTE_PTR           pRequestedAttributes;
15527 +  CK_ULONG              ulRequestedAttributesLen;
15528 +  CK_BYTE_PTR           pRequiredAttributes;
15529 +  CK_ULONG              ulRequiredAttributesLen;
15530 +} CK_CMS_SIG_PARAMS;
15532 +typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
15534 +typedef struct CK_KEY_DERIVATION_STRING_DATA {
15535 +  CK_BYTE_PTR pData;
15536 +  CK_ULONG    ulLen;
15537 +} CK_KEY_DERIVATION_STRING_DATA;
15539 +typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
15540 +  CK_KEY_DERIVATION_STRING_DATA_PTR;
15543 +/* The CK_EXTRACT_PARAMS is used for the
15544 + * CKM_EXTRACT_KEY_FROM_KEY mechanism.  It specifies which bit
15545 + * of the base key should be used as the first bit of the
15546 + * derived key */
15547 +/* CK_EXTRACT_PARAMS is new for v2.0 */
15548 +typedef CK_ULONG CK_EXTRACT_PARAMS;
15550 +typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
15552 +/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
15553 + * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
15554 + * indicate the Pseudo-Random Function (PRF) used to generate
15555 + * key bits using PKCS #5 PBKDF2. */
15556 +typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
15558 +typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
15560 +/* The following PRFs are defined in PKCS #5 v2.0. */
15561 +#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
15564 +/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
15565 + * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
15566 + * source of the salt value when deriving a key using PKCS #5
15567 + * PBKDF2. */
15568 +typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
15570 +typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
15572 +/* The following salt value sources are defined in PKCS #5 v2.0. */
15573 +#define CKZ_SALT_SPECIFIED        0x00000001
15575 +/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
15576 + * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
15577 + * parameters to the CKM_PKCS5_PBKD2 mechanism. */
15578 +typedef struct CK_PKCS5_PBKD2_PARAMS {
15579 +        CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE           saltSource;
15580 +        CK_VOID_PTR                                pSaltSourceData;
15581 +        CK_ULONG                                   ulSaltSourceDataLen;
15582 +        CK_ULONG                                   iterations;
15583 +        CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
15584 +        CK_VOID_PTR                                pPrfData;
15585 +        CK_ULONG                                   ulPrfDataLen;
15586 +        CK_UTF8CHAR_PTR                            pPassword;
15587 +        CK_ULONG_PTR                               ulPasswordLen;
15588 +} CK_PKCS5_PBKD2_PARAMS;
15590 +typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
15592 +/* All CK_OTP structs are new for PKCS #11 v2.20 amendment 3 */
15594 +typedef CK_ULONG CK_OTP_PARAM_TYPE;
15595 +typedef CK_OTP_PARAM_TYPE CK_PARAM_TYPE; /* B/w compatibility */
15597 +typedef struct CK_OTP_PARAM {
15598 +    CK_OTP_PARAM_TYPE type;
15599 +    CK_VOID_PTR pValue;
15600 +    CK_ULONG ulValueLen;
15601 +} CK_OTP_PARAM;
15603 +typedef CK_OTP_PARAM CK_PTR CK_OTP_PARAM_PTR;
15605 +typedef struct CK_OTP_PARAMS {
15606 +    CK_OTP_PARAM_PTR pParams;
15607 +    CK_ULONG ulCount;
15608 +} CK_OTP_PARAMS;
15610 +typedef CK_OTP_PARAMS CK_PTR CK_OTP_PARAMS_PTR;
15612 +typedef struct CK_OTP_SIGNATURE_INFO {
15613 +    CK_OTP_PARAM_PTR pParams;
15614 +    CK_ULONG ulCount;
15615 +} CK_OTP_SIGNATURE_INFO;
15617 +typedef CK_OTP_SIGNATURE_INFO CK_PTR CK_OTP_SIGNATURE_INFO_PTR;
15619 +/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */
15620 +#define CK_OTP_VALUE          0
15621 +#define CK_OTP_PIN            1
15622 +#define CK_OTP_CHALLENGE      2
15623 +#define CK_OTP_TIME           3
15624 +#define CK_OTP_COUNTER        4
15625 +#define CK_OTP_FLAGS          5
15626 +#define CK_OTP_OUTPUT_LENGTH  6
15627 +#define CK_OTP_OUTPUT_FORMAT  7
15629 +/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */
15630 +#define CKF_NEXT_OTP          0x00000001
15631 +#define CKF_EXCLUDE_TIME      0x00000002
15632 +#define CKF_EXCLUDE_COUNTER   0x00000004
15633 +#define CKF_EXCLUDE_CHALLENGE 0x00000008
15634 +#define CKF_EXCLUDE_PIN       0x00000010
15635 +#define CKF_USER_FRIENDLY_OTP 0x00000020
15637 +/* CK_KIP_PARAMS is new for PKCS #11 v2.20 amendment 2 */
15638 +typedef struct CK_KIP_PARAMS {
15639 +    CK_MECHANISM_PTR  pMechanism;
15640 +    CK_OBJECT_HANDLE  hKey;
15641 +    CK_BYTE_PTR       pSeed;
15642 +    CK_ULONG          ulSeedLen;
15643 +} CK_KIP_PARAMS;
15645 +typedef CK_KIP_PARAMS CK_PTR CK_KIP_PARAMS_PTR;
15647 +/* CK_AES_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
15648 +typedef struct CK_AES_CTR_PARAMS {
15649 +    CK_ULONG ulCounterBits;
15650 +    CK_BYTE cb[16];
15651 +} CK_AES_CTR_PARAMS;
15653 +typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR;
15655 +/* CK_CAMELLIA_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
15656 +typedef struct CK_CAMELLIA_CTR_PARAMS {
15657 +    CK_ULONG ulCounterBits;
15658 +    CK_BYTE cb[16];
15659 +} CK_CAMELLIA_CTR_PARAMS;
15661 +typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR;
15663 +/* CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
15664 +typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS {
15665 +    CK_BYTE      iv[16];
15666 +    CK_BYTE_PTR  pData;
15667 +    CK_ULONG     length;
15668 +} CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS;
15670 +typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
15672 +/* CK_ARIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
15673 +typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS {
15674 +    CK_BYTE      iv[16];
15675 +    CK_BYTE_PTR  pData;
15676 +    CK_ULONG     length;
15677 +} CK_ARIA_CBC_ENCRYPT_DATA_PARAMS;
15679 +typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
15681 +#endif
15682 Index: openssl/util/libeay.num
15683 diff -u openssl/util/libeay.num:1.8.2.1.4.1.2.1.4.1 openssl/util/libeay.num:1.12
15684 --- openssl/util/libeay.num:1.8.2.1.4.1.2.1.4.1 Mon Apr 14 12:42:50 2014
15685 +++ openssl/util/libeay.num     Mon Apr 14 12:44:22 2014
15686 @@ -4312,3 +4312,5 @@
15687  BIO_s_datagram_sctp                     4680   EXIST::FUNCTION:DGRAM,SCTP
15688  BIO_dgram_is_sctp                       4681   EXIST::FUNCTION:SCTP
15689  BIO_dgram_sctp_notification_cb          4682   EXIST::FUNCTION:SCTP
15690 +ENGINE_load_pk11ca                      4683   EXIST::FUNCTION:HW_PKCS11CA,ENGINE
15691 +ENGINE_load_pk11so                      4683   EXIST::FUNCTION:HW_PKCS11SO,ENGINE
15692 Index: openssl/util/mk1mf.pl
15693 diff -u openssl/util/mk1mf.pl:1.9.2.1.4.1.10.1 openssl/util/mk1mf.pl:1.11
15694 --- openssl/util/mk1mf.pl:1.9.2.1.4.1.10.1      Fri Jan  2 14:55:51 2015
15695 +++ openssl/util/mk1mf.pl       Fri Jan  2 14:56:55 2015
15696 @@ -114,6 +114,8 @@
15697         no-ecdh                                 - No ECDH
15698         no-engine                               - No engine
15699         no-hw                                   - No hw
15700 +       no-hw-pkcs11ca                          - No hw PKCS#11 CA flavor
15701 +       no-hw-pkcs11so                          - No hw PKCS#11 SO flavor
15702         nasm                                    - Use NASM for x86 asm
15703         nw-nasm                                 - Use NASM x86 asm for NetWare
15704         nw-mwasm                                - Use Metrowerks x86 asm for NetWare
15705 @@ -278,6 +280,8 @@
15706  $cflags.=" -DOPENSSL_NO_GOST" if $no_gost;
15707  $cflags.=" -DOPENSSL_NO_ENGINE"   if $no_engine;
15708  $cflags.=" -DOPENSSL_NO_HW"   if $no_hw;
15709 +$cflags.=" -DOPENSSL_NO_HW_PKCS11CA"   if $no_hw_pkcs11ca;
15710 +$cflags.=" -DOPENSSL_NO_HW_PKCS11SO"   if $no_hw_pkcs11so;
15711  $cflags.=" -DOPENSSL_FIPS"    if $fips;
15712  $cflags.=" -DOPENSSL_NO_JPAKE"    if $no_jpake;
15713  $cflags.=" -DOPENSSL_NO_EC2M"    if $no_ec2m;
15714 @@ -345,6 +349,9 @@
15715                 $dir=$val;
15716                 }
15718 +       if ($key eq "PK11_LIB_LOCATION")
15719 +               { $cflags .= " -D$key=\\\"$val\\\"" if $val ne "";}
15721         if ($key eq "KRB5_INCLUDES")
15722                 { $cflags .= " $val";}
15724 @@ -1131,6 +1138,8 @@
15725                 "no-gost" => \$no_gost,
15726                 "no-engine" => \$no_engine,
15727                 "no-hw" => \$no_hw,
15728 +               "no-hw-pkcs11ca" => \$no_hw_pkcs11ca,
15729 +               "no-hw-pkcs11so" => \$no_hw_pkcs11so,
15730                 "no-rsax" => 0,
15731                 "just-ssl" =>
15732                         [\$no_rc2, \$no_idea, \$no_des, \$no_bf, \$no_cast,
15733 Index: openssl/util/mkdef.pl
15734 diff -u openssl/util/mkdef.pl:1.7.2.1.4.1.10.1 openssl/util/mkdef.pl:1.10
15735 --- openssl/util/mkdef.pl:1.7.2.1.4.1.10.1      Fri Jan  2 14:55:51 2015
15736 +++ openssl/util/mkdef.pl       Fri Jan  2 14:56:55 2015
15737 @@ -96,7 +96,7 @@
15738                          # External "algorithms"
15739                          "FP_API", "STDIO", "SOCK", "KRB5", "DGRAM",
15740                          # Engines
15741 -                        "STATIC_ENGINE", "ENGINE", "HW", "GMP",
15742 +                        "STATIC_ENGINE", "ENGINE", "HW", "GMP", "HW_PKCS11CA", "HW_PKCS11SO",
15743                          # RFC3779
15744                          "RFC3779",
15745                          # TLS
15746 @@ -137,6 +137,7 @@
15747  my $no_md2; my $no_md4; my $no_md5; my $no_sha; my $no_ripemd; my $no_mdc2;
15748  my $no_rsa; my $no_dsa; my $no_dh; my $no_hmac=0; my $no_aes; my $no_krb5;
15749  my $no_ec; my $no_ecdsa; my $no_ecdh; my $no_engine; my $no_hw;
15750 +my $no_pkcs11ca; my $no_pkcs11so;
15751  my $no_fp_api; my $no_static_engine=1; my $no_gmp; my $no_deprecated;
15752  my $no_rfc3779; my $no_psk; my $no_tlsext; my $no_cms; my $no_capieng;
15753  my $no_jpake; my $no_srp; my $no_ssl2; my $no_ec2m; my $no_nistp_gcc; 
15754 @@ -242,6 +243,8 @@
15755         elsif (/^no-sctp$/)     { $no_sctp=1; }
15756         elsif (/^no-srtp$/)     { $no_srtp=1; }
15757         elsif (/^no-unit-test$/){ $no_unit_test=1; }
15758 +       elsif (/^no-hw-pkcs11ca$/) { $no_pkcs11ca=1; }
15759 +       elsif (/^no-hw-pkcs11so$/) { $no_pkcs11so=1; }
15760         }
15763 @@ -1196,6 +1199,8 @@
15764                         if ($keyword eq "KRB5" && $no_krb5) { return 0; }
15765                         if ($keyword eq "ENGINE" && $no_engine) { return 0; }
15766                         if ($keyword eq "HW" && $no_hw) { return 0; }
15767 +                       if ($keyword eq "HW_PKCS11CA" && $no_pkcs11ca) { return 0; }
15768 +                       if ($keyword eq "HW_PKCS11SO" && $no_pkcs11so) { return 0; }
15769                         if ($keyword eq "FP_API" && $no_fp_api) { return 0; }
15770                         if ($keyword eq "STATIC_ENGINE" && $no_static_engine) { return 0; }
15771                         if ($keyword eq "GMP" && $no_gmp) { return 0; }
15772 Index: openssl/util/pl/VC-32.pl
15773 diff -u openssl/util/pl/VC-32.pl:1.7.2.1.4.1.2.1.4.1 openssl/util/pl/VC-32.pl:1.10
15774 --- openssl/util/pl/VC-32.pl:1.7.2.1.4.1.2.1.4.1        Mon Apr 14 12:42:50 2014
15775 +++ openssl/util/pl/VC-32.pl    Mon Apr 14 12:44:22 2014
15776 @@ -48,7 +48,7 @@
15777      my $f = $shlib || $fips ?' /MD':' /MT';
15778      $lib_cflag='/Zl' if (!$shlib);     # remove /DEFAULTLIBs from static lib
15779      $opt_cflags=$f.' /Ox';
15780 -    $dbg_cflags=$f.'d /Od -DDEBUG -D_DEBUG';
15781 +    $dbg_cflags=$f.'d /Od /Zi -DDEBUG -D_DEBUG';
15782      $lflags="/nologo /subsystem:console /opt:ref";
15784      *::perlasm_compile_target = sub {