Sync usage with man page.
[netbsd-mini2440.git] / external / bsd / bind / dist / bin / pkcs11 / openssl-0.9.8l-patch
blob16e5347b89ff7290258caf724c2b745f8bd57882
1 Index: openssl/Configure
2 diff -u openssl/Configure:1.1.3.1 openssl/Configure:1.7
3 --- openssl/Configure:1.1.3.1   Mon Feb 16 08:44:22 2009
4 +++ openssl/Configure   Mon Oct  5 13:16:50 2009
5 @@ -12,7 +12,7 @@
6  
7  # see INSTALL for instructions.
8  
9 -my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [experimental-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [enable-montasm] [no-asm] [no-dso] [no-krb5] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
10 +my $usage="Usage: Configure --pk11-libname=PK11_LIB_LOCATION --pk11-flavor=FLAVOR [no-<cipher> ...] [enable-<cipher> ...] [experimental-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [enable-montasm] [no-asm] [no-dso] [no-krb5] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--test-sanity] os/compiler[:flags]\n";
12  # Options:
13  #
14 @@ -21,6 +21,12 @@
15  # --prefix      prefix for the OpenSSL include, lib and bin directories
16  #               (Default: the OPENSSLDIR directory)
17  #
18 +# --pk11-libname  PKCS#11 library name.
19 +#               (No default)
21 +# --pk11-flavor either crypto-accelerator or sign-only
22 +#               (No default)
24  # --install_prefix  Additional prefix for package builders (empty by
25  #               default).  This needn't be set in advance, you can
26  #               just as well use "make INSTALL_PREFIX=/whatever install".
27 @@ -329,7 +335,7 @@
28  "linux-ppc",   "gcc:-DB_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_RISC1 DES_UNROLL::linux_ppc32.o::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
29  #### IA-32 targets...
30  "linux-ia32-icc",      "icc:-DL_ENDIAN -DTERMIO -O2 -no_cpprt::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-KPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
31 -"linux-elf",   "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
32 +"linux-elf",   "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT -pthread::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
33  "linux-aout",  "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -march=i486 -Wall::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_out_asm}",
34  ####
35  "linux-generic64","gcc:-DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHAR RC4_CHUNK DES_INT DES_UNROLL BF_PTR:${no_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
36 @@ -337,7 +343,7 @@
37  "linux-ia64",  "gcc:-DL_ENDIAN -DTERMIO -O3 -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
38  "linux-ia64-ecc","ecc:-DL_ENDIAN -DTERMIO -O2 -Wall -no_cpprt::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
39  "linux-ia64-icc","icc:-DL_ENDIAN -DTERMIO -O2 -Wall -no_cpprt::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK:${ia64_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
40 -"linux-x86_64",        "gcc:-m64 -DL_ENDIAN -DTERMIO -O3 -Wall -DMD32_REG_T=int::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK BF_PTR2 DES_INT DES_UNROLL:${x86_64_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
41 +"linux-x86_64",        "gcc:-m64 -DL_ENDIAN -DTERMIO -O3 -Wall -DMD32_REG_T=int::-D_REENTRANT -pthread::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK BF_PTR2 DES_INT DES_UNROLL:${x86_64_asm}:dlfcn:linux-shared:-fPIC:-m64:.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)",
42  #### SPARC Linux setups
43  # Ray Miller <ray.miller@computing-services.oxford.ac.uk> has patiently
44  # assisted with debugging of following two configs.
45 @@ -580,6 +586,10 @@
46  my $idx_ranlib = $idx++;
47  my $idx_arflags = $idx++;
49 +# PKCS#11 engine patch
50 +my $pk11_libname="";
51 +my $pk11_flavor="";
53  my $prefix="";
54  my $openssldir="";
55  my $exe_ext="";
56 @@ -812,6 +822,14 @@
57                                 {
58                                 $flags.=$_." ";
59                                 }
60 +                        elsif (/^--pk11-libname=(.*)$/)
61 +                                {
62 +                                $pk11_libname=$1;
63 +                                }
64 +                       elsif (/^--pk11-flavor=(.*)$/)
65 +                               {
66 +                               $pk11_flavor=$1;
67 +                               }
68                         elsif (/^--prefix=(.*)$/)
69                                 {
70                                 $prefix=$1;
71 @@ -943,6 +961,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 @@ -1057,6 +1091,25 @@
95         print "\n";
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  $IsMK1MF=1 if ($target eq "mingw" && $^O ne "cygwin" && !is_msys());
120 @@ -1103,6 +1156,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 @@ -1456,6 +1511,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.1.3.1 openssl/Makefile.org:1.3
139 --- openssl/Makefile.org:1.1.3.1        Tue Mar  3 22:40:29 2009
140 +++ openssl/Makefile.org        Fri Sep  4 10:43:21 2009
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.6
153 --- /dev/null   Mon Oct  5 13:17:23 2009
154 +++ openssl/README.pkcs11       Mon Oct  5 13:16:50 2009
155 @@ -0,0 +1,247 @@
156 +ISC modified
157 +============
159 +The PKCS#11 engine exists in two flavors, crypto-accelerator and
160 +sign-only. The first one is from the Solaris patch and uses the
161 +PKCS#11 device for all crypto operations it supports. The second
162 +is a stripped down version which provides only the useful
163 +function (i.e., signature with a RSA private key in the device
164 +protected key store and key loading).
166 +As a hint PKCS#11 boards should use the crypto-accelerator flavor,
167 +external PKCS#11 devices the sign-only. SCA 6000 is an example
168 +of the first, AEP Keyper of the second.
170 +Note it is mandatory to set a pk11-flavor (and only one) in
171 +config/Configure.
173 +PKCS#11 engine support for OpenSSL 0.9.8j
174 +=========================================
176 +[March 11, 2009]
178 +Contents:
180 +Overview
181 +Revisions of the patch for 0.9.8 branch
182 +FAQs
183 +Feedback
185 +Overview
186 +========
188 +This patch containing code available in OpenSolaris adds support for PKCS#11
189 +engine into OpenSSL and implements PKCS#11 v2.20. It is to be applied against
190 +OpenSSL 0.9.8j source code distribution as shipped by OpenSSL.Org. Your system
191 +must provide PKCS#11 backend otherwise the patch is useless. You provide the
192 +PKCS#11 library name during the build configuration phase, see below.
194 +Patch can be applied like this:
196 +       # NOTE: use gtar if on Solaris
197 +       tar xfzv openssl-0.9.8j.tar.gz
198 +       # now download the patch to the current directory
199 +       # ...
200 +       cd openssl-0.9.8j
201 +       # NOTE: must use gpatch if on Solaris (is part of the system)
202 +       patch -p1 < path-to/pkcs11_engine-0.9.8j.patch.2009-03-11
204 +It is designed to support pure acceleration for RSA, DSA, DH and all the
205 +symetric ciphers and message digest algorithms that PKCS#11 and OpenSSL share
206 +except for missing support for patented algorithms MDC2, RC3, RC5 and IDEA.
208 +According to the PKCS#11 providers installed on your machine, it can support
209 +following mechanisms:
211 +       RSA, DSA, DH, RAND, DES-CBC, DES-EDE3-CBC, DES-ECB, DES-EDE3, RC4,
212 +       AES-128-CBC, AES-192-CBC, AES-256-CBC, AES-128-ECB, AES-192-ECB,
213 +       AES-256-ECB, AES-128-CTR, AES-192-CTR, AES-256-CTR, MD5, SHA1, SHA224,
214 +       SHA256, SHA384, SHA512
216 +Note that for AES counter mode the application must provide their own EVP
217 +functions since OpenSSL doesn't support counter mode through EVP yet. You may
218 +see OpenSSH source code (cipher.c) to get the idea how to do that. SunSSH is an
219 +example of code that uses the PKCS#11 engine and deals with the fork-safety
220 +problem (see engine.c and packet.c files if interested).
222 ++------------------------------------------------------------------------------+
223 +| NOTE: this patch version does NOT contain experimental code for accessing    |
224 +| RSA keys stored in PKCS#11 key stores by reference. Some problems were found |
225 +| (thanks to all who wrote me!) and due to my ENOTIME problem I may address    |
226 +| those issues in a future version of the patch that will have that code back, |
227 +| hopefully fixed.                                                             | 
228 ++------------------------------------------------------------------------------+
230 +You must provide the location of PKCS#11 library in your system to the
231 +configure script. You will be instructed to do that when you try to run the
232 +config script:
234 +       $ ./config 
235 +       Operating system: i86pc-whatever-solaris2
236 +       Configuring for solaris-x86-cc
237 +       You must set --pk11-libname for PKCS#11 library.
238 +       See README.pkcs11 for more information.
240 +Taking openCryptoki project on Linux AMD64 box as an example, you would run
241 +configure script like this:
243 +       ./config --pk11-libname=/usr/lib64/pkcs11/PKCS11_API.so
245 +To check whether newly built openssl really supports PKCS#11 it's enough to run
246 +"apps/openssl engine" and look for "(pkcs11) PKCS #11 engine support" in the
247 +output. If you see no PKCS#11 engine support check that the built openssl binary
248 +and the PKCS#11 library from --pk11-libname don't conflict on 32/64 bits.
250 +This patch was tested on Solaris against PKCS#11 engine available from Solaris
251 +Cryptographic Framework (Solaris 10 and OpenSolaris) and also on Linux using
252 +PKCS#11 libraries from openCryptoki project (see openCryptoki website
253 +http://sourceforge.net/projects/opencryptoki for more information). Some Linux
254 +distributions even ship those libraries with the system. The patch should work
255 +on any system that is supported by OpenSSL itself and has functional PKCS#11
256 +library.
258 +The patch contains "RSA Security Inc. PKCS #11 Cryptographic Token Interface
259 +(Cryptoki)" - files cryptoki.h, pkcs11.h, pkcs11f.h and pkcs11t.h which are
260 +copyrighted by RSA Security Inc., see pkcs11.h for more information.
262 +Other added/modified code in this patch is copyrighted by Sun Microsystems,
263 +Inc. and is released under the OpenSSL license (see LICENSE file for more
264 +information).
266 +Revisions of the patch for 0.9.8 branch
267 +=======================================
269 +2009-03-11
270 +- adjusted for OpenSSL version 0.9.8j 
272 +- README.pkcs11 moved out of the patch, and is shipped together with it in a
273 +  tarball instead so that it can be read before the patch is applied.
275 +- fixed bugs:
277 +       6804216 pkcs#11 engine should support a key length range for RC4
278 +       6734038 Apache SSL web server using the pkcs11 engine fails to start if
279 +               meta slot is disabled
281 +2008-12-02
282 +- fixed bugs and RFEs (most of the work done by Vladimir Kotal)
284 +       6723504 more granular locking in PKCS#11 engine
285 +       6667128 CRYPTO_LOCK_PK11_ENGINE assumption does not hold true
286 +       6710420 PKCS#11 engine source should be lint clean
287 +       6747327 PKCS#11 engine atfork handlers need to be aware of guys who take
288 +               it seriously
289 +       6746712 PKCS#11 engine source code should be cstyle clean
290 +       6731380 return codes of several functions are not checked in the PKCS#11
291 +               engine code
292 +       6746735 PKCS#11 engine should use extended FILE space API
293 +       6734038 Apache SSL web server using the pkcs11 engine fails to start if
294 +               meta slot is disabled
296 +2008-08-01
297 +- fixed bug
299 +       6731839 OpenSSL PKCS#11 engine no longer uses n2cp for symmetric ciphers
300 +               and digests
302 +- Solaris specific code for slot selection made automatic
304 +2008-07-29
305 +- update the patch to OpenSSL 0.9.8h version
306 +- pkcs11t.h updated to the latest version:
308 +       6545665 make CKM_AES_CTR available to non-kernel users
310 +- fixed bugs in the engine code:
312 +       6602801 PK11_SESSION cache has to employ reference counting scheme for
313 +               asymmetric key operations
314 +       6605538 pkcs11 functions C_FindObjects[{Init,Final}]() not called
315 +               atomically
316 +       6607307 pkcs#11 engine can't read RSA private keys
317 +       6652362 pk11_RSA_finish() is cutting corners
318 +       6662112 pk11_destroy_{rsa,dsa,dh}_key_objects() use locking in
319 +               suboptimal way
320 +       6666625 pk11_destroy_{rsa,dsa,dh}_key_objects() should be more
321 +               resilient to destroy failures
322 +       6667273 OpenSSL engine should not use free() but OPENSSL_free()
323 +       6670363 PKCS#11 engine fails to reuse existing symmetric keys
324 +       6678135 memory corruption in pk11_DH_generate_key() in pkcs#11 engine
325 +       6678503 DSA signature conversion in pk11_dsa_do_verify() ignores size
326 +               of big numbers leading to failures
327 +       6706562 pk11_DH_compute_key() returns 0 in case of failure instead of
328 +               -1
329 +       6706622 pk11_load_{pub,priv}key create corrupted RSA key references
330 +       6707129 return values from BN_new() in pk11_DH_generate_key() are not
331 +               checked
332 +       6707274 DSA/RSA/DH PKCS#11 engine operations need to be resistant to
333 +               structure reuse
334 +       6707782 OpenSSL PKCS#11 engine pretends to be aware of
335 +               OPENSSL_NO_{RSA,DSA,DH}
336 +       defines but fails miserably
337 +       6709966 make check_new_*() to return values to indicate cache hit/miss
338 +       6705200 pk11_dh struct initialization in PKCS#11 engine is missing
339 +               generate_params parameter
340 +       6709513 PKCS#11 engine sets IV length even for ECB modes
341 +       6728296 buffer length not initialized for C_(En|De)crypt_Final() in the
342 +               PKCS#11 engine
343 +       6728871 PKCS#11 engine must reset global_session in pk11_finish()
345 +- new features and enhancements:
347 +       6562155 OpenSSL pkcs#11 engine needs support for SHA224/256/384/512
348 +       6685012 OpenSSL pkcs#11 engine needs support for new cipher modes
349 +       6725903 OpenSSL PKCS#11 engine shouldn't use soft token for symmetric
350 +               ciphers and digests
352 +2007-10-15
353 +- update for 0.9.8f version
354 +- update for "6607670 teach pkcs#11 engine how to use keys be reference"
356 +2007-10-02
357 +- draft for "6607670 teach pkcs#11 engine how to use keys be reference"
358 +- draft for "6607307 pkcs#11 engine can't read RSA private keys"
360 +2007-09-26
361 +- 6375348 Using pkcs11 as the SSLCryptoDevice with Apache/OpenSSL causes
362 +         significant performance drop
363 +- 6573196 memory is leaked when OpenSSL is used with PKCS#11 engine
365 +2007-05-25
366 +- 6558630 race in OpenSSL pkcs11 engine when using symetric block ciphers
368 +2007-05-19
369 +- initial patch for 0.9.8e using latest OpenSolaris code
371 +FAQs
372 +====
374 +(1) my build failed on Linux distro with this error:
376 +../libcrypto.a(hw_pk11.o): In function `pk11_library_init':
377 +hw_pk11.c:(.text+0x20f5): undefined reference to `pthread_atfork'
379 +       - don't use "no-threads" when configuring
380 +       - if you didn't then OpenSSL failed to create a threaded library by
381 +         default. You may manually edit Configure and try again. Look for the
382 +         architecture that Configure printed, for example:
384 +Configured for linux-elf.
386 +       - then edit Configure, find string "linux-elf" (inluding the quotes),
387 +         and add flags to support threads to the 4th column of the 2nd string.
388 +         If you build with GCC then adding "-pthread" should be enough. With
389 +         "linux-elf" as an example, you would add " -pthread" right after
390 +         "-D_REENTRANT", like this:
392 +....-O3 -fomit-frame-pointer -Wall::-D_REENTRANT -pthread::-ldl:.....
395 +Feedback
396 +========
398 +Please send feedback to security-discuss@opensolaris.org. The patch was
399 +created by Jan.Pechanec@Sun.COM from code available in OpenSolaris.
401 +Latest version should be always available on http://blogs.sun.com/janp.
403 Index: openssl/crypto/opensslconf.h
404 diff -u openssl/crypto/opensslconf.h:1.1.3.1 openssl/crypto/opensslconf.h:1.5
405 --- openssl/crypto/opensslconf.h:1.1.3.1        Wed Mar 25 13:11:43 2009
406 +++ openssl/crypto/opensslconf.h        Fri Sep  4 10:43:21 2009
407 @@ -38,6 +38,9 @@
409  #endif /* OPENSSL_DOING_MAKEDEPEND */
411 +#ifndef OPENSSL_THREADS
412 +# define OPENSSL_THREADS
413 +#endif
414  #ifndef OPENSSL_NO_DYNAMIC_ENGINE
415  # define OPENSSL_NO_DYNAMIC_ENGINE
416  #endif
417 @@ -79,6 +82,8 @@
418  # endif
419  #endif
421 +#define OPENSSL_CPUID_OBJ
423  /* crypto/opensslconf.h.in */
425  #ifdef OPENSSL_DOING_MAKEDEPEND
426 @@ -140,7 +145,7 @@
427   * This enables code handling data aligned at natural CPU word
428   * boundary. See crypto/rc4/rc4_enc.c for further details.
429   */
430 -#undef RC4_CHUNK
431 +#define RC4_CHUNK unsigned long
432  #endif
433  #endif
435 @@ -148,7 +153,7 @@
436  /* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
437   * %20 speed up (longs are 8 bytes, int's are 4). */
438  #ifndef DES_LONG
439 -#define DES_LONG unsigned long
440 +#define DES_LONG unsigned int
441  #endif
442  #endif
444 @@ -162,9 +167,9 @@
445  /* The prime number generation stuff may not work when
446   * EIGHT_BIT but I don't care since I've only used this mode
447   * for debuging the bignum libraries */
448 -#undef SIXTY_FOUR_BIT_LONG
449 +#define SIXTY_FOUR_BIT_LONG
450  #undef SIXTY_FOUR_BIT
451 -#define THIRTY_TWO_BIT
452 +#undef THIRTY_TWO_BIT
453  #undef SIXTEEN_BIT
454  #undef EIGHT_BIT
455  #endif
456 @@ -178,7 +183,7 @@
458  #if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
459  #define CONFIG_HEADER_BF_LOCL_H
460 -#undef BF_PTR
461 +#define BF_PTR2
462  #endif /* HEADER_BF_LOCL_H */
464  #if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
465 @@ -208,7 +213,7 @@
466  /* Unroll the inner loop, this sometimes helps, sometimes hinders.
467   * Very mucy CPU dependant */
468  #ifndef DES_UNROLL
469 -#undef DES_UNROLL
470 +#define DES_UNROLL
471  #endif
473  /* These default values were supplied by
474 Index: openssl/crypto/engine/Makefile
475 diff -u openssl/crypto/engine/Makefile:1.1.3.1 openssl/crypto/engine/Makefile:1.5
476 --- openssl/crypto/engine/Makefile:1.1.3.1      Wed Sep 17 17:10:59 2008
477 +++ openssl/crypto/engine/Makefile      Mon Oct  5 13:16:50 2009
478 @@ -21,12 +21,14 @@
479         eng_table.c eng_pkey.c eng_fat.c eng_all.c \
480         tb_rsa.c tb_dsa.c tb_ecdsa.c tb_dh.c tb_ecdh.c tb_rand.c tb_store.c \
481         tb_cipher.c tb_digest.c \
482 -       eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c eng_padlock.c
483 +       eng_openssl.c eng_cnf.c eng_dyn.c eng_cryptodev.c eng_padlock.c \
484 +       hw_pk11.c hw_pk11_pub.c hw_pk11so.c hw_pk11so_pub.c
485  LIBOBJ= eng_err.o eng_lib.o eng_list.o eng_init.o eng_ctrl.o \
486         eng_table.o eng_pkey.o eng_fat.o eng_all.o \
487         tb_rsa.o tb_dsa.o tb_ecdsa.o tb_dh.o tb_ecdh.o tb_rand.o tb_store.o \
488         tb_cipher.o tb_digest.o \
489 -       eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o eng_padlock.o
490 +       eng_openssl.o eng_cnf.o eng_dyn.o eng_cryptodev.o eng_padlock.o \
491 +       hw_pk11.o hw_pk11_pub.o hw_pk11so.o hw_pk11so_pub.o
493  SRC= $(LIBSRC)
495 @@ -286,6 +288,102 @@
496  eng_table.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h
497  eng_table.o: ../../include/openssl/x509_vfy.h ../cryptlib.h eng_int.h
498  eng_table.o: eng_table.c
499 +hw_pk11.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
500 +hw_pk11.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
501 +hw_pk11.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
502 +hw_pk11.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
503 +hw_pk11.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
504 +hw_pk11.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
505 +hw_pk11.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
506 +hw_pk11.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
507 +hw_pk11.o: ../../include/openssl/ui.h ../../include/openssl/err.h
508 +hw_pk11.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
509 +hw_pk11.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
510 +hw_pk11.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
511 +hw_pk11.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
512 +hw_pk11.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
513 +hw_pk11.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
514 +hw_pk11.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
515 +hw_pk11.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
516 +hw_pk11.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
517 +hw_pk11.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
518 +hw_pk11.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
519 +hw_pk11.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
520 +hw_pk11.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
521 +hw_pk11.o: ../../include/openssl/pem2.h ../cryptlib.h
522 +hw_pk11.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11.c
523 +hw_pk11_pub.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
524 +hw_pk11_pub.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
525 +hw_pk11_pub.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
526 +hw_pk11_pub.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
527 +hw_pk11_pub.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
528 +hw_pk11_pub.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
529 +hw_pk11_pub.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
530 +hw_pk11_pub.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
531 +hw_pk11_pub.o: ../../include/openssl/ui.h ../../include/openssl/err.h
532 +hw_pk11_pub.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
533 +hw_pk11_pub.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
534 +hw_pk11_pub.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
535 +hw_pk11_pub.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
536 +hw_pk11_pub.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
537 +hw_pk11_pub.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
538 +hw_pk11_pub.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
539 +hw_pk11_pub.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
540 +hw_pk11_pub.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
541 +hw_pk11_pub.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
542 +hw_pk11_pub.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
543 +hw_pk11_pub.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
544 +hw_pk11_pub.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
545 +hw_pk11_pub.o: ../../include/openssl/pem2.h ../cryptlib.h
546 +hw_pk11_pub.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11_pub.c
547 +hw_pk11so.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
548 +hw_pk11so.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
549 +hw_pk11so.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
550 +hw_pk11so.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
551 +hw_pk11so.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
552 +hw_pk11so.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
553 +hw_pk11so.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
554 +hw_pk11so.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
555 +hw_pk11so.o: ../../include/openssl/ui.h ../../include/openssl/err.h
556 +hw_pk11so.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
557 +hw_pk11so.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
558 +hw_pk11so.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
559 +hw_pk11so.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
560 +hw_pk11so.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
561 +hw_pk11so.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
562 +hw_pk11so.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
563 +hw_pk11so.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
564 +hw_pk11so.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
565 +hw_pk11so.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
566 +hw_pk11so.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
567 +hw_pk11so.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
568 +hw_pk11so.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
569 +hw_pk11so.o: ../../include/openssl/pem2.h ../cryptlib.h
570 +hw_pk11so.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11so.c
571 +hw_pk11so_pub.o: ../../include/openssl/e_os2.h ../../include/openssl/opensslconf.h
572 +hw_pk11so_pub.o: ../../include/openssl/engine.h ../../include/openssl/ossl_typ.h
573 +hw_pk11so_pub.o: ../../include/openssl/bn.h ../../include/openssl/rsa.h
574 +hw_pk11so_pub.o: ../../include/openssl/asn1.h ../../include/openssl/bio.h
575 +hw_pk11so_pub.o: ../../include/openssl/crypto.h ../../include/openssl/stack.h
576 +hw_pk11so_pub.o: ../../include/openssl/safestack.h ../../include/openssl/opensslv.h
577 +hw_pk11so_pub.o: ../../include/openssl/symhacks.h ../../include/openssl/dsa.h
578 +hw_pk11so_pub.o: ../../include/openssl/dh.h ../../include/openssl/rand.h
579 +hw_pk11so_pub.o: ../../include/openssl/ui.h ../../include/openssl/err.h
580 +hw_pk11so_pub.o: ../../include/openssl/lhash.h ../../include/openssl/dso.h
581 +hw_pk11so_pub.o: ../../include/openssl/pem.h ../../include/openssl/evp.h
582 +hw_pk11so_pub.o: ../../include/openssl/md2.h ../../include/openssl/md4.h
583 +hw_pk11so_pub.o: ../../include/openssl/md5.h ../../include/openssl/sha.h
584 +hw_pk11so_pub.o: ../../include/openssl/ripemd.h ../../include/openssl/des.h
585 +hw_pk11so_pub.o: ../../include/openssl/des_old.h ../../include/openssl/ui_compat.h
586 +hw_pk11so_pub.o: ../../include/openssl/rc4.h ../../include/openssl/rc2.h
587 +hw_pk11so_pub.o: ../../crypto/rc5/rc5.h ../../include/openssl/blowfish.h
588 +hw_pk11so_pub.o: ../../include/openssl/cast.h ../../include/openssl/idea.h
589 +hw_pk11so_pub.o: ../../crypto/mdc2/mdc2.h ../../include/openssl/aes.h
590 +hw_pk11so_pub.o: ../../include/openssl/objects.h ../../include/openssl/obj_mac.h
591 +hw_pk11so_pub.o: ../../include/openssl/x509.h ../../include/openssl/buffer.h
592 +hw_pk11so_pub.o: ../../include/openssl/x509_vfy.h ../../include/openssl/pkcs7.h
593 +hw_pk11so_pub.o: ../../include/openssl/pem2.h ../cryptlib.h
594 +hw_pk11so_pub.o: ../../e_os.h hw_pk11_err.c hw_pk11_err.h hw_pk11so_pub.c
595  tb_cipher.o: ../../e_os.h ../../include/openssl/asn1.h
596  tb_cipher.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
597  tb_cipher.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
598 Index: openssl/crypto/engine/cryptoki.h
599 diff -u /dev/null openssl/crypto/engine/cryptoki.h:1.4
600 --- /dev/null   Mon Oct  5 13:17:24 2009
601 +++ openssl/crypto/engine/cryptoki.h    Thu Dec 18 00:14:12 2008
602 @@ -0,0 +1,103 @@
604 + * CDDL HEADER START
605 + *
606 + * The contents of this file are subject to the terms of the
607 + * Common Development and Distribution License, Version 1.0 only
608 + * (the "License").  You may not use this file except in compliance
609 + * with the License.
610 + *
611 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
612 + * or http://www.opensolaris.org/os/licensing.
613 + * See the License for the specific language governing permissions
614 + * and limitations under the License.
615 + *
616 + * When distributing Covered Code, include this CDDL HEADER in each
617 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
618 + * If applicable, add the following below this CDDL HEADER, with the
619 + * fields enclosed by brackets "[]" replaced with your own identifying
620 + * information: Portions Copyright [yyyy] [name of copyright owner]
621 + *
622 + * CDDL HEADER END
623 + */
625 + * Copyright 2003 Sun Microsystems, Inc.   All rights reserved.
626 + * Use is subject to license terms.
627 + */
629 +#ifndef        _CRYPTOKI_H
630 +#define        _CRYPTOKI_H
632 +/* ident       "@(#)cryptoki.h 1.2     05/06/08 SMI" */
634 +#ifdef __cplusplus
635 +extern "C" {
636 +#endif
638 +#ifndef        CK_PTR
639 +#define        CK_PTR *
640 +#endif
642 +#ifndef CK_DEFINE_FUNCTION
643 +#define        CK_DEFINE_FUNCTION(returnType, name) returnType name
644 +#endif
646 +#ifndef CK_DECLARE_FUNCTION
647 +#define        CK_DECLARE_FUNCTION(returnType, name) returnType name
648 +#endif
650 +#ifndef CK_DECLARE_FUNCTION_POINTER
651 +#define        CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
652 +#endif
654 +#ifndef CK_CALLBACK_FUNCTION
655 +#define        CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
656 +#endif
658 +#ifndef NULL_PTR
659 +#include <unistd.h>    /* For NULL */
660 +#define        NULL_PTR NULL
661 +#endif
664 + * pkcs11t.h defines TRUE and FALSE in a way that upsets lint
665 + */
666 +#ifndef        CK_DISABLE_TRUE_FALSE
667 +#define        CK_DISABLE_TRUE_FALSE
668 +#ifndef        TRUE
669 +#define        TRUE    1
670 +#endif /* TRUE */
671 +#ifndef        FALSE
672 +#define        FALSE   0
673 +#endif /* FALSE */
674 +#endif /* CK_DISABLE_TRUE_FALSE */
676 +#undef CK_PKCS11_FUNCTION_INFO
678 +#include "pkcs11.h"
680 +/* Solaris specific functions */
682 +#include <stdlib.h>
685 + * SUNW_C_GetMechSession will initialize the framework and do all
686 + * the necessary PKCS#11 calls to create a session capable of
687 + * providing operations on the requested mechanism
688 + */
689 +CK_RV SUNW_C_GetMechSession(CK_MECHANISM_TYPE mech,
690 +    CK_SESSION_HANDLE_PTR hSession);
693 + * SUNW_C_KeyToObject will create a secret key object for the given
694 + * mechanism from the rawkey data.
695 + */
696 +CK_RV SUNW_C_KeyToObject(CK_SESSION_HANDLE hSession,
697 +    CK_MECHANISM_TYPE mech, const void *rawkey, size_t rawkey_len,
698 +    CK_OBJECT_HANDLE_PTR obj);
701 +#ifdef __cplusplus
703 +#endif
705 +#endif /* _CRYPTOKI_H */
706 Index: openssl/crypto/engine/eng_all.c
707 diff -u openssl/crypto/engine/eng_all.c:1.1.3.1 openssl/crypto/engine/eng_all.c:1.3
708 --- openssl/crypto/engine/eng_all.c:1.1.3.1     Wed Jun  4 18:01:39 2008
709 +++ openssl/crypto/engine/eng_all.c     Mon Oct  5 13:16:50 2009
710 @@ -110,6 +110,14 @@
711  #if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
712         ENGINE_load_capi();
713  #endif
714 +#ifndef OPENSSL_NO_HW_PKCS11
715 +#ifndef OPENSSL_NO_HW_PKCS11CA
716 +       ENGINE_load_pk11ca();
717 +#endif
718 +#ifndef OPENSSL_NO_HW_PKCS11SO
719 +       ENGINE_load_pk11so();
720 +#endif
721 +#endif
722  #endif
723         }
725 Index: openssl/crypto/engine/eng_list.c
726 diff -u openssl/crypto/engine/eng_list.c:1.1.3.1 openssl/crypto/engine/eng_list.c:1.2
727 --- openssl/crypto/engine/eng_list.c:1.1.3.1    Sat Aug  6 10:34:35 2005
728 +++ openssl/crypto/engine/eng_list.c    Mon Oct  5 13:16:50 2009
729 @@ -408,7 +408,11 @@
730                                 !ENGINE_ctrl_cmd_string(iterator, "DIR_ADD",
731                                         load_dir, 0) ||
732                                 !ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0))
733 +                       {
734 +                               if (iterator)
735 +                                       ENGINE_free(iterator);
736                                 goto notfound;
737 +                       }
738                 return iterator;
739                 }
740  notfound:
741 Index: openssl/crypto/engine/engine.h
742 diff -u openssl/crypto/engine/engine.h:1.1.3.1 openssl/crypto/engine/engine.h:1.3
743 --- openssl/crypto/engine/engine.h:1.1.3.1      Wed Jun  4 18:01:40 2008
744 +++ openssl/crypto/engine/engine.h      Mon Oct  5 13:16:50 2009
745 @@ -337,6 +337,12 @@
746  void ENGINE_load_ubsec(void);
747  #endif
748  void ENGINE_load_cryptodev(void);
749 +#ifndef OPENSSL_NO_HW_PKCS11CA
750 +void ENGINE_load_pk11ca(void);
751 +#endif
752 +#ifndef OPENSSL_NO_HW_PKCS11SO
753 +void ENGINE_load_pk11so(void);
754 +#endif
755  void ENGINE_load_padlock(void);
756  void ENGINE_load_builtin_engines(void);
757  #ifndef OPENSSL_NO_CAPIENG
758 Index: openssl/crypto/engine/hw_pk11.c
759 diff -u /dev/null openssl/crypto/engine/hw_pk11.c:1.26
760 --- /dev/null   Mon Oct  5 13:17:24 2009
761 +++ openssl/crypto/engine/hw_pk11.c     Mon Oct  5 13:16:50 2009
762 @@ -0,0 +1,3927 @@
764 + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
765 + * Use is subject to license terms.
766 + */
768 +/* crypto/engine/hw_pk11.c */
770 + * This product includes software developed by the OpenSSL Project for
771 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
772 + *
773 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
774 + * Afchine Madjlessi.
775 + */
777 + * ====================================================================
778 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
779 + *
780 + * Redistribution and use in source and binary forms, with or without
781 + * modification, are permitted provided that the following conditions
782 + * are met:
783 + *
784 + * 1. Redistributions of source code must retain the above copyright
785 + *    notice, this list of conditions and the following disclaimer.
786 + *
787 + * 2. Redistributions in binary form must reproduce the above copyright
788 + *    notice, this list of conditions and the following disclaimer in
789 + *    the documentation and/or other materials provided with the
790 + *    distribution.
791 + *
792 + * 3. All advertising materials mentioning features or use of this
793 + *    software must display the following acknowledgment:
794 + *    "This product includes software developed by the OpenSSL Project
795 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
796 + *
797 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
798 + *    endorse or promote products derived from this software without
799 + *    prior written permission. For written permission, please contact
800 + *    licensing@OpenSSL.org.
801 + *
802 + * 5. Products derived from this software may not be called "OpenSSL"
803 + *    nor may "OpenSSL" appear in their names without prior written
804 + *    permission of the OpenSSL Project.
805 + *
806 + * 6. Redistributions of any form whatsoever must retain the following
807 + *    acknowledgment:
808 + *    "This product includes software developed by the OpenSSL Project
809 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
810 + *
811 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
812 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
813 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
814 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
815 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
816 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
817 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
818 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
819 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
820 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
821 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
822 + * OF THE POSSIBILITY OF SUCH DAMAGE.
823 + * ====================================================================
824 + *
825 + * This product includes cryptographic software written by Eric Young
826 + * (eay@cryptsoft.com).  This product includes software written by Tim
827 + * Hudson (tjh@cryptsoft.com).
828 + *
829 + */
831 +#include <stdio.h>
832 +#include <stdlib.h>
833 +#include <string.h>
834 +#include <sys/types.h>
836 +#include <openssl/e_os2.h>
837 +#include <openssl/crypto.h>
838 +#include <cryptlib.h>
839 +#include <openssl/engine.h>
840 +#include <openssl/dso.h>
841 +#include <openssl/err.h>
842 +#include <openssl/bn.h>
843 +#include <openssl/md5.h>
844 +#include <openssl/pem.h>
845 +#ifndef OPENSSL_NO_RSA
846 +#include <openssl/rsa.h>
847 +#endif
848 +#ifndef OPENSSL_NO_DSA
849 +#include <openssl/dsa.h>
850 +#endif
851 +#ifndef OPENSSL_NO_DH
852 +#include <openssl/dh.h>
853 +#endif
854 +#include <openssl/rand.h>
855 +#include <openssl/objects.h>
856 +#include <openssl/x509.h>
857 +#include <openssl/aes.h>
859 +#ifdef OPENSSL_SYS_WIN32
860 +typedef int pid_t;
861 +#define getpid() GetCurrentProcessId()
862 +#define NOPTHREADS
863 +#ifndef NULL_PTR
864 +#define NULL_PTR NULL
865 +#endif
866 +#define CK_DEFINE_FUNCTION(returnType, name) \
867 +       returnType __declspec(dllexport) name
868 +#define CK_DECLARE_FUNCTION(returnType, name) \
869 +       returnType __declspec(dllimport) name
870 +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
871 +       returnType __declspec(dllimport) (* name)
872 +#else
873 +#include <signal.h>
874 +#include <unistd.h>
875 +#include <dlfcn.h>
876 +#endif
878 +#ifndef NOPTHREADS
879 +#include <pthread.h>
880 +#endif
882 +#ifndef OPENSSL_NO_HW
883 +#ifndef OPENSSL_NO_HW_PK11
884 +#ifndef OPENSSL_NO_HW_PK11CA
886 +/* label for debug messages printed on stderr */
887 +#define        PK11_DBG        "PKCS#11 ENGINE DEBUG"
888 +/* prints a lot of debug messages on stderr about slot selection process */
889 +/* #undef      DEBUG_SLOT_SELECTION */
891 + * Solaris specific code. See comment at check_hw_mechanisms() for more
892 + * information.
893 + */
894 +#if defined (__SVR4) && defined (__sun)
895 +#undef SOLARIS_HW_SLOT_SELECTION
896 +#endif
899 + * AES counter mode is not supported in the OpenSSL EVP API yet and neither
900 + * there are official OIDs for mechanisms based on this mode. With our changes,
901 + * an application can define its own EVP calls for AES counter mode and then
902 + * it can make use of hardware acceleration through this engine. However, it's
903 + * better if we keep AES CTR support code under ifdef's.
904 + */
905 +#define        SOLARIS_AES_CTR
907 +#ifdef OPENSSL_SYS_WIN32
908 +#pragma pack(push, cryptoki, 1)
909 +#include "cryptoki.h"
910 +#include "pkcs11.h"
911 +#pragma pack(pop, cryptoki)
912 +#else
913 +#include "cryptoki.h"
914 +#include "pkcs11.h"
915 +#endif
916 +#include "hw_pk11ca.h"
917 +#include "hw_pk11_err.c"
919 +#ifdef SOLARIS_AES_CTR
921 + * NIDs for AES counter mode that will be defined during the engine
922 + * initialization.
923 + */
924 +static int NID_aes_128_ctr = NID_undef;
925 +static int NID_aes_192_ctr = NID_undef;
926 +static int NID_aes_256_ctr = NID_undef;
927 +#endif /* SOLARIS_AES_CTR */
929 +#ifdef SOLARIS_HW_SLOT_SELECTION
931 + * Tables for symmetric ciphers and digest mechs found in the pkcs11_kernel
932 + * library. See comment at check_hw_mechanisms() for more information.
933 + */
934 +static int *hw_cnids;
935 +static int *hw_dnids;
936 +#endif /* SOLARIS_HW_SLOT_SELECTION */
938 +/* PKCS#11 session caches and their locks for all operation types */
939 +static PK11_CACHE session_cache[OP_MAX];
942 + * As stated in v2.20, 11.7 Object Management Function, in section for
943 + * C_FindObjectsInit(), at most one search operation may be active at a given
944 + * time in a given session. Therefore, C_Find{,Init,Final}Objects() should be
945 + * grouped together to form one atomic search operation. This is already
946 + * ensured by the property of unique PKCS#11 session handle used for each
947 + * PK11_SESSION object.
948 + *
949 + * This is however not the biggest concern - maintaining consistency of the
950 + * underlying object store is more important. The same section of the spec also
951 + * says that one thread can be in the middle of a search operation while another
952 + * thread destroys the object matching the search template which would result in
953 + * invalid handle returned from the search operation.
954 + *
955 + * Hence, the following locks are used for both protection of the object stores.
956 + * They are also used for active list protection.
957 + */
958 +#ifndef NOPTHREADS
959 +pthread_mutex_t *find_lock[OP_MAX] = { NULL };
960 +#endif
963 + * lists of asymmetric key handles which are active (referenced by at least one
964 + * PK11_SESSION structure, either held by a thread or present in free_session
965 + * list) for given algorithm type
966 + */
967 +PK11_active *active_list[OP_MAX] = { NULL };
970 + * Create all secret key objects in a global session so that they are available
971 + * to use for other sessions. These other sessions may be opened or closed
972 + * without losing the secret key objects.
973 + */
974 +static CK_SESSION_HANDLE       global_session = CK_INVALID_HANDLE;
976 +/* ENGINE level stuff */
977 +static int pk11_init(ENGINE *e);
978 +static int pk11_library_init(ENGINE *e);
979 +static int pk11_finish(ENGINE *e);
980 +static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
981 +static int pk11_destroy(ENGINE *e);
983 +/* RAND stuff */
984 +static void pk11_rand_seed(const void *buf, int num);
985 +static void pk11_rand_add(const void *buf, int num, double add_entropy);
986 +static void pk11_rand_cleanup(void);
987 +static int pk11_rand_bytes(unsigned char *buf, int num);
988 +static int pk11_rand_status(void);
990 +/* These functions are also used in other files */
991 +PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
992 +void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
994 +/* active list manipulation functions used in this file */
995 +extern int pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type);
996 +extern void pk11_free_active_list(PK11_OPTYPE type);
998 +#ifndef OPENSSL_NO_RSA
999 +int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
1000 +int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
1001 +int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
1002 +#endif
1003 +#ifndef OPENSSL_NO_DSA
1004 +int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
1005 +int pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
1006 +int pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
1007 +#endif
1008 +#ifndef OPENSSL_NO_DH
1009 +int pk11_destroy_dh_key_objects(PK11_SESSION *session);
1010 +int pk11_destroy_dh_object(PK11_SESSION *session, CK_BBOOL uselock);
1011 +#endif
1013 +/* Local helper functions */
1014 +static int pk11_free_all_sessions(void);
1015 +static int pk11_free_session_list(PK11_OPTYPE optype);
1016 +static int pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype);
1017 +static int pk11_destroy_cipher_key_objects(PK11_SESSION *session);
1018 +static int pk11_destroy_object(CK_SESSION_HANDLE session,
1019 +       CK_OBJECT_HANDLE oh);
1020 +static const char *get_PK11_LIBNAME(void);
1021 +static void free_PK11_LIBNAME(void);
1022 +static long set_PK11_LIBNAME(const char *name);
1024 +/* Symmetric cipher and digest support functions */
1025 +static int cipher_nid_to_pk11(int nid);
1026 +#ifdef SOLARIS_AES_CTR
1027 +static int pk11_add_NID(char *sn, char *ln);
1028 +static int pk11_add_aes_ctr_NIDs(void);
1029 +#endif /* SOLARIS_AES_CTR */
1030 +static int pk11_usable_ciphers(const int **nids);
1031 +static int pk11_usable_digests(const int **nids);
1032 +static int pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
1033 +       const unsigned char *iv, int enc);
1034 +static int pk11_cipher_final(PK11_SESSION *sp);
1035 +static int pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
1036 +       const unsigned char *in, unsigned int inl);
1037 +static int pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx);
1038 +static int pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
1039 +       const int **nids, int nid);
1040 +static int pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
1041 +       const int **nids, int nid);
1042 +static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
1043 +       const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp);
1044 +static int check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key,
1045 +       int key_len);
1046 +static int md_nid_to_pk11(int nid);
1047 +static int pk11_digest_init(EVP_MD_CTX *ctx);
1048 +static int pk11_digest_update(EVP_MD_CTX *ctx, const void *data,
1049 +       size_t count);
1050 +static int pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md);
1051 +static int pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from);
1052 +static int pk11_digest_cleanup(EVP_MD_CTX *ctx);
1054 +static int pk11_choose_slots(int *any_slot_found);
1055 +static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
1056 +    CK_SLOT_ID current_slot, int *current_slot_n_cipher,
1057 +    int *local_cipher_nids);
1058 +static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
1059 +    CK_SLOT_ID current_slot, int *current_slot_n_digest,
1060 +    int *local_digest_nids);
1061 +static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR, int slot_id,
1062 +    CK_MECHANISM_TYPE mech, int *current_slot_n_cipher, int *local_cipher_nids,
1063 +    int id);
1064 +static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
1065 +    CK_MECHANISM_TYPE mech, int *current_slot_n_digest, int *local_digest_nids,
1066 +    int id);
1068 +static int pk11_init_all_locks(void);
1069 +static void pk11_free_all_locks(void);
1071 +#ifdef SOLARIS_HW_SLOT_SELECTION
1072 +static int check_hw_mechanisms(void);
1073 +static int nid_in_table(int nid, int *nid_table);
1074 +#endif /* SOLARIS_HW_SLOT_SELECTION */
1076 +/* Index for the supported ciphers */
1077 +enum pk11_cipher_id {
1078 +       PK11_DES_CBC,
1079 +       PK11_DES3_CBC,
1080 +       PK11_DES_ECB,
1081 +       PK11_DES3_ECB,
1082 +       PK11_RC4,
1083 +       PK11_AES_128_CBC,
1084 +       PK11_AES_192_CBC,
1085 +       PK11_AES_256_CBC,
1086 +       PK11_AES_128_ECB,
1087 +       PK11_AES_192_ECB,
1088 +       PK11_AES_256_ECB,
1089 +       PK11_BLOWFISH_CBC,
1090 +#ifdef SOLARIS_AES_CTR
1091 +       PK11_AES_128_CTR,
1092 +       PK11_AES_192_CTR,
1093 +       PK11_AES_256_CTR,
1094 +#endif /* SOLARIS_AES_CTR */
1095 +       PK11_CIPHER_MAX
1098 +/* Index for the supported digests */
1099 +enum pk11_digest_id {
1100 +       PK11_MD5,
1101 +       PK11_SHA1,
1102 +       PK11_SHA224,
1103 +       PK11_SHA256,
1104 +       PK11_SHA384,
1105 +       PK11_SHA512,
1106 +       PK11_DIGEST_MAX
1109 +#define        TRY_OBJ_DESTROY(sess_hdl, obj_hdl, retval, uselock, alg_type)   \
1110 +       {                                                               \
1111 +       if (uselock)                                                    \
1112 +               LOCK_OBJSTORE(alg_type);                                \
1113 +       if (pk11_active_delete(obj_hdl, alg_type) == 1)                 \
1114 +               {                                                       \
1115 +               retval = pk11_destroy_object(sess_hdl, obj_hdl);        \
1116 +               }                                                       \
1117 +       if (uselock)                                                    \
1118 +               UNLOCK_OBJSTORE(alg_type);                              \
1119 +       }
1121 +#define        TRY_OBJ_DELETE(sess_hdl, obj_hdl, retval, uselock, alg_type)    \
1122 +       {                                                               \
1123 +       if (uselock)                                                    \
1124 +               LOCK_OBJSTORE(alg_type);                                \
1125 +       (void) pk11_active_delete(obj_hdl, alg_type);                   \
1126 +       if (uselock)                                                    \
1127 +               UNLOCK_OBJSTORE(alg_type);                              \
1128 +       }
1130 +static int cipher_nids[PK11_CIPHER_MAX];
1131 +static int digest_nids[PK11_DIGEST_MAX];
1132 +static int cipher_count                = 0;
1133 +static int digest_count                = 0;
1134 +static CK_BBOOL pk11_have_rsa  = CK_FALSE;
1135 +static CK_BBOOL pk11_have_recover = CK_FALSE;
1136 +static CK_BBOOL pk11_have_dsa  = CK_FALSE;
1137 +static CK_BBOOL pk11_have_dh   = CK_FALSE;
1138 +static CK_BBOOL pk11_have_random = CK_FALSE;
1140 +typedef struct PK11_CIPHER_st
1141 +       {
1142 +       enum pk11_cipher_id     id;
1143 +       int                     nid;
1144 +       int                     iv_len;
1145 +       int                     min_key_len;
1146 +       int                     max_key_len;
1147 +       CK_KEY_TYPE             key_type;
1148 +       CK_MECHANISM_TYPE       mech_type;
1149 +       } PK11_CIPHER;
1151 +static PK11_CIPHER ciphers[] =
1152 +       {
1153 +       { PK11_DES_CBC,         NID_des_cbc,            8,       8,   8,
1154 +               CKK_DES,        CKM_DES_CBC, },
1155 +       { PK11_DES3_CBC,        NID_des_ede3_cbc,       8,      24,  24,
1156 +               CKK_DES3,       CKM_DES3_CBC, },
1157 +       { PK11_DES_ECB,         NID_des_ecb,            0,       8,   8,
1158 +               CKK_DES,        CKM_DES_ECB, },
1159 +       { PK11_DES3_ECB,        NID_des_ede3_ecb,       0,      24,  24,
1160 +               CKK_DES3,       CKM_DES3_ECB, },
1161 +       { PK11_RC4,             NID_rc4,                0,      16, 256,
1162 +               CKK_RC4,        CKM_RC4, },
1163 +       { PK11_AES_128_CBC,     NID_aes_128_cbc,        16,     16,  16,
1164 +               CKK_AES,        CKM_AES_CBC, },
1165 +       { PK11_AES_192_CBC,     NID_aes_192_cbc,        16,     24,  24,
1166 +               CKK_AES,        CKM_AES_CBC, },
1167 +       { PK11_AES_256_CBC,     NID_aes_256_cbc,        16,     32,  32,
1168 +               CKK_AES,        CKM_AES_CBC, },
1169 +       { PK11_AES_128_ECB,     NID_aes_128_ecb,        0,      16,  16,
1170 +               CKK_AES,        CKM_AES_ECB, },
1171 +       { PK11_AES_192_ECB,     NID_aes_192_ecb,        0,      24,  24,
1172 +               CKK_AES,        CKM_AES_ECB, },
1173 +       { PK11_AES_256_ECB,     NID_aes_256_ecb,        0,      32,  32,
1174 +               CKK_AES,        CKM_AES_ECB, },
1175 +       { PK11_BLOWFISH_CBC,    NID_bf_cbc,             8,      16,  16,
1176 +               CKK_BLOWFISH,   CKM_BLOWFISH_CBC, },
1177 +#ifdef SOLARIS_AES_CTR
1178 +       /* we don't know the correct NIDs until the engine is initialized */
1179 +       { PK11_AES_128_CTR,     NID_undef,              16,     16,  16,
1180 +               CKK_AES,        CKM_AES_CTR, },
1181 +       { PK11_AES_192_CTR,     NID_undef,              16,     24,  24,
1182 +               CKK_AES,        CKM_AES_CTR, },
1183 +       { PK11_AES_256_CTR,     NID_undef,              16,     32,  32,
1184 +               CKK_AES,        CKM_AES_CTR, },
1185 +#endif /* SOLARIS_AES_CTR */
1186 +       };
1188 +typedef struct PK11_DIGEST_st
1189 +       {
1190 +       enum pk11_digest_id     id;
1191 +       int                     nid;
1192 +       CK_MECHANISM_TYPE       mech_type;
1193 +       } PK11_DIGEST;
1195 +static PK11_DIGEST digests[] =
1196 +       {
1197 +       {PK11_MD5,      NID_md5,        CKM_MD5, },
1198 +       {PK11_SHA1,     NID_sha1,       CKM_SHA_1, },
1199 +       {PK11_SHA224,   NID_sha224,     CKM_SHA224, },
1200 +       {PK11_SHA256,   NID_sha256,     CKM_SHA256, },
1201 +       {PK11_SHA384,   NID_sha384,     CKM_SHA384, },
1202 +       {PK11_SHA512,   NID_sha512,     CKM_SHA512, },
1203 +       {0,             NID_undef,      0xFFFF, },
1204 +       };
1207 + * Structure to be used for the cipher_data/md_data in
1208 + * EVP_CIPHER_CTX/EVP_MD_CTX structures in order to use the same pk11
1209 + * session in multiple cipher_update calls
1210 + */
1211 +typedef struct PK11_CIPHER_STATE_st
1212 +       {
1213 +       PK11_SESSION    *sp;
1214 +       } PK11_CIPHER_STATE;
1218 + * libcrypto EVP stuff - this is how we get wired to EVP so the engine gets
1219 + * called when libcrypto requests a cipher NID.
1220 + *
1221 + * Note how the PK11_CIPHER_STATE is used here.
1222 + */
1224 +/* DES CBC EVP */
1225 +static const EVP_CIPHER pk11_des_cbc =
1226 +       {
1227 +       NID_des_cbc,
1228 +       8, 8, 8,
1229 +       EVP_CIPH_CBC_MODE,
1230 +       pk11_cipher_init,
1231 +       pk11_cipher_do_cipher,
1232 +       pk11_cipher_cleanup,
1233 +       sizeof (PK11_CIPHER_STATE),
1234 +       EVP_CIPHER_set_asn1_iv,
1235 +       EVP_CIPHER_get_asn1_iv,
1236 +       NULL
1237 +       };
1239 +/* 3DES CBC EVP */
1240 +static const EVP_CIPHER pk11_3des_cbc =
1241 +       {
1242 +       NID_des_ede3_cbc,
1243 +       8, 24, 8,
1244 +       EVP_CIPH_CBC_MODE,
1245 +       pk11_cipher_init,
1246 +       pk11_cipher_do_cipher,
1247 +       pk11_cipher_cleanup,
1248 +       sizeof (PK11_CIPHER_STATE),
1249 +       EVP_CIPHER_set_asn1_iv,
1250 +       EVP_CIPHER_get_asn1_iv,
1251 +       NULL
1252 +       };
1255 + * ECB modes don't use an Initial Vector so that's why set_asn1_parameters and
1256 + * get_asn1_parameters fields are set to NULL.
1257 + */
1258 +static const EVP_CIPHER pk11_des_ecb =
1259 +       {
1260 +       NID_des_ecb,
1261 +       8, 8, 8,
1262 +       EVP_CIPH_ECB_MODE,
1263 +       pk11_cipher_init,
1264 +       pk11_cipher_do_cipher,
1265 +       pk11_cipher_cleanup,
1266 +       sizeof (PK11_CIPHER_STATE),
1267 +       NULL,
1268 +       NULL,
1269 +       NULL
1270 +       };
1272 +static const EVP_CIPHER pk11_3des_ecb =
1273 +       {
1274 +       NID_des_ede3_ecb,
1275 +       8, 24, 8,
1276 +       EVP_CIPH_ECB_MODE,
1277 +       pk11_cipher_init,
1278 +       pk11_cipher_do_cipher,
1279 +       pk11_cipher_cleanup,
1280 +       sizeof (PK11_CIPHER_STATE),
1281 +       NULL,
1282 +       NULL,
1283 +       NULL
1284 +       };
1287 +static const EVP_CIPHER pk11_aes_128_cbc =
1288 +       {
1289 +       NID_aes_128_cbc,
1290 +       16, 16, 16,
1291 +       EVP_CIPH_CBC_MODE,
1292 +       pk11_cipher_init,
1293 +       pk11_cipher_do_cipher,
1294 +       pk11_cipher_cleanup,
1295 +       sizeof (PK11_CIPHER_STATE),
1296 +       EVP_CIPHER_set_asn1_iv,
1297 +       EVP_CIPHER_get_asn1_iv,
1298 +       NULL
1299 +       };
1301 +static const EVP_CIPHER pk11_aes_192_cbc =
1302 +       {
1303 +       NID_aes_192_cbc,
1304 +       16, 24, 16,
1305 +       EVP_CIPH_CBC_MODE,
1306 +       pk11_cipher_init,
1307 +       pk11_cipher_do_cipher,
1308 +       pk11_cipher_cleanup,
1309 +       sizeof (PK11_CIPHER_STATE),
1310 +       EVP_CIPHER_set_asn1_iv,
1311 +       EVP_CIPHER_get_asn1_iv,
1312 +       NULL
1313 +       };
1315 +static const EVP_CIPHER pk11_aes_256_cbc =
1316 +       {
1317 +       NID_aes_256_cbc,
1318 +       16, 32, 16,
1319 +       EVP_CIPH_CBC_MODE,
1320 +       pk11_cipher_init,
1321 +       pk11_cipher_do_cipher,
1322 +       pk11_cipher_cleanup,
1323 +       sizeof (PK11_CIPHER_STATE),
1324 +       EVP_CIPHER_set_asn1_iv,
1325 +       EVP_CIPHER_get_asn1_iv,
1326 +       NULL
1327 +       };
1330 + * ECB modes don't use IV so that's why set_asn1_parameters and
1331 + * get_asn1_parameters are set to NULL.
1332 + */
1333 +static const EVP_CIPHER pk11_aes_128_ecb =
1334 +       {
1335 +       NID_aes_128_ecb,
1336 +       16, 16, 0,
1337 +       EVP_CIPH_ECB_MODE,
1338 +       pk11_cipher_init,
1339 +       pk11_cipher_do_cipher,
1340 +       pk11_cipher_cleanup,
1341 +       sizeof (PK11_CIPHER_STATE),
1342 +       NULL,
1343 +       NULL,
1344 +       NULL
1345 +       };
1347 +static const EVP_CIPHER pk11_aes_192_ecb =
1348 +       {
1349 +       NID_aes_192_ecb,
1350 +       16, 24, 0,
1351 +       EVP_CIPH_ECB_MODE,
1352 +       pk11_cipher_init,
1353 +       pk11_cipher_do_cipher,
1354 +       pk11_cipher_cleanup,
1355 +       sizeof (PK11_CIPHER_STATE),
1356 +       NULL,
1357 +       NULL,
1358 +       NULL
1359 +       };
1361 +static const EVP_CIPHER pk11_aes_256_ecb =
1362 +       {
1363 +       NID_aes_256_ecb,
1364 +       16, 32, 0,
1365 +       EVP_CIPH_ECB_MODE,
1366 +       pk11_cipher_init,
1367 +       pk11_cipher_do_cipher,
1368 +       pk11_cipher_cleanup,
1369 +       sizeof (PK11_CIPHER_STATE),
1370 +       NULL,
1371 +       NULL,
1372 +       NULL
1373 +       };
1375 +#ifdef SOLARIS_AES_CTR
1377 + * NID_undef's will be changed to the AES counter mode NIDs as soon they are
1378 + * created in pk11_library_init(). Note that the need to change these structures
1379 + * is the reason why we don't define them with the const keyword.
1380 + */
1381 +static EVP_CIPHER pk11_aes_128_ctr =
1382 +       {
1383 +       NID_undef,
1384 +       16, 16, 16,
1385 +       EVP_CIPH_CBC_MODE,
1386 +       pk11_cipher_init,
1387 +       pk11_cipher_do_cipher,
1388 +       pk11_cipher_cleanup,
1389 +       sizeof (PK11_CIPHER_STATE),
1390 +       EVP_CIPHER_set_asn1_iv,
1391 +       EVP_CIPHER_get_asn1_iv,
1392 +       NULL
1393 +       };
1395 +static EVP_CIPHER pk11_aes_192_ctr =
1396 +       {
1397 +       NID_undef,
1398 +       16, 24, 16,
1399 +       EVP_CIPH_CBC_MODE,
1400 +       pk11_cipher_init,
1401 +       pk11_cipher_do_cipher,
1402 +       pk11_cipher_cleanup,
1403 +       sizeof (PK11_CIPHER_STATE),
1404 +       EVP_CIPHER_set_asn1_iv,
1405 +       EVP_CIPHER_get_asn1_iv,
1406 +       NULL
1407 +       };
1409 +static EVP_CIPHER pk11_aes_256_ctr =
1410 +       {
1411 +       NID_undef,
1412 +       16, 32, 16,
1413 +       EVP_CIPH_CBC_MODE,
1414 +       pk11_cipher_init,
1415 +       pk11_cipher_do_cipher,
1416 +       pk11_cipher_cleanup,
1417 +       sizeof (PK11_CIPHER_STATE),
1418 +       EVP_CIPHER_set_asn1_iv,
1419 +       EVP_CIPHER_get_asn1_iv,
1420 +       NULL
1421 +       };
1422 +#endif /* SOLARIS_AES_CTR */
1424 +static const EVP_CIPHER pk11_bf_cbc =
1425 +       {
1426 +       NID_bf_cbc,
1427 +       8, 16, 8,
1428 +       EVP_CIPH_VARIABLE_LENGTH,
1429 +       pk11_cipher_init,
1430 +       pk11_cipher_do_cipher,
1431 +       pk11_cipher_cleanup,
1432 +       sizeof (PK11_CIPHER_STATE),
1433 +       EVP_CIPHER_set_asn1_iv,
1434 +       EVP_CIPHER_get_asn1_iv,
1435 +       NULL
1436 +       };
1438 +static const EVP_CIPHER pk11_rc4 =
1439 +       {
1440 +       NID_rc4,
1441 +       1, 16, 0,
1442 +       EVP_CIPH_VARIABLE_LENGTH,
1443 +       pk11_cipher_init,
1444 +       pk11_cipher_do_cipher,
1445 +       pk11_cipher_cleanup,
1446 +       sizeof (PK11_CIPHER_STATE),
1447 +       NULL,
1448 +       NULL,
1449 +       NULL
1450 +       };
1452 +static const EVP_MD pk11_md5 =
1453 +       {
1454 +       NID_md5,
1455 +       NID_md5WithRSAEncryption,
1456 +       MD5_DIGEST_LENGTH,
1457 +       0,
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 +       MD5_CBLOCK,
1465 +       sizeof (PK11_CIPHER_STATE),
1466 +       };
1468 +static const EVP_MD pk11_sha1 =
1469 +       {
1470 +       NID_sha1,
1471 +       NID_sha1WithRSAEncryption,
1472 +       SHA_DIGEST_LENGTH,
1473 +       0,
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_CBLOCK,
1481 +       sizeof (PK11_CIPHER_STATE),
1482 +       };
1484 +static const EVP_MD pk11_sha224 =
1485 +       {
1486 +       NID_sha224,
1487 +       NID_sha224WithRSAEncryption,
1488 +       SHA224_DIGEST_LENGTH,
1489 +       0,
1490 +       pk11_digest_init,
1491 +       pk11_digest_update,
1492 +       pk11_digest_final,
1493 +       pk11_digest_copy,
1494 +       pk11_digest_cleanup,
1495 +       EVP_PKEY_RSA_method,
1496 +       /* SHA-224 uses the same cblock size as SHA-256 */
1497 +       SHA256_CBLOCK,
1498 +       sizeof (PK11_CIPHER_STATE),
1499 +       };
1501 +static const EVP_MD pk11_sha256 =
1502 +       {
1503 +       NID_sha256,
1504 +       NID_sha256WithRSAEncryption,
1505 +       SHA256_DIGEST_LENGTH,
1506 +       0,
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 +       SHA256_CBLOCK,
1514 +       sizeof (PK11_CIPHER_STATE),
1515 +       };
1517 +static const EVP_MD pk11_sha384 =
1518 +       {
1519 +       NID_sha384,
1520 +       NID_sha384WithRSAEncryption,
1521 +       SHA384_DIGEST_LENGTH,
1522 +       0,
1523 +       pk11_digest_init,
1524 +       pk11_digest_update,
1525 +       pk11_digest_final,
1526 +       pk11_digest_copy,
1527 +       pk11_digest_cleanup,
1528 +       EVP_PKEY_RSA_method,
1529 +       /* SHA-384 uses the same cblock size as SHA-512 */
1530 +       SHA512_CBLOCK,
1531 +       sizeof (PK11_CIPHER_STATE),
1532 +       };
1534 +static const EVP_MD pk11_sha512 =
1535 +       {
1536 +       NID_sha512,
1537 +       NID_sha512WithRSAEncryption,
1538 +       SHA512_DIGEST_LENGTH,
1539 +       0,
1540 +       pk11_digest_init,
1541 +       pk11_digest_update,
1542 +       pk11_digest_final,
1543 +       pk11_digest_copy,
1544 +       pk11_digest_cleanup,
1545 +       EVP_PKEY_RSA_method,
1546 +       SHA512_CBLOCK,
1547 +       sizeof (PK11_CIPHER_STATE),
1548 +       };
1551 + * Initialization function. Sets up various PKCS#11 library components.
1552 + * The definitions for control commands specific to this engine
1553 + */
1554 +#define PK11_CMD_SO_PATH               ENGINE_CMD_BASE
1555 +#define PK11_CMD_PIN                   (ENGINE_CMD_BASE+1)
1556 +#define PK11_CMD_SLOT                  (ENGINE_CMD_BASE+2)
1557 +static const ENGINE_CMD_DEFN pk11_cmd_defns[] =
1558 +       {
1559 +               {
1560 +               PK11_CMD_SO_PATH,
1561 +               "SO_PATH",
1562 +               "Specifies the path to the 'pkcs#11' shared library",
1563 +               ENGINE_CMD_FLAG_STRING
1564 +               },
1565 +               {
1566 +               PK11_CMD_PIN,
1567 +               "PIN",
1568 +               "Specifies the pin code",
1569 +               ENGINE_CMD_FLAG_STRING
1570 +               },
1571 +               {
1572 +               PK11_CMD_SLOT,
1573 +               "SLOT",
1574 +               "Specifies the slot (default is auto select)",
1575 +               ENGINE_CMD_FLAG_NUMERIC,
1576 +               },
1577 +               {0, NULL, NULL, 0}
1578 +       };
1581 +static RAND_METHOD pk11_random =
1582 +       {
1583 +       pk11_rand_seed,
1584 +       pk11_rand_bytes,
1585 +       pk11_rand_cleanup,
1586 +       pk11_rand_add,
1587 +       pk11_rand_bytes,
1588 +       pk11_rand_status
1589 +       };
1592 +/* Constants used when creating the ENGINE */
1593 +#ifdef OPENSSL_NO_HW_PK11SO
1594 +#error "can't load both crypto-accelerator and sign-only PKCS#11 engines"
1595 +#endif
1596 +static const char *engine_pk11_id = "pkcs11";
1597 +static const char *engine_pk11_name =
1598 +       "PKCS #11 engine support (crypto accelerator)";
1600 +CK_FUNCTION_LIST_PTR pFuncList = NULL;
1601 +static const char PK11_GET_FUNCTION_LIST[] = "C_GetFunctionList";
1604 + * These is the static string constant for the DSO file name and the function
1605 + * symbol names to bind to.
1606 + */
1607 +static const char def_PK11_LIBNAME[] = PK11_LIB_LOCATION;
1609 +static CK_BBOOL true = TRUE;
1610 +static CK_BBOOL false = FALSE;
1611 +static CK_SLOT_ID pubkey_SLOTID = 0;
1612 +static CK_SLOT_ID rand_SLOTID = 0;
1613 +static CK_SLOT_ID SLOTID = 0;
1614 +char *pk11_pin = NULL;
1615 +static CK_BBOOL pk11_library_initialized = FALSE;
1616 +static CK_BBOOL pk11_atfork_initialized = FALSE;
1617 +static int pk11_pid = 0;
1619 +static DSO *pk11_dso = NULL;
1621 +/* allocate and initialize all locks used by the engine itself */
1622 +static int pk11_init_all_locks(void)
1623 +       {
1624 +#ifndef NOPTHREADS
1625 +       int type;
1627 +#ifndef OPENSSL_NO_RSA
1628 +       find_lock[OP_RSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
1629 +       if (find_lock[OP_RSA] == NULL)
1630 +               goto malloc_err;
1631 +       (void) pthread_mutex_init(find_lock[OP_RSA], NULL);
1632 +#endif /* OPENSSL_NO_RSA */
1634 +#ifndef OPENSSL_NO_DSA
1635 +       find_lock[OP_DSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
1636 +       if (find_lock[OP_DSA] == NULL)
1637 +               goto malloc_err;
1638 +       (void) pthread_mutex_init(find_lock[OP_DSA], NULL);
1639 +#endif /* OPENSSL_NO_DSA */
1641 +#ifndef OPENSSL_NO_DH
1642 +       find_lock[OP_DH] = OPENSSL_malloc(sizeof (pthread_mutex_t));
1643 +       if (find_lock[OP_DH] == NULL)
1644 +               goto malloc_err;
1645 +       (void) pthread_mutex_init(find_lock[OP_DH], NULL);
1646 +#endif /* OPENSSL_NO_DH */
1648 +       for (type = 0; type < OP_MAX; type++)
1649 +               {
1650 +               session_cache[type].lock =
1651 +                   OPENSSL_malloc(sizeof (pthread_mutex_t));
1652 +               if (session_cache[type].lock == NULL)
1653 +                       goto malloc_err;
1654 +               (void) pthread_mutex_init(session_cache[type].lock, NULL);
1655 +               }
1657 +       return (1);
1659 +malloc_err:
1660 +       pk11_free_all_locks();
1661 +       PK11err(PK11_F_INIT_ALL_LOCKS, PK11_R_MALLOC_FAILURE);
1662 +       return (0);
1663 +#else
1664 +       return (1);
1665 +#endif
1666 +       }
1668 +static void pk11_free_all_locks(void)
1669 +       {
1670 +#ifndef NOPTHREADS
1671 +       int type;
1673 +#ifndef OPENSSL_NO_RSA
1674 +       if (find_lock[OP_RSA] != NULL)
1675 +               {
1676 +               (void) pthread_mutex_destroy(find_lock[OP_RSA]);
1677 +               OPENSSL_free(find_lock[OP_RSA]);
1678 +               find_lock[OP_RSA] = NULL;
1679 +               }
1680 +#endif /* OPENSSL_NO_RSA */
1681 +#ifndef OPENSSL_NO_DSA
1682 +       if (find_lock[OP_DSA] != NULL)
1683 +               {
1684 +               (void) pthread_mutex_destroy(find_lock[OP_DSA]);
1685 +               OPENSSL_free(find_lock[OP_DSA]);
1686 +               find_lock[OP_DSA] = NULL;
1687 +               }
1688 +#endif /* OPENSSL_NO_DSA */
1689 +#ifndef OPENSSL_NO_DH
1690 +       if (find_lock[OP_DH] != NULL)
1691 +               {
1692 +               (void) pthread_mutex_destroy(find_lock[OP_DH]);
1693 +               OPENSSL_free(find_lock[OP_DH]);
1694 +               find_lock[OP_DH] = NULL;
1695 +               }
1696 +#endif /* OPENSSL_NO_DH */
1698 +       for (type = 0; type < OP_MAX; type++)
1699 +               {
1700 +               if (session_cache[type].lock != NULL)
1701 +                       {
1702 +                       (void) pthread_mutex_destroy(session_cache[type].lock);
1703 +                       OPENSSL_free(session_cache[type].lock);
1704 +                       session_cache[type].lock = NULL;
1705 +                       }
1706 +               }
1707 +#endif
1708 +       }
1711 + * This internal function is used by ENGINE_pk11() and "dynamic" ENGINE support.
1712 + */
1713 +static int bind_pk11(ENGINE *e)
1714 +       {
1715 +#ifndef OPENSSL_NO_RSA
1716 +       const RSA_METHOD *rsa = NULL;
1717 +       RSA_METHOD *pk11_rsa = PK11_RSA();
1718 +#endif /* OPENSSL_NO_RSA */
1719 +       if (!pk11_library_initialized)
1720 +               if (!pk11_library_init(e))
1721 +                       return (0);
1723 +       if (!ENGINE_set_id(e, engine_pk11_id) ||
1724 +           !ENGINE_set_name(e, engine_pk11_name) ||
1725 +           !ENGINE_set_ciphers(e, pk11_engine_ciphers) ||
1726 +           !ENGINE_set_digests(e, pk11_engine_digests))
1727 +               return (0);
1728 +#ifndef OPENSSL_NO_RSA
1729 +       if (pk11_have_rsa == CK_TRUE)
1730 +               {
1731 +               if (!ENGINE_set_RSA(e, PK11_RSA()) ||
1732 +                   !ENGINE_set_load_privkey_function(e, pk11_load_privkey) ||
1733 +                   !ENGINE_set_load_pubkey_function(e, pk11_load_pubkey))
1734 +                       return (0);
1735 +#ifdef DEBUG_SLOT_SELECTION
1736 +               fprintf(stderr, "%s: registered RSA\n", PK11_DBG);
1737 +#endif /* DEBUG_SLOT_SELECTION */
1738 +               }
1739 +#endif /* OPENSSL_NO_RSA */
1740 +#ifndef OPENSSL_NO_DSA
1741 +       if (pk11_have_dsa == CK_TRUE)
1742 +               {
1743 +               if (!ENGINE_set_DSA(e, PK11_DSA()))
1744 +                       return (0);
1745 +#ifdef DEBUG_SLOT_SELECTION
1746 +               fprintf(stderr, "%s: registered DSA\n", PK11_DBG);
1747 +#endif /* DEBUG_SLOT_SELECTION */
1748 +               }
1749 +#endif /* OPENSSL_NO_DSA */
1750 +#ifndef OPENSSL_NO_DH
1751 +       if (pk11_have_dh == CK_TRUE)
1752 +               {
1753 +               if (!ENGINE_set_DH(e, PK11_DH()))
1754 +                       return (0);
1755 +#ifdef DEBUG_SLOT_SELECTION
1756 +               fprintf(stderr, "%s: registered DH\n", PK11_DBG);
1757 +#endif /* DEBUG_SLOT_SELECTION */
1758 +               }
1759 +#endif /* OPENSSL_NO_DH */
1760 +       if (pk11_have_random)
1761 +               {
1762 +               if (!ENGINE_set_RAND(e, &pk11_random))
1763 +                       return (0);
1764 +#ifdef DEBUG_SLOT_SELECTION
1765 +               fprintf(stderr, "%s: registered random\n", PK11_DBG);
1766 +#endif /* DEBUG_SLOT_SELECTION */
1767 +               }
1768 +       if (!ENGINE_set_init_function(e, pk11_init) ||
1769 +           !ENGINE_set_destroy_function(e, pk11_destroy) ||
1770 +           !ENGINE_set_finish_function(e, pk11_finish) ||
1771 +           !ENGINE_set_ctrl_function(e, pk11_ctrl) ||
1772 +           !ENGINE_set_cmd_defns(e, pk11_cmd_defns))
1773 +               return (0);
1776 + * Apache calls OpenSSL function RSA_blinding_on() once during startup
1777 + * which in turn calls bn_mod_exp. Since we do not implement bn_mod_exp
1778 + * here, we wire it back to the OpenSSL software implementation.
1779 + * Since it is used only once, performance is not a concern.
1780 + */
1781 +#ifndef OPENSSL_NO_RSA
1782 +       rsa = RSA_PKCS1_SSLeay();
1783 +       pk11_rsa->rsa_mod_exp = rsa->rsa_mod_exp;
1784 +       pk11_rsa->bn_mod_exp = rsa->bn_mod_exp;
1785 +       if (pk11_have_recover != CK_TRUE)
1786 +               pk11_rsa->rsa_pub_dec = rsa->rsa_pub_dec;
1787 +#endif /* OPENSSL_NO_RSA */
1789 +       /* Ensure the pk11 error handling is set up */
1790 +       ERR_load_pk11_strings();
1792 +       return (1);
1793 +       }
1795 +/* Dynamic engine support is disabled at a higher level for Solaris */
1796 +#ifdef ENGINE_DYNAMIC_SUPPORT
1797 +#error  "dynamic engine not supported"
1798 +static int bind_helper(ENGINE *e, const char *id)
1799 +       {
1800 +       if (id && (strcmp(id, engine_pk11_id) != 0))
1801 +               return (0);
1803 +       if (!bind_pk11(e))
1804 +               return (0);
1806 +       return (1);
1807 +       }
1809 +IMPLEMENT_DYNAMIC_CHECK_FN()
1810 +IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
1812 +#else
1813 +static ENGINE *engine_pk11(void)
1814 +       {
1815 +       ENGINE *ret = ENGINE_new();
1817 +       if (!ret)
1818 +               return (NULL);
1820 +       if (!bind_pk11(ret))
1821 +               {
1822 +               ENGINE_free(ret);
1823 +               return (NULL);
1824 +               }
1826 +       return (ret);
1827 +       }
1829 +void
1830 +ENGINE_load_pk11(void)
1831 +       {
1832 +       ENGINE *e_pk11 = NULL;
1834 +       /*
1835 +        * Do not use dynamic PKCS#11 library on Solaris due to
1836 +        * security reasons. We will link it in statically.
1837 +        */
1838 +       /* Attempt to load PKCS#11 library */
1839 +       if (!pk11_dso)
1840 +               pk11_dso = DSO_load(NULL, get_PK11_LIBNAME(), NULL, 0);
1842 +       if (pk11_dso == NULL)
1843 +               {
1844 +               PK11err(PK11_F_LOAD, PK11_R_DSO_FAILURE);
1845 +               return;
1846 +               }
1848 +       e_pk11 = engine_pk11();
1849 +       if (!e_pk11)
1850 +               {
1851 +               DSO_free(pk11_dso);
1852 +               pk11_dso = NULL;
1853 +               return;
1854 +               }
1856 +       /*
1857 +        * At this point, the pk11 shared library is either dynamically
1858 +        * loaded or statically linked in. So, initialize the pk11
1859 +        * library before calling ENGINE_set_default since the latter
1860 +        * needs cipher and digest algorithm information
1861 +        */
1862 +       if (!pk11_library_init(e_pk11))
1863 +               {
1864 +               DSO_free(pk11_dso);
1865 +               pk11_dso = NULL;
1866 +               ENGINE_free(e_pk11);
1867 +               return;
1868 +               }
1870 +       ENGINE_add(e_pk11);
1872 +       ENGINE_free(e_pk11);
1873 +       ERR_clear_error();
1874 +       }
1875 +#endif /* ENGINE_DYNAMIC_SUPPORT */
1878 + * These are the static string constants for the DSO file name and
1879 + * the function symbol names to bind to.
1880 + */
1881 +static const char *PK11_LIBNAME = NULL;
1883 +static const char *get_PK11_LIBNAME(void)
1884 +       {
1885 +       if (PK11_LIBNAME)
1886 +               return (PK11_LIBNAME);
1888 +       return (def_PK11_LIBNAME);
1889 +       }
1891 +static void free_PK11_LIBNAME(void)
1892 +       {
1893 +       if (PK11_LIBNAME)
1894 +               OPENSSL_free((void*)PK11_LIBNAME);
1896 +       PK11_LIBNAME = NULL;
1897 +       }
1899 +static long set_PK11_LIBNAME(const char *name)
1900 +       {
1901 +       free_PK11_LIBNAME();
1903 +       return ((PK11_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
1904 +       }
1906 +/* acquire all engine specific mutexes before fork */
1907 +static void pk11_fork_prepare(void)
1908 +       {
1909 +#ifndef NOPTHREADS
1910 +       int i;
1912 +       if (!pk11_library_initialized)
1913 +               return;
1915 +       LOCK_OBJSTORE(OP_RSA);
1916 +       LOCK_OBJSTORE(OP_DSA);
1917 +       LOCK_OBJSTORE(OP_DH);
1918 +       for (i = 0; i < OP_MAX; i++)
1919 +               {
1920 +               (void) pthread_mutex_lock(session_cache[i].lock);
1921 +               }
1922 +#endif
1923 +       }
1925 +/* release all engine specific mutexes */
1926 +static void pk11_fork_parent(void)
1927 +       {
1928 +#ifndef NOPTHREADS
1929 +       int i;
1931 +       if (!pk11_library_initialized)
1932 +               return;
1934 +       for (i = OP_MAX - 1; i >= 0; i--)
1935 +               {
1936 +               (void) pthread_mutex_unlock(session_cache[i].lock);
1937 +               }
1938 +       UNLOCK_OBJSTORE(OP_DH);
1939 +       UNLOCK_OBJSTORE(OP_DSA);
1940 +       UNLOCK_OBJSTORE(OP_RSA);
1941 +#endif
1942 +       }
1945 + * same situation as in parent - we need to unlock all locks to make them
1946 + * accessible to all threads.
1947 + */
1948 +static void pk11_fork_child(void)
1949 +       {
1950 +#ifndef NOPTHREADS
1951 +       int i;
1953 +       if (!pk11_library_initialized)
1954 +               return;
1956 +       for (i = OP_MAX - 1; i >= 0; i--)
1957 +               {
1958 +               (void) pthread_mutex_unlock(session_cache[i].lock);
1959 +               }
1960 +       UNLOCK_OBJSTORE(OP_DH);
1961 +       UNLOCK_OBJSTORE(OP_DSA);
1962 +       UNLOCK_OBJSTORE(OP_RSA);
1963 +#endif
1964 +       }
1966 +/* Initialization function for the pk11 engine */
1967 +static int pk11_init(ENGINE *e)
1969 +       return (pk11_library_init(e));
1973 + * Initialization function. Sets up various PKCS#11 library components.
1974 + * It selects a slot based on predefined critiera. In the process, it also
1975 + * count how many ciphers and digests to support. Since the cipher and
1976 + * digest information is needed when setting default engine, this function
1977 + * needs to be called before calling ENGINE_set_default.
1978 + */
1979 +/* ARGSUSED */
1980 +static int pk11_library_init(ENGINE *e)
1981 +       {
1982 +       CK_C_GetFunctionList p;
1983 +       CK_RV rv = CKR_OK;
1984 +       CK_INFO info;
1985 +       CK_ULONG ul_state_len;
1986 +       int any_slot_found;
1987 +       int i;
1988 +#ifndef OPENSSL_SYS_WIN32
1989 +       struct sigaction sigint_act, sigterm_act, sighup_act;
1990 +#endif
1992 +       /*
1993 +        * pk11_library_initialized is set to 0 in pk11_finish() which is called
1994 +        * from ENGINE_finish(). However, if there is still at least one
1995 +        * existing functional reference to the engine (see engine(3) for more
1996 +        * information), pk11_finish() is skipped. For example, this can happen
1997 +        * if an application forgets to clear one cipher context. In case of a
1998 +        * fork() when the application is finishing the engine so that it can be
1999 +        * reinitialized in the child, forgotten functional reference causes
2000 +        * pk11_library_initialized to stay 1. In that case we need the PID
2001 +        * check so that we properly initialize the engine again.
2002 +        */
2003 +       if (pk11_library_initialized)
2004 +               {
2005 +               if (pk11_pid == getpid())
2006 +                       {
2007 +                       return (1);
2008 +                       }
2009 +               else
2010 +                       {
2011 +                       global_session = CK_INVALID_HANDLE;
2012 +                       /*
2013 +                        * free the locks first to prevent memory leak in case
2014 +                        * the application calls fork() without finishing the
2015 +                        * engine first.
2016 +                        */
2017 +                       pk11_free_all_locks();
2018 +                       }
2019 +               }
2021 +       if (pk11_dso == NULL)
2022 +               {
2023 +               PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
2024 +               goto err;
2025 +               }
2027 +#ifdef SOLARIS_AES_CTR
2028 +       /*
2029 +        * We must do this before we start working with slots since we need all
2030 +        * NIDs there.
2031 +        */
2032 +       if (pk11_add_aes_ctr_NIDs() == 0)
2033 +               goto err;
2034 +#endif /* SOLARIS_AES_CTR */
2036 +#ifdef SOLARIS_HW_SLOT_SELECTION
2037 +       if (check_hw_mechanisms() == 0)
2038 +               goto err;
2039 +#endif /* SOLARIS_HW_SLOT_SELECTION */
2041 +       /* get the C_GetFunctionList function from the loaded library */
2042 +       p = (CK_C_GetFunctionList)DSO_bind_func(pk11_dso,
2043 +               PK11_GET_FUNCTION_LIST);
2044 +       if (!p)
2045 +               {
2046 +               PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
2047 +               goto err;
2048 +               }
2050 +       /* get the full function list from the loaded library */
2051 +       rv = p(&pFuncList);
2052 +       if (rv != CKR_OK)
2053 +               {
2054 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE, rv);
2055 +               goto err;
2056 +               }
2058 +#ifndef OPENSSL_SYS_WIN32
2059 +       /* Not all PKCS#11 library are signal safe! */
2061 +       (void) memset(&sigint_act, 0, sizeof(sigint_act));
2062 +       (void) memset(&sigterm_act, 0, sizeof(sigterm_act));
2063 +       (void) memset(&sighup_act, 0, sizeof(sighup_act));
2064 +       (void) sigaction(SIGINT, NULL, &sigint_act);
2065 +       (void) sigaction(SIGTERM, NULL, &sigterm_act);
2066 +       (void) sigaction(SIGHUP, NULL, &sighup_act);
2067 +#endif
2068 +       rv = pFuncList->C_Initialize(NULL_PTR);
2069 +#ifndef OPENSSL_SYS_WIN32
2070 +       (void) sigaction(SIGINT, &sigint_act, NULL);
2071 +       (void) sigaction(SIGTERM, &sigterm_act, NULL);
2072 +       (void) sigaction(SIGHUP, &sighup_act, NULL);
2073 +#endif
2074 +       if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
2075 +               {
2076 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_INITIALIZE, rv);
2077 +               goto err;
2078 +               }
2080 +       rv = pFuncList->C_GetInfo(&info);
2081 +       if (rv != CKR_OK)
2082 +               {
2083 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_GETINFO, rv);
2084 +               goto err;
2085 +               }
2087 +       if (pk11_choose_slots(&any_slot_found) == 0)
2088 +               goto err;
2090 +       /*
2091 +        * The library we use, set in def_PK11_LIBNAME, may not offer any
2092 +        * slot(s). In that case, we must not proceed but we must not return an
2093 +        * error. The reason is that applications that try to set up the PKCS#11
2094 +        * engine don't exit on error during the engine initialization just
2095 +        * because no slot was present.
2096 +        */
2097 +       if (any_slot_found == 0)
2098 +               return (1);
2100 +       if (global_session == CK_INVALID_HANDLE)
2101 +               {
2102 +               /* Open the global_session for the new process */
2103 +               rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
2104 +                       NULL_PTR, NULL_PTR, &global_session);
2105 +               if (rv != CKR_OK)
2106 +                       {
2107 +                       PK11err_add_data(PK11_F_LIBRARY_INIT,
2108 +                           PK11_R_OPENSESSION, rv);
2109 +                       goto err;
2110 +                       }
2111 +               }
2113 +       /*
2114 +        * Disable digest if C_GetOperationState is not supported since
2115 +        * this function is required by OpenSSL digest copy function
2116 +        */
2117 +       /* Keyper fails to return CKR_FUNCTION_NOT_SUPPORTED */
2118 +       if (pFuncList->C_GetOperationState(global_session, NULL, &ul_state_len)
2119 +                       != CKR_OK) {
2120 +#ifdef DEBUG_SLOT_SELECTION
2121 +               fprintf(stderr, "%s: C_GetOperationState() not supported, "
2122 +                   "setting digest_count to 0\n", PK11_DBG);
2123 +#endif /* DEBUG_SLOT_SELECTION */
2124 +               digest_count = 0;
2125 +       }
2127 +       pk11_library_initialized = TRUE;
2128 +       pk11_pid = getpid();
2129 +       /*
2130 +        * if initialization of the locks fails pk11_init_all_locks()
2131 +        * will do the cleanup.
2132 +        */
2133 +       if (!pk11_init_all_locks())
2134 +               goto err;
2135 +       for (i = 0; i < OP_MAX; i++)
2136 +               session_cache[i].head = NULL;
2137 +       /*
2138 +        * initialize active lists. We only use active lists
2139 +        * for asymmetric ciphers.
2140 +        */
2141 +       for (i = 0; i < OP_MAX; i++)
2142 +               active_list[i] = NULL;
2144 +#ifndef NOPTHREADS
2145 +       if (!pk11_atfork_initialized)
2146 +               {
2147 +               if (pthread_atfork(pk11_fork_prepare, pk11_fork_parent,
2148 +                   pk11_fork_child) != 0)
2149 +                       {
2150 +                       PK11err(PK11_F_LIBRARY_INIT, PK11_R_ATFORK_FAILED);
2151 +                       goto err;
2152 +                       }
2153 +               pk11_atfork_initialized = TRUE;
2154 +               }
2155 +#endif
2157 +       return (1);
2159 +err:
2160 +       return (0);
2161 +       }
2163 +/* Destructor (complements the "ENGINE_pk11()" constructor) */
2164 +/* ARGSUSED */
2165 +static int pk11_destroy(ENGINE *e)
2166 +       {
2167 +       free_PK11_LIBNAME();
2168 +       ERR_unload_pk11_strings();
2169 +       if (pk11_pin) {
2170 +               memset(pk11_pin, 0, strlen(pk11_pin));
2171 +               OPENSSL_free((void*)pk11_pin);
2172 +       }
2173 +       pk11_pin = NULL;
2174 +       return (1);
2175 +       }
2178 + * Termination function to clean up the session, the token, and the pk11
2179 + * library.
2180 + */
2181 +/* ARGSUSED */
2182 +static int pk11_finish(ENGINE *e)
2183 +       {
2184 +       int i;
2186 +       if (pk11_pin) {
2187 +               memset(pk11_pin, 0, strlen(pk11_pin));
2188 +               OPENSSL_free((void*)pk11_pin);
2189 +       }
2190 +       pk11_pin = NULL;
2192 +       if (pk11_dso == NULL)
2193 +               {
2194 +               PK11err(PK11_F_FINISH, PK11_R_NOT_LOADED);
2195 +               goto err;
2196 +               }
2198 +       OPENSSL_assert(pFuncList != NULL);
2200 +       if (pk11_free_all_sessions() == 0)
2201 +               goto err;
2203 +       /* free all active lists */
2204 +       for (i = 0; i < OP_MAX; i++)
2205 +               pk11_free_active_list(i);
2207 +       pFuncList->C_CloseSession(global_session);
2208 +       global_session = CK_INVALID_HANDLE;
2210 +       /*
2211 +        * Since we are part of a library (libcrypto.so), calling this function
2212 +        * may have side-effects.
2213 +        */
2214 +#if 0
2215 +       pFuncList->C_Finalize(NULL);
2216 +#endif
2218 +       if (!DSO_free(pk11_dso))
2219 +               {
2220 +               PK11err(PK11_F_FINISH, PK11_R_DSO_FAILURE);
2221 +               goto err;
2222 +               }
2223 +       pk11_dso = NULL;
2224 +       pFuncList = NULL;
2225 +       pk11_library_initialized = FALSE;
2226 +       pk11_pid = 0;
2227 +       /*
2228 +        * There is no way how to unregister atfork handlers (other than
2229 +        * unloading the library) so we just free the locks. For this reason
2230 +        * the atfork handlers check if the engine is initialized and bail out
2231 +        * immediately if not. This is necessary in case a process finishes
2232 +        * the engine before calling fork().
2233 +        */
2234 +       pk11_free_all_locks();
2236 +       return (1);
2238 +err:
2239 +       return (0);
2240 +       }
2242 +/* Standard engine interface function to set the dynamic library path */
2243 +/* ARGSUSED */
2244 +static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
2245 +       {
2246 +       int initialized = ((pk11_dso == NULL) ? 0 : 1);
2248 +       switch (cmd)
2249 +               {
2250 +       case PK11_CMD_SO_PATH:
2251 +               if (p == NULL)
2252 +                       {
2253 +                       PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
2254 +                       return (0);
2255 +                       }
2257 +               if (initialized)
2258 +                       {
2259 +                       PK11err(PK11_F_CTRL, PK11_R_ALREADY_LOADED);
2260 +                       return (0);
2261 +                       }
2263 +               return (set_PK11_LIBNAME((const char *)p));
2264 +       case PK11_CMD_PIN:
2265 +               if (pk11_pin) {
2266 +                       memset(pk11_pin, 0, strlen(pk11_pin));
2267 +                       OPENSSL_free((void*)pk11_pin);
2268 +               }
2269 +               pk11_pin = NULL;
2271 +               if (p == NULL)
2272 +                       {
2273 +                       PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
2274 +                       return (0);
2275 +                       }
2277 +               pk11_pin = BUF_strdup(p);
2278 +               if (pk11_pin == NULL)
2279 +                       {
2280 +                       PK11err(PK11_F_GET_SESSION, PK11_R_MALLOC_FAILURE);
2281 +                       return (0);
2282 +                       }
2283 +               return (1);
2284 +       case PK11_CMD_SLOT:
2285 +               SLOTID = (CK_SLOT_ID)i;
2286 +#ifdef DEBUG_SLOT_SELECTION
2287 +               fprintf(stderr, "%s: slot set\n", PK11_DBG);
2288 +#endif
2289 +               return (1);
2290 +       default:
2291 +               break;
2292 +               }
2294 +       PK11err(PK11_F_CTRL, PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED);
2296 +       return (0);
2297 +       }
2300 +/* Required function by the engine random interface. It does nothing here */
2301 +static void pk11_rand_cleanup(void)
2302 +       {
2303 +       return;
2304 +       }
2306 +/* ARGSUSED */
2307 +static void pk11_rand_add(const void *buf, int num, double add)
2308 +       {
2309 +       PK11_SESSION *sp;
2311 +       if ((sp = pk11_get_session(OP_RAND)) == NULL)
2312 +               return;
2314 +       /*
2315 +        * Ignore any errors (e.g. CKR_RANDOM_SEED_NOT_SUPPORTED) since
2316 +        * the calling functions do not care anyway
2317 +        */
2318 +       pFuncList->C_SeedRandom(sp->session, (unsigned char *) buf, num);
2319 +       pk11_return_session(sp, OP_RAND);
2321 +       return;
2322 +       }
2324 +static void pk11_rand_seed(const void *buf, int num)
2325 +       {
2326 +       pk11_rand_add(buf, num, 0);
2327 +       }
2329 +static int pk11_rand_bytes(unsigned char *buf, int num)
2330 +       {
2331 +       CK_RV rv;
2332 +       PK11_SESSION *sp;
2334 +       if ((sp = pk11_get_session(OP_RAND)) == NULL)
2335 +               return (0);
2337 +       rv = pFuncList->C_GenerateRandom(sp->session, buf, num);
2338 +       if (rv != CKR_OK)
2339 +               {
2340 +               PK11err_add_data(PK11_F_RAND_BYTES, PK11_R_GENERATERANDOM, rv);
2341 +               pk11_return_session(sp, OP_RAND);
2342 +               return (0);
2343 +               }
2345 +       pk11_return_session(sp, OP_RAND);
2346 +       return (1);
2347 +       }
2349 +/* Required function by the engine random interface. It does nothing here */
2350 +static int pk11_rand_status(void)
2351 +       {
2352 +       return (1);
2353 +       }
2355 +/* Free all BIGNUM structures from PK11_SESSION. */
2356 +static void pk11_free_nums(PK11_SESSION *sp, PK11_OPTYPE optype)
2357 +       {
2358 +       switch (optype)
2359 +               {
2360 +#ifndef        OPENSSL_NO_RSA
2361 +               case OP_RSA:
2362 +                       if (sp->opdata_rsa_n_num != NULL)
2363 +                               {
2364 +                               BN_free(sp->opdata_rsa_n_num);
2365 +                               sp->opdata_rsa_n_num = NULL;
2366 +                               }
2367 +                       if (sp->opdata_rsa_e_num != NULL)
2368 +                               {
2369 +                               BN_free(sp->opdata_rsa_e_num);
2370 +                               sp->opdata_rsa_e_num = NULL;
2371 +                               }
2372 +                       if (sp->opdata_rsa_d_num != NULL)
2373 +                               {
2374 +                               BN_free(sp->opdata_rsa_d_num);
2375 +                               sp->opdata_rsa_d_num = NULL;
2376 +                               }
2377 +                       break;
2378 +#endif
2379 +#ifndef        OPENSSL_NO_DSA
2380 +               case OP_DSA:
2381 +                       if (sp->opdata_dsa_pub_num != NULL)
2382 +                               {
2383 +                               BN_free(sp->opdata_dsa_pub_num);
2384 +                               sp->opdata_dsa_pub_num = NULL;
2385 +                               }
2386 +                       if (sp->opdata_dsa_priv_num != NULL)
2387 +                               {
2388 +                               BN_free(sp->opdata_dsa_priv_num);
2389 +                               sp->opdata_dsa_priv_num = NULL;
2390 +                               }
2391 +                       break;
2392 +#endif
2393 +#ifndef        OPENSSL_NO_DH
2394 +               case OP_DH:
2395 +                       if (sp->opdata_dh_priv_num != NULL)
2396 +                               {
2397 +                               BN_free(sp->opdata_dh_priv_num);
2398 +                               sp->opdata_dh_priv_num = NULL;
2399 +                               }
2400 +                       break;
2401 +#endif
2402 +               default:
2403 +                       break;
2404 +               }
2405 +       }
2408 + * Get new PK11_SESSION structure ready for use. Every process must have
2409 + * its own freelist of PK11_SESSION structures so handle fork() here
2410 + * by destroying the old and creating new freelist.
2411 + * The returned PK11_SESSION structure is disconnected from the freelist.
2412 + */
2413 +PK11_SESSION *
2414 +pk11_get_session(PK11_OPTYPE optype)
2415 +       {
2416 +       PK11_SESSION *sp = NULL, *sp1, *freelist;
2417 +#ifndef NOPTHREADS
2418 +       pthread_mutex_t *freelist_lock = NULL;
2419 +#endif
2420 +       CK_RV rv;
2422 +       switch (optype)
2423 +               {
2424 +               case OP_RSA:
2425 +               case OP_DSA:
2426 +               case OP_DH:
2427 +               case OP_RAND:
2428 +               case OP_DIGEST:
2429 +               case OP_CIPHER:
2430 +#ifndef NOPTHREADS
2431 +                       freelist_lock = session_cache[optype].lock;
2432 +#endif
2433 +                       break;
2434 +               default:
2435 +                       PK11err(PK11_F_GET_SESSION,
2436 +                               PK11_R_INVALID_OPERATION_TYPE);
2437 +                       return (NULL);
2438 +               }
2439 +#ifndef NOPTHREADS
2440 +       (void) pthread_mutex_lock(freelist_lock);
2441 +#else
2442 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
2443 +#endif
2444 +       freelist = session_cache[optype].head;
2445 +       sp = freelist;
2447 +       /*
2448 +        * If the free list is empty, allocate new unitialized (filled
2449 +        * with zeroes) PK11_SESSION structure otherwise return first
2450 +        * structure from the freelist.
2451 +        */
2452 +       if (sp == NULL)
2453 +               {
2454 +               if ((sp = OPENSSL_malloc(sizeof (PK11_SESSION))) == NULL)
2455 +                       {
2456 +                       PK11err(PK11_F_GET_SESSION,
2457 +                               PK11_R_MALLOC_FAILURE);
2458 +                       goto err;
2459 +                       }
2460 +               (void) memset(sp, 0, sizeof (PK11_SESSION));
2461 +               }
2462 +       else
2463 +               {
2464 +               freelist = sp->next;
2465 +               }
2467 +       if (sp->pid != 0 && sp->pid != getpid())
2468 +               {
2469 +               /*
2470 +                * We are a new process and thus need to free any inherited
2471 +                * PK11_SESSION objects.
2472 +                */
2473 +               while ((sp1 = freelist) != NULL)
2474 +                       {
2475 +                       freelist = sp1->next;
2476 +                       /*
2477 +                        * NOTE: we do not want to call pk11_free_all_sessions()
2478 +                        * here because it would close underlying PKCS#11
2479 +                        * sessions and destroy all objects.
2480 +                        */
2481 +                       pk11_free_nums(sp1, optype);
2482 +                       OPENSSL_free(sp1);
2483 +                       }
2485 +               /* we have to free the active list as well. */
2486 +               pk11_free_active_list(optype);
2488 +               /* Initialize the process */
2489 +               rv = pFuncList->C_Initialize(NULL_PTR);
2490 +               if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
2491 +                       {
2492 +                       PK11err_add_data(PK11_F_GET_SESSION, PK11_R_INITIALIZE,
2493 +                           rv);
2494 +                       OPENSSL_free(sp);
2495 +                       sp = NULL;
2496 +                       goto err;
2497 +                       }
2499 +               /*
2500 +                * Choose slot here since the slot table is different on this
2501 +                * process. If we are here then we must have found at least one
2502 +                * usable slot before so we don't need to check any_slot_found.
2503 +                * See pk11_library_init()'s usage of this function for more
2504 +                * information.
2505 +                */
2506 +#ifdef SOLARIS_HW_SLOT_SELECTION
2507 +               if (check_hw_mechanisms() == 0)
2508 +                       goto err;
2509 +#endif /* SOLARIS_HW_SLOT_SELECTION */
2510 +               if (pk11_choose_slots(NULL) == 0)
2511 +                       goto err;
2513 +               /* Open the global_session for the new process */
2514 +               rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
2515 +                       NULL_PTR, NULL_PTR, &global_session);
2516 +               if (rv != CKR_OK)
2517 +                       {
2518 +                       PK11err_add_data(PK11_F_GET_SESSION, PK11_R_OPENSESSION,
2519 +                           rv);
2520 +                       OPENSSL_free(sp);
2521 +                       sp = NULL;
2522 +                       goto err;
2523 +                       }
2525 +               /* It is an inherited session and needs re-initialization. */
2526 +               if (pk11_setup_session(sp, optype) == 0)
2527 +                       {
2528 +                       OPENSSL_free(sp);
2529 +                       sp = NULL;
2530 +                       }
2531 +               }
2532 +       if (sp->pid == 0)
2533 +               {
2534 +               /* It is a new session and needs initialization. */
2535 +               if (pk11_setup_session(sp, optype) == 0)
2536 +                       {
2537 +                       OPENSSL_free(sp);
2538 +                       sp = NULL;
2539 +                       }
2540 +               }
2542 +       /* set new head for the list of PK11_SESSION objects */
2543 +       session_cache[optype].head = freelist;
2545 +err:
2546 +       if (sp != NULL)
2547 +               sp->next = NULL;
2549 +#ifndef NOPTHREADS
2550 +       (void) pthread_mutex_unlock(freelist_lock);
2551 +#else
2552 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
2553 +#endif
2555 +       return (sp);
2556 +       }
2559 +void
2560 +pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype)
2561 +       {
2562 +#ifndef NOPTHREADS
2563 +       pthread_mutex_t *freelist_lock;
2564 +#endif
2565 +       PK11_SESSION *freelist;
2567 +       if (sp == NULL || sp->pid != getpid())
2568 +               return;
2570 +       switch (optype)
2571 +               {
2572 +               case OP_RSA:
2573 +               case OP_DSA:
2574 +               case OP_DH:
2575 +               case OP_RAND:
2576 +               case OP_DIGEST:
2577 +               case OP_CIPHER:
2578 +#ifndef NOPTHREADS
2579 +                       freelist_lock = session_cache[optype].lock;
2580 +#endif
2581 +                       break;
2582 +               default:
2583 +                       PK11err(PK11_F_RETURN_SESSION,
2584 +                               PK11_R_INVALID_OPERATION_TYPE);
2585 +                       return;
2586 +               }
2588 +#ifndef NOPTHREADS
2589 +       (void) pthread_mutex_lock(freelist_lock);
2590 +#else
2591 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
2592 +#endif
2593 +       freelist = session_cache[optype].head;
2594 +       sp->next = freelist;
2595 +       session_cache[optype].head = sp;
2596 +#ifndef NOPTHREADS
2597 +       (void) pthread_mutex_unlock(freelist_lock);
2598 +#else
2599 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
2600 +#endif
2601 +       }
2604 +/* Destroy all objects. This function is called when the engine is finished */
2605 +static int pk11_free_all_sessions()
2606 +       {
2607 +       int ret = 1;
2608 +       int type;
2610 +#ifndef OPENSSL_NO_RSA
2611 +       (void) pk11_destroy_rsa_key_objects(NULL);
2612 +#endif /* OPENSSL_NO_RSA */
2613 +#ifndef OPENSSL_NO_DSA
2614 +       (void) pk11_destroy_dsa_key_objects(NULL);
2615 +#endif /* OPENSSL_NO_DSA */
2616 +#ifndef OPENSSL_NO_DH
2617 +       (void) pk11_destroy_dh_key_objects(NULL);
2618 +#endif /* OPENSSL_NO_DH */
2619 +       (void) pk11_destroy_cipher_key_objects(NULL);
2621 +       /*
2622 +        * We try to release as much as we can but any error means that we will
2623 +        * return 0 on exit.
2624 +        */
2625 +       for (type = 0; type < OP_MAX; type++)
2626 +               {
2627 +               if (pk11_free_session_list(type) == 0)
2628 +                       ret = 0;
2629 +               }
2631 +       return (ret);
2632 +       }
2635 + * Destroy session structures from the linked list specified. Free as many
2636 + * sessions as possible but any failure in C_CloseSession() means that we
2637 + * return an error on return.
2638 + */
2639 +static int pk11_free_session_list(PK11_OPTYPE optype)
2640 +       {
2641 +       CK_RV rv;
2642 +       PK11_SESSION *sp = NULL;
2643 +       PK11_SESSION *freelist = NULL;
2644 +       pid_t mypid = getpid();
2645 +#ifndef NOPTHREADS
2646 +       pthread_mutex_t *freelist_lock;
2647 +#endif
2648 +       int ret = 1;
2650 +       switch (optype)
2651 +               {
2652 +               case OP_RSA:
2653 +               case OP_DSA:
2654 +               case OP_DH:
2655 +               case OP_RAND:
2656 +               case OP_DIGEST:
2657 +               case OP_CIPHER:
2658 +#ifndef NOPTHREADS
2659 +                       freelist_lock = session_cache[optype].lock;
2660 +#endif
2661 +                       break;
2662 +               default:
2663 +                       PK11err(PK11_F_FREE_ALL_SESSIONS,
2664 +                               PK11_R_INVALID_OPERATION_TYPE);
2665 +                       return (0);
2666 +               }
2668 +#ifndef NOPTHREADS
2669 +       (void) pthread_mutex_lock(freelist_lock);
2670 +#else
2671 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
2672 +#endif
2673 +       freelist = session_cache[optype].head;
2674 +       while ((sp = freelist) != NULL)
2675 +               {
2676 +               if (sp->session != CK_INVALID_HANDLE && sp->pid == mypid)
2677 +                       {
2678 +                       rv = pFuncList->C_CloseSession(sp->session);
2679 +                       if (rv != CKR_OK)
2680 +                               {
2681 +                               PK11err_add_data(PK11_F_FREE_ALL_SESSIONS,
2682 +                                       PK11_R_CLOSESESSION, rv);
2683 +                               ret = 0;
2684 +                               }
2685 +                       }
2686 +               freelist = sp->next;
2687 +               pk11_free_nums(sp, optype);
2688 +               OPENSSL_free(sp);
2689 +               }
2691 +#ifndef NOPTHREADS
2692 +       (void) pthread_mutex_unlock(freelist_lock);
2693 +#else
2694 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
2695 +#endif
2696 +       return (ret);
2697 +       }
2700 +static int pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype)
2701 +       {
2702 +       CK_RV rv;
2703 +       CK_SLOT_ID myslot;
2705 +       switch (optype)
2706 +               {
2707 +               case OP_RSA:
2708 +               case OP_DSA:
2709 +               case OP_DH:
2710 +                       myslot = pubkey_SLOTID;
2711 +                       break;
2712 +               case OP_RAND:
2713 +                       myslot = rand_SLOTID;
2714 +                       break;
2715 +               case OP_DIGEST:
2716 +               case OP_CIPHER:
2717 +                       myslot = SLOTID;
2718 +                       break;
2719 +               default:
2720 +                       PK11err(PK11_F_SETUP_SESSION,
2721 +                           PK11_R_INVALID_OPERATION_TYPE);
2722 +                       return (0);
2723 +               }
2725 +       sp->session = CK_INVALID_HANDLE;
2726 +#ifdef DEBUG_SLOT_SELECTION
2727 +       fprintf(stderr, "%s: myslot=%d optype=%d\n", PK11_DBG, myslot, optype);
2728 +#endif /* DEBUG_SLOT_SELECTION */
2729 +       rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
2730 +               NULL_PTR, NULL_PTR, &sp->session);
2731 +       if (rv == CKR_CRYPTOKI_NOT_INITIALIZED)
2732 +               {
2733 +               /*
2734 +                * We are probably a child process so force the
2735 +                * reinitialize of the session
2736 +                */
2737 +               pk11_library_initialized = FALSE;
2738 +               if (!pk11_library_init(NULL))
2739 +                       return (0);
2740 +               rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
2741 +                       NULL_PTR, NULL_PTR, &sp->session);
2742 +               }
2743 +       if (rv != CKR_OK)
2744 +               {
2745 +               PK11err_add_data(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION, rv);
2746 +               return (0);
2747 +               }
2749 +       sp->pid = getpid();
2751 +       switch (optype)
2752 +               {
2753 +#ifndef OPENSSL_NO_RSA
2754 +               case OP_RSA:
2755 +                       sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
2756 +                       sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
2757 +                       sp->opdata_rsa_pub = NULL;
2758 +                       sp->opdata_rsa_n_num = NULL;
2759 +                       sp->opdata_rsa_e_num = NULL;
2760 +                       sp->opdata_rsa_priv = NULL;
2761 +                       sp->opdata_rsa_d_num = NULL;
2762 +                       break;
2763 +#endif /* OPENSSL_NO_RSA */
2764 +#ifndef OPENSSL_NO_DSA
2765 +               case OP_DSA:
2766 +                       sp->opdata_dsa_pub_key = CK_INVALID_HANDLE;
2767 +                       sp->opdata_dsa_priv_key = CK_INVALID_HANDLE;
2768 +                       sp->opdata_dsa_pub = NULL;
2769 +                       sp->opdata_dsa_pub_num = NULL;
2770 +                       sp->opdata_dsa_priv = NULL;
2771 +                       sp->opdata_dsa_priv_num = NULL;
2772 +                       break;
2773 +#endif /* OPENSSL_NO_DSA */
2774 +#ifndef OPENSSL_NO_DH
2775 +               case OP_DH:
2776 +                       sp->opdata_dh_key = CK_INVALID_HANDLE;
2777 +                       sp->opdata_dh = NULL;
2778 +                       sp->opdata_dh_priv_num = NULL;
2779 +                       break;
2780 +#endif /* OPENSSL_NO_DH */
2781 +               case OP_CIPHER:
2782 +                       sp->opdata_cipher_key = CK_INVALID_HANDLE;
2783 +                       sp->opdata_encrypt = -1;
2784 +                       break;
2785 +               default:
2786 +                       break;
2787 +               }
2789 +       return (1);
2790 +       }
2792 +#ifndef OPENSSL_NO_RSA
2793 +/* Destroy RSA public key from single session. */
2794 +int
2795 +pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
2796 +       {
2797 +       int ret = 0;
2799 +       if (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE)
2800 +               {
2801 +               TRY_OBJ_DESTROY(sp->session, sp->opdata_rsa_pub_key,
2802 +                   ret, uselock, OP_RSA);
2803 +               sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
2804 +               sp->opdata_rsa_pub = NULL;
2805 +               if (sp->opdata_rsa_n_num != NULL)
2806 +                       {
2807 +                       BN_free(sp->opdata_rsa_n_num);
2808 +                       sp->opdata_rsa_n_num = NULL;
2809 +                       }
2810 +               if (sp->opdata_rsa_e_num != NULL)
2811 +                       {
2812 +                       BN_free(sp->opdata_rsa_e_num);
2813 +                       sp->opdata_rsa_e_num = NULL;
2814 +                       }
2815 +               }
2817 +       return (ret);
2818 +       }
2820 +/* Destroy RSA private key from single session. */
2821 +int
2822 +pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
2823 +       {
2824 +       int ret = 0;
2826 +       if (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE)
2827 +               {
2828 +               if ((sp->opdata_rsa_priv->flags & RSA_FLAG_EXT_PKEY) != 0)
2829 +                       {
2830 +                       TRY_OBJ_DELETE(sp->session,
2831 +                                      sp->opdata_rsa_priv_key,
2832 +                                      ret, uselock, OP_RSA);
2833 +                       }
2834 +               else
2835 +                       {
2836 +                       TRY_OBJ_DESTROY(sp->session,
2837 +                                       sp->opdata_rsa_priv_key,
2838 +                                       ret, uselock, OP_RSA);
2839 +                       }
2840 +               sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
2841 +               sp->opdata_rsa_priv = NULL;
2842 +               if (sp->opdata_rsa_d_num != NULL)
2843 +                       {
2844 +                       BN_free(sp->opdata_rsa_d_num);
2845 +                       sp->opdata_rsa_d_num = NULL;
2846 +                       }
2847 +               }
2849 +       return (ret);
2850 +       }
2853 + * Destroy RSA key object wrapper. If session is NULL, try to destroy all
2854 + * objects in the free list.
2855 + */
2856 +int
2857 +pk11_destroy_rsa_key_objects(PK11_SESSION *session)
2858 +       {
2859 +       int ret = 1;
2860 +       PK11_SESSION *sp = NULL;
2861 +       PK11_SESSION *local_free_session;
2862 +       CK_BBOOL uselock = TRUE;
2864 +       if (session != NULL)
2865 +               local_free_session = session;
2866 +       else
2867 +               {
2868 +#ifndef NOPTHREADS
2869 +               (void) pthread_mutex_lock(session_cache[OP_RSA].lock);
2870 +#else
2871 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
2872 +#endif
2873 +               local_free_session = session_cache[OP_RSA].head;
2874 +               uselock = FALSE;
2875 +               }
2877 +       /*
2878 +        * go through the list of sessions and delete key objects
2879 +        */
2880 +       while ((sp = local_free_session) != NULL)
2881 +               {
2882 +               local_free_session = sp->next;
2884 +               /*
2885 +                * Do not terminate list traversal if one of the
2886 +                * destroy operations fails.
2887 +                */
2888 +               if (pk11_destroy_rsa_object_pub(sp, uselock) == 0)
2889 +                       {
2890 +                       ret = 0;
2891 +                       continue;
2892 +                       }
2893 +               if (pk11_destroy_rsa_object_priv(sp, uselock) == 0)
2894 +                       {
2895 +                       ret = 0;
2896 +                       continue;
2897 +                       }
2898 +               }
2900 +#ifndef NOPTHREADS
2901 +       if (session == NULL)
2902 +               (void) pthread_mutex_unlock(session_cache[OP_RSA].lock);
2903 +#else
2904 +       if (session == NULL)
2905 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
2906 +#endif
2908 +       return (ret);
2909 +       }
2910 +#endif /* OPENSSL_NO_RSA */
2912 +#ifndef OPENSSL_NO_DSA
2913 +/* Destroy DSA public key from single session. */
2914 +int
2915 +pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
2916 +       {
2917 +       int ret = 0;
2919 +       if (sp->opdata_dsa_pub_key != CK_INVALID_HANDLE)
2920 +               {
2921 +               TRY_OBJ_DESTROY(sp->session, sp->opdata_dsa_pub_key,
2922 +                   ret, uselock, OP_DSA);
2923 +               sp->opdata_dsa_pub_key = CK_INVALID_HANDLE;
2924 +               sp->opdata_dsa_pub = NULL;
2925 +               if (sp->opdata_dsa_pub_num != NULL)
2926 +                       {
2927 +                       BN_free(sp->opdata_dsa_pub_num);
2928 +                       sp->opdata_dsa_pub_num = NULL;
2929 +                       }
2930 +               }
2932 +       return (ret);
2933 +       }
2935 +/* Destroy DSA private key from single session. */
2936 +int
2937 +pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
2938 +       {
2939 +       int ret = 0;
2941 +       if (sp->opdata_dsa_priv_key != CK_INVALID_HANDLE)
2942 +               {
2943 +               TRY_OBJ_DESTROY(sp->session, sp->opdata_dsa_priv_key,
2944 +                   ret, uselock, OP_DSA);
2945 +               sp->opdata_dsa_priv_key = CK_INVALID_HANDLE;
2946 +               sp->opdata_dsa_priv = NULL;
2947 +               if (sp->opdata_dsa_priv_num != NULL)
2948 +                       {
2949 +                       BN_free(sp->opdata_dsa_priv_num);
2950 +                       sp->opdata_dsa_priv_num = NULL;
2951 +                       }
2952 +               }
2954 +       return (ret);
2955 +       }
2958 + * Destroy DSA key object wrapper. If session is NULL, try to destroy all
2959 + * objects in the free list.
2960 + */
2961 +int
2962 +pk11_destroy_dsa_key_objects(PK11_SESSION *session)
2963 +       {
2964 +       int ret = 1;
2965 +       PK11_SESSION *sp = NULL;
2966 +       PK11_SESSION *local_free_session;
2967 +       CK_BBOOL uselock = TRUE;
2969 +       if (session != NULL)
2970 +               local_free_session = session;
2971 +       else
2972 +               {
2973 +#ifndef NOPTHREADS
2974 +               (void) pthread_mutex_lock(session_cache[OP_DSA].lock);
2975 +#else
2976 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
2977 +#endif
2978 +               local_free_session = session_cache[OP_DSA].head;
2979 +               uselock = FALSE;
2980 +               }
2982 +       /*
2983 +        * go through the list of sessions and delete key objects
2984 +        */
2985 +       while ((sp = local_free_session) != NULL)
2986 +               {
2987 +               local_free_session = sp->next;
2989 +               /*
2990 +                * Do not terminate list traversal if one of the
2991 +                * destroy operations fails.
2992 +                */
2993 +               if (pk11_destroy_dsa_object_pub(sp, uselock) == 0)
2994 +                       {
2995 +                       ret = 0;
2996 +                       continue;
2997 +                       }
2998 +               if (pk11_destroy_dsa_object_priv(sp, uselock) == 0)
2999 +                       {
3000 +                       ret = 0;
3001 +                       continue;
3002 +                       }
3003 +               }
3005 +#ifndef NOPTHREADS
3006 +       if (session == NULL)
3007 +               (void) pthread_mutex_unlock(session_cache[OP_DSA].lock);
3008 +#else
3009 +       if (session == NULL)
3010 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
3011 +#endif
3013 +       return (ret);
3014 +       }
3015 +#endif /* OPENSSL_NO_DSA */
3017 +#ifndef OPENSSL_NO_DH
3018 +/* Destroy DH key from single session. */
3019 +int
3020 +pk11_destroy_dh_object(PK11_SESSION *sp, CK_BBOOL uselock)
3021 +       {
3022 +       int ret = 0;
3024 +       if (sp->opdata_dh_key != CK_INVALID_HANDLE)
3025 +               {
3026 +               TRY_OBJ_DESTROY(sp->session, sp->opdata_dh_key,
3027 +                   ret, uselock, OP_DH);
3028 +               sp->opdata_dh_key = CK_INVALID_HANDLE;
3029 +               sp->opdata_dh = NULL;
3030 +               if (sp->opdata_dh_priv_num != NULL)
3031 +                       {
3032 +                       BN_free(sp->opdata_dh_priv_num);
3033 +                       sp->opdata_dh_priv_num = NULL;
3034 +                       }
3035 +               }
3037 +       return (ret);
3038 +       }
3041 + * Destroy DH key object wrapper.
3042 + *
3043 + * arg0: pointer to PKCS#11 engine session structure
3044 + *       if session is NULL, try to destroy all objects in the free list
3045 + */
3046 +int
3047 +pk11_destroy_dh_key_objects(PK11_SESSION *session)
3048 +       {
3049 +       int ret = 1;
3050 +       PK11_SESSION *sp = NULL;
3051 +       PK11_SESSION *local_free_session;
3052 +       CK_BBOOL uselock = TRUE;
3054 +       if (session != NULL)
3055 +               local_free_session = session;
3056 +       else
3057 +               {
3058 +#ifndef NOPTHREADS
3059 +               (void) pthread_mutex_lock(session_cache[OP_DH].lock);
3060 +#else
3061 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
3062 +#endif
3063 +               local_free_session = session_cache[OP_DH].head;
3064 +               uselock = FALSE;
3065 +               }
3067 +       while ((sp = local_free_session) != NULL)
3068 +               {
3069 +               local_free_session = sp->next;
3071 +               /*
3072 +                * Do not terminate list traversal if one of the
3073 +                * destroy operations fails.
3074 +                */
3075 +               if (pk11_destroy_dh_object(sp, uselock) == 0)
3076 +                       {
3077 +                       ret = 0;
3078 +                       continue;
3079 +                       }
3080 +               }
3082 +#ifndef NOPTHREADS
3083 +       if (session == NULL)
3084 +               (void) pthread_mutex_unlock(session_cache[OP_DH].lock);
3085 +#else
3086 +       if (session == NULL)
3087 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
3088 +#endif
3090 +       return (ret);
3091 +       }
3092 +#endif /* OPENSSL_NO_DH */
3094 +static int pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh)
3095 +       {
3096 +       CK_RV rv;
3097 +       rv = pFuncList->C_DestroyObject(session, oh);
3098 +       if (rv != CKR_OK)
3099 +               {
3100 +               PK11err_add_data(PK11_F_DESTROY_OBJECT, PK11_R_DESTROYOBJECT,
3101 +                   rv);
3102 +               return (0);
3103 +               }
3105 +       return (1);
3106 +       }
3109 +/* Symmetric ciphers and digests support functions */
3111 +static int
3112 +cipher_nid_to_pk11(int nid)
3113 +       {
3114 +       int i;
3116 +       for (i = 0; i < PK11_CIPHER_MAX; i++)
3117 +               if (ciphers[i].nid == nid)
3118 +                       return (ciphers[i].id);
3119 +       return (-1);
3120 +       }
3122 +static int
3123 +pk11_usable_ciphers(const int **nids)
3124 +       {
3125 +       if (cipher_count > 0)
3126 +               *nids = cipher_nids;
3127 +       else
3128 +               *nids = NULL;
3129 +       return (cipher_count);
3130 +       }
3132 +static int
3133 +pk11_usable_digests(const int **nids)
3134 +       {
3135 +       if (digest_count > 0)
3136 +               *nids = digest_nids;
3137 +       else
3138 +               *nids = NULL;
3139 +       return (digest_count);
3140 +       }
3143 + * Init context for encryption or decryption using a symmetric key.
3144 + */
3145 +static int pk11_init_symmetric(EVP_CIPHER_CTX *ctx, PK11_CIPHER *pcipher,
3146 +       PK11_SESSION *sp, CK_MECHANISM_PTR pmech)
3147 +       {
3148 +       CK_RV rv;
3149 +#ifdef SOLARIS_AES_CTR
3150 +       CK_AES_CTR_PARAMS ctr_params;
3151 +#endif /* SOLARIS_AES_CTR */
3153 +       /*
3154 +        * We expect pmech->mechanism to be already set and
3155 +        * pParameter/ulParameterLen initialized to NULL/0 before
3156 +        * pk11_init_symetric() is called.
3157 +        */
3158 +       OPENSSL_assert(pmech->mechanism != 0);
3159 +       OPENSSL_assert(pmech->pParameter == NULL);
3160 +       OPENSSL_assert(pmech->ulParameterLen == 0);
3162 +#ifdef SOLARIS_AES_CTR
3163 +       if (ctx->cipher->nid == NID_aes_128_ctr ||
3164 +           ctx->cipher->nid == NID_aes_192_ctr ||
3165 +           ctx->cipher->nid == NID_aes_256_ctr)
3166 +               {
3167 +               pmech->pParameter = (void *)(&ctr_params);
3168 +               pmech->ulParameterLen = sizeof (ctr_params);
3169 +               /*
3170 +                * For now, we are limited to the fixed length of the counter,
3171 +                * it covers the whole counter block. That's what RFC 4344
3172 +                * needs. For more information on internal structure of the
3173 +                * counter block, see RFC 3686. If needed in the future, we can
3174 +                * add code so that the counter length can be set via
3175 +                * ENGINE_ctrl() function.
3176 +                */
3177 +               ctr_params.ulCounterBits = AES_BLOCK_SIZE * 8;
3178 +               OPENSSL_assert(pcipher->iv_len == AES_BLOCK_SIZE);
3179 +               (void) memcpy(ctr_params.cb, ctx->iv, AES_BLOCK_SIZE);
3180 +               }
3181 +       else
3182 +#endif /* SOLARIS_AES_CTR */
3183 +               {
3184 +               if (pcipher->iv_len > 0)
3185 +                       {
3186 +                       pmech->pParameter = (void *)ctx->iv;
3187 +                       pmech->ulParameterLen = pcipher->iv_len;
3188 +                       }
3189 +               }
3191 +       /* if we get here, the encryption needs to be reinitialized */
3192 +       if (ctx->encrypt)
3193 +               rv = pFuncList->C_EncryptInit(sp->session, pmech,
3194 +                       sp->opdata_cipher_key);
3195 +       else
3196 +               rv = pFuncList->C_DecryptInit(sp->session, pmech,
3197 +                       sp->opdata_cipher_key);
3199 +       if (rv != CKR_OK)
3200 +               {
3201 +               PK11err_add_data(PK11_F_CIPHER_INIT, ctx->encrypt ?
3202 +                   PK11_R_ENCRYPTINIT : PK11_R_DECRYPTINIT, rv);
3203 +               pk11_return_session(sp, OP_CIPHER);
3204 +               return (0);
3205 +               }
3207 +       return (1);
3208 +       }
3210 +/* ARGSUSED */
3211 +static int
3212 +pk11_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
3213 +    const unsigned char *iv, int enc)
3214 +       {
3215 +       CK_MECHANISM mech;
3216 +       int index;
3217 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
3218 +       PK11_SESSION *sp;
3219 +       PK11_CIPHER *p_ciph_table_row;
3221 +       state->sp = NULL;
3223 +       index = cipher_nid_to_pk11(ctx->cipher->nid);
3224 +       if (index < 0 || index >= PK11_CIPHER_MAX)
3225 +               return (0);
3227 +       p_ciph_table_row = &ciphers[index];
3228 +       /*
3229 +        * iv_len in the ctx->cipher structure is the maximum IV length for the
3230 +        * current cipher and it must be less or equal to the IV length in our
3231 +        * ciphers table. The key length must be in the allowed interval. From
3232 +        * all cipher modes that the PKCS#11 engine supports only RC4 allows a
3233 +        * key length to be in some range, all other NIDs have a precise key
3234 +        * length. Every application can define its own EVP functions so this
3235 +        * code serves as a sanity check.
3236 +        *
3237 +        * Note that the reason why the IV length in ctx->cipher might be
3238 +        * greater than the actual length is that OpenSSL uses BLOCK_CIPHER_defs
3239 +        * macro to define functions that return EVP structures for all DES
3240 +        * modes. So, even ECB modes get 8 byte IV.
3241 +        */
3242 +       if (ctx->cipher->iv_len < p_ciph_table_row->iv_len ||
3243 +           ctx->key_len < p_ciph_table_row->min_key_len ||
3244 +           ctx->key_len > p_ciph_table_row->max_key_len) {
3245 +               PK11err(PK11_F_CIPHER_INIT, PK11_R_KEY_OR_IV_LEN_PROBLEM);
3246 +               return (0);
3247 +       }
3249 +       if ((sp = pk11_get_session(OP_CIPHER)) == NULL)
3250 +               return (0);
3252 +       /* if applicable, the mechanism parameter is used for IV */
3253 +       mech.mechanism = p_ciph_table_row->mech_type;
3254 +       mech.pParameter = NULL;
3255 +       mech.ulParameterLen = 0;
3257 +       /* The key object is destroyed here if it is not the current key. */
3258 +       (void) check_new_cipher_key(sp, key, ctx->key_len);
3260 +       /*
3261 +        * If the key is the same and the encryption is also the same, then
3262 +        * just reuse it. However, we must not forget to reinitialize the
3263 +        * context that was finalized in pk11_cipher_cleanup().
3264 +        */
3265 +       if (sp->opdata_cipher_key != CK_INVALID_HANDLE &&
3266 +           sp->opdata_encrypt == ctx->encrypt)
3267 +               {
3268 +               state->sp = sp;
3269 +               if (pk11_init_symmetric(ctx, p_ciph_table_row, sp, &mech) == 0)
3270 +                       return (0);
3272 +               return (1);
3273 +               }
3275 +       /*
3276 +        * Check if the key has been invalidated. If so, a new key object
3277 +        * needs to be created.
3278 +        */
3279 +       if (sp->opdata_cipher_key == CK_INVALID_HANDLE)
3280 +               {
3281 +               sp->opdata_cipher_key = pk11_get_cipher_key(
3282 +                       ctx, key, p_ciph_table_row->key_type, sp);
3283 +               }
3285 +       if (sp->opdata_encrypt != ctx->encrypt && sp->opdata_encrypt != -1)
3286 +               {
3287 +               /*
3288 +                * The previous encryption/decryption is different. Need to
3289 +                * terminate the previous * active encryption/decryption here.
3290 +                */
3291 +               if (!pk11_cipher_final(sp))
3292 +                       {
3293 +                       pk11_return_session(sp, OP_CIPHER);
3294 +                       return (0);
3295 +                       }
3296 +               }
3298 +       if (sp->opdata_cipher_key == CK_INVALID_HANDLE)
3299 +               {
3300 +               pk11_return_session(sp, OP_CIPHER);
3301 +               return (0);
3302 +               }
3304 +       /* now initialize the context with a new key */
3305 +       if (pk11_init_symmetric(ctx, p_ciph_table_row, sp, &mech) == 0)
3306 +               return (0);
3308 +       sp->opdata_encrypt = ctx->encrypt;
3309 +       state->sp = sp;
3311 +       return (1);
3312 +       }
3315 + * When reusing the same key in an encryption/decryption session for a
3316 + * decryption/encryption session, we need to close the active session
3317 + * and recreate a new one. Note that the key is in the global session so
3318 + * that it needs not be recreated.
3319 + *
3320 + * It is more appropriate to use C_En/DecryptFinish here. At the time of this
3321 + * development, these two functions in the PKCS#11 libraries used return
3322 + * unexpected errors when passing in 0 length output. It may be a good
3323 + * idea to try them again if performance is a problem here and fix
3324 + * C_En/DecryptFinial if there are bugs there causing the problem.
3325 + */
3326 +static int
3327 +pk11_cipher_final(PK11_SESSION *sp)
3328 +       {
3329 +       CK_RV rv;
3331 +       rv = pFuncList->C_CloseSession(sp->session);
3332 +       if (rv != CKR_OK)
3333 +               {
3334 +               PK11err_add_data(PK11_F_CIPHER_FINAL, PK11_R_CLOSESESSION, rv);
3335 +               return (0);
3336 +               }
3338 +       rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
3339 +               NULL_PTR, NULL_PTR, &sp->session);
3340 +       if (rv != CKR_OK)
3341 +               {
3342 +               PK11err_add_data(PK11_F_CIPHER_FINAL, PK11_R_OPENSESSION, rv);
3343 +               return (0);
3344 +               }
3346 +       return (1);
3347 +       }
3350 + * An engine interface function. The calling function allocates sufficient
3351 + * memory for the output buffer "out" to hold the results.
3352 + */
3353 +static int
3354 +pk11_cipher_do_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
3355 +       const unsigned char *in, unsigned int inl)
3356 +       {
3357 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->cipher_data;
3358 +       PK11_SESSION *sp;
3359 +       CK_RV rv;
3360 +       unsigned long outl = inl;
3362 +       if (state == NULL || state->sp == NULL)
3363 +               return (0);
3365 +       sp = (PK11_SESSION *) state->sp;
3367 +       if (!inl)
3368 +               return (1);
3370 +       /* RC4 is the only stream cipher we support */
3371 +       if (ctx->cipher->nid != NID_rc4 && (inl % ctx->cipher->block_size) != 0)
3372 +               return (0);
3374 +       if (ctx->encrypt)
3375 +               {
3376 +               rv = pFuncList->C_EncryptUpdate(sp->session,
3377 +                       (unsigned char *)in, inl, out, &outl);
3379 +               if (rv != CKR_OK)
3380 +                       {
3381 +                       PK11err_add_data(PK11_F_CIPHER_DO_CIPHER,
3382 +                           PK11_R_ENCRYPTUPDATE, rv);
3383 +                       return (0);
3384 +                       }
3385 +               }
3386 +       else
3387 +               {
3388 +               rv = pFuncList->C_DecryptUpdate(sp->session,
3389 +                       (unsigned char *)in, inl, out, &outl);
3391 +               if (rv != CKR_OK)
3392 +                       {
3393 +                       PK11err_add_data(PK11_F_CIPHER_DO_CIPHER,
3394 +                           PK11_R_DECRYPTUPDATE, rv);
3395 +                       return (0);
3396 +                       }
3397 +               }
3399 +       /*
3400 +        * For DES_CBC, DES3_CBC, AES_CBC, and RC4, the output size is always
3401 +        * the same size of input.
3402 +        * The application has guaranteed to call the block ciphers with
3403 +        * correctly aligned buffers.
3404 +        */
3405 +       if (inl != outl)
3406 +               return (0);
3408 +       return (1);
3409 +       }
3412 + * Return the session to the pool. Calling C_EncryptFinal() and C_DecryptFinal()
3413 + * here is the right thing because in EVP_DecryptFinal_ex(), engine's
3414 + * do_cipher() is not even called, and in EVP_EncryptFinal_ex() it is called but
3415 + * the engine can't find out that it's the finalizing call. We wouldn't
3416 + * necessarily have to finalize the context here since reinitializing it with
3417 + * C_(Encrypt|Decrypt)Init() should be fine but for the sake of correctness,
3418 + * let's do it. Some implementations might leak memory if the previously used
3419 + * context is initialized without finalizing it first.
3420 + */
3421 +static int
3422 +pk11_cipher_cleanup(EVP_CIPHER_CTX *ctx)
3423 +       {
3424 +       CK_RV rv;
3425 +       CK_ULONG len = EVP_MAX_BLOCK_LENGTH;
3426 +       CK_BYTE buf[EVP_MAX_BLOCK_LENGTH];
3427 +       PK11_CIPHER_STATE *state = ctx->cipher_data;
3429 +       if (state != NULL && state->sp != NULL)
3430 +               {
3431 +               /*
3432 +                * We are not interested in the data here, we just need to get
3433 +                * rid of the context.
3434 +                */
3435 +               if (ctx->encrypt)
3436 +                       rv = pFuncList->C_EncryptFinal(
3437 +                           state->sp->session, buf, &len);
3438 +               else
3439 +                       rv = pFuncList->C_DecryptFinal(
3440 +                           state->sp->session, buf, &len);
3442 +               if (rv != CKR_OK)
3443 +                       {
3444 +                       PK11err_add_data(PK11_F_CIPHER_CLEANUP, ctx->encrypt ?
3445 +                           PK11_R_ENCRYPTFINAL : PK11_R_DECRYPTFINAL, rv);
3446 +                       pk11_return_session(state->sp, OP_CIPHER);
3447 +                       return (0);
3448 +                       }
3450 +               pk11_return_session(state->sp, OP_CIPHER);
3451 +               state->sp = NULL;
3452 +               }
3454 +       return (1);
3455 +       }
3458 + * Registered by the ENGINE when used to find out how to deal with
3459 + * a particular NID in the ENGINE. This says what we'll do at the
3460 + * top level - note, that list is restricted by what we answer with
3461 + */
3462 +/* ARGSUSED */
3463 +static int
3464 +pk11_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
3465 +       const int **nids, int nid)
3466 +       {
3467 +       if (!cipher)
3468 +               return (pk11_usable_ciphers(nids));
3470 +       switch (nid)
3471 +               {
3472 +               case NID_des_ede3_cbc:
3473 +                       *cipher = &pk11_3des_cbc;
3474 +                       break;
3475 +               case NID_des_cbc:
3476 +                       *cipher = &pk11_des_cbc;
3477 +                       break;
3478 +               case NID_des_ede3_ecb:
3479 +                       *cipher = &pk11_3des_ecb;
3480 +                       break;
3481 +               case NID_des_ecb:
3482 +                       *cipher = &pk11_des_ecb;
3483 +                       break;
3484 +               case NID_aes_128_cbc:
3485 +                       *cipher = &pk11_aes_128_cbc;
3486 +                       break;
3487 +               case NID_aes_192_cbc:
3488 +                       *cipher = &pk11_aes_192_cbc;
3489 +                       break;
3490 +               case NID_aes_256_cbc:
3491 +                       *cipher = &pk11_aes_256_cbc;
3492 +                       break;
3493 +               case NID_aes_128_ecb:
3494 +                       *cipher = &pk11_aes_128_ecb;
3495 +                       break;
3496 +               case NID_aes_192_ecb:
3497 +                       *cipher = &pk11_aes_192_ecb;
3498 +                       break;
3499 +               case NID_aes_256_ecb:
3500 +                       *cipher = &pk11_aes_256_ecb;
3501 +                       break;
3502 +               case NID_bf_cbc:
3503 +                       *cipher = &pk11_bf_cbc;
3504 +                       break;
3505 +               case NID_rc4:
3506 +                       *cipher = &pk11_rc4;
3507 +                       break;
3508 +               default:
3509 +#ifdef SOLARIS_AES_CTR
3510 +                       /*
3511 +                        * These can't be in separated cases because the NIDs
3512 +                        * here are not constants.
3513 +                        */
3514 +                       if (nid == NID_aes_128_ctr)
3515 +                               *cipher = &pk11_aes_128_ctr;
3516 +                       else if (nid == NID_aes_192_ctr)
3517 +                               *cipher = &pk11_aes_192_ctr;
3518 +                       else if (nid == NID_aes_256_ctr)
3519 +                               *cipher = &pk11_aes_256_ctr;
3520 +                       else
3521 +#endif /* SOLARIS_AES_CTR */
3522 +                       *cipher = NULL;
3523 +                       break;
3524 +               }
3525 +       return (*cipher != NULL);
3526 +       }
3528 +/* ARGSUSED */
3529 +static int
3530 +pk11_engine_digests(ENGINE *e, const EVP_MD **digest,
3531 +       const int **nids, int nid)
3532 +       {
3533 +       if (!digest)
3534 +               return (pk11_usable_digests(nids));
3536 +       switch (nid)
3537 +               {
3538 +               case NID_md5:
3539 +                       *digest = &pk11_md5;
3540 +                       break;
3541 +               case NID_sha1:
3542 +                       *digest = &pk11_sha1;
3543 +                       break;
3544 +               case NID_sha224:
3545 +                       *digest = &pk11_sha224;
3546 +                       break;
3547 +               case NID_sha256:
3548 +                       *digest = &pk11_sha256;
3549 +                       break;
3550 +               case NID_sha384:
3551 +                       *digest = &pk11_sha384;
3552 +                       break;
3553 +               case NID_sha512:
3554 +                       *digest = &pk11_sha512;
3555 +                       break;
3556 +               default:
3557 +                       *digest = NULL;
3558 +                       break;
3559 +               }
3560 +       return (*digest != NULL);
3561 +       }
3564 +/* Create a secret key object in a PKCS#11 session */
3565 +static CK_OBJECT_HANDLE pk11_get_cipher_key(EVP_CIPHER_CTX *ctx,
3566 +       const unsigned char *key, CK_KEY_TYPE key_type, PK11_SESSION *sp)
3567 +       {
3568 +       CK_RV rv;
3569 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
3570 +       CK_OBJECT_CLASS obj_key = CKO_SECRET_KEY;
3571 +       CK_ULONG ul_key_attr_count = 6;
3573 +       CK_ATTRIBUTE  a_key_template[] =
3574 +               {
3575 +               {CKA_CLASS, (void*) NULL, sizeof (CK_OBJECT_CLASS)},
3576 +               {CKA_KEY_TYPE, (void*) NULL, sizeof (CK_KEY_TYPE)},
3577 +               {CKA_TOKEN, &false, sizeof (false)},
3578 +               {CKA_ENCRYPT, &true, sizeof (true)},
3579 +               {CKA_DECRYPT, &true, sizeof (true)},
3580 +               {CKA_VALUE, (void*) NULL, 0},
3581 +               };
3583 +       /*
3584 +        * Create secret key object in global_session. All other sessions
3585 +        * can use the key handles. Here is why:
3586 +        * OpenSSL will call EncryptInit and EncryptUpdate using a secret key.
3587 +        * It may then call DecryptInit and DecryptUpdate using the same key.
3588 +        * To use the same key object, we need to call EncryptFinal with
3589 +        * a 0 length message. Currently, this does not work for 3DES
3590 +        * mechanism. To get around this problem, we close the session and
3591 +        * then create a new session to use the same key object. When a session
3592 +        * is closed, all the object handles will be invalid. Thus, create key
3593 +        * objects in a global session, an individual session may be closed to
3594 +        * terminate the active operation.
3595 +        */
3596 +       CK_SESSION_HANDLE session = global_session;
3597 +       a_key_template[0].pValue = &obj_key;
3598 +       a_key_template[1].pValue = &key_type;
3599 +       a_key_template[5].pValue = (void *) key;
3600 +       a_key_template[5].ulValueLen = (unsigned long) ctx->key_len;
3602 +       rv = pFuncList->C_CreateObject(session,
3603 +               a_key_template, ul_key_attr_count, &h_key);
3604 +       if (rv != CKR_OK)
3605 +               {
3606 +               PK11err_add_data(PK11_F_GET_CIPHER_KEY, PK11_R_CREATEOBJECT,
3607 +                   rv);
3608 +               goto err;
3609 +               }
3611 +       /*
3612 +        * Save the key information used in this session.
3613 +        * The max can be saved is PK11_KEY_LEN_MAX.
3614 +        */
3615 +       sp->opdata_key_len = ctx->key_len > PK11_KEY_LEN_MAX ?
3616 +               PK11_KEY_LEN_MAX : ctx->key_len;
3617 +       (void) memcpy(sp->opdata_key, key, sp->opdata_key_len);
3618 +err:
3620 +       return (h_key);
3621 +       }
3623 +static int
3624 +md_nid_to_pk11(int nid)
3625 +       {
3626 +       int i;
3628 +       for (i = 0; i < PK11_DIGEST_MAX; i++)
3629 +               if (digests[i].nid == nid)
3630 +                       return (digests[i].id);
3631 +       return (-1);
3632 +       }
3634 +static int
3635 +pk11_digest_init(EVP_MD_CTX *ctx)
3636 +       {
3637 +       CK_RV rv;
3638 +       CK_MECHANISM mech;
3639 +       int index;
3640 +       PK11_SESSION *sp;
3641 +       PK11_DIGEST *pdp;
3642 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
3644 +       state->sp = NULL;
3646 +       index = md_nid_to_pk11(ctx->digest->type);
3647 +       if (index < 0 || index >= PK11_DIGEST_MAX)
3648 +               return (0);
3650 +       pdp = &digests[index];
3651 +       if ((sp = pk11_get_session(OP_DIGEST)) == NULL)
3652 +               return (0);
3654 +       /* at present, no parameter is needed for supported digests */
3655 +       mech.mechanism = pdp->mech_type;
3656 +       mech.pParameter = NULL;
3657 +       mech.ulParameterLen = 0;
3659 +       rv = pFuncList->C_DigestInit(sp->session, &mech);
3661 +       if (rv != CKR_OK)
3662 +               {
3663 +               PK11err_add_data(PK11_F_DIGEST_INIT, PK11_R_DIGESTINIT, rv);
3664 +               pk11_return_session(sp, OP_DIGEST);
3665 +               return (0);
3666 +               }
3668 +       state->sp = sp;
3670 +       return (1);
3671 +       }
3673 +static int
3674 +pk11_digest_update(EVP_MD_CTX *ctx, const void *data, size_t count)
3675 +       {
3676 +       CK_RV rv;
3677 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
3679 +       /* 0 length message will cause a failure in C_DigestFinal */
3680 +       if (count == 0)
3681 +               return (1);
3683 +       if (state == NULL || state->sp == NULL)
3684 +               return (0);
3686 +       rv = pFuncList->C_DigestUpdate(state->sp->session, (CK_BYTE *) data,
3687 +               count);
3689 +       if (rv != CKR_OK)
3690 +               {
3691 +               PK11err_add_data(PK11_F_DIGEST_UPDATE, PK11_R_DIGESTUPDATE, rv);
3692 +               pk11_return_session(state->sp, OP_DIGEST);
3693 +               state->sp = NULL;
3694 +               return (0);
3695 +               }
3697 +       return (1);
3698 +       }
3700 +static int
3701 +pk11_digest_final(EVP_MD_CTX *ctx, unsigned char *md)
3702 +       {
3703 +       CK_RV rv;
3704 +       unsigned long len;
3705 +       PK11_CIPHER_STATE *state = (PK11_CIPHER_STATE *) ctx->md_data;
3706 +       len = ctx->digest->md_size;
3708 +       if (state == NULL || state->sp == NULL)
3709 +               return (0);
3711 +       rv = pFuncList->C_DigestFinal(state->sp->session, md, &len);
3713 +       if (rv != CKR_OK)
3714 +               {
3715 +               PK11err_add_data(PK11_F_DIGEST_FINAL, PK11_R_DIGESTFINAL, rv);
3716 +               pk11_return_session(state->sp, OP_DIGEST);
3717 +               state->sp = NULL;
3718 +               return (0);
3719 +               }
3721 +       if (ctx->digest->md_size != len)
3722 +               return (0);
3724 +       /*
3725 +        * Final is called and digest is returned, so return the session
3726 +        * to the pool
3727 +        */
3728 +       pk11_return_session(state->sp, OP_DIGEST);
3729 +       state->sp = NULL;
3731 +       return (1);
3732 +       }
3734 +static int
3735 +pk11_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
3736 +       {
3737 +       CK_RV rv;
3738 +       int ret = 0;
3739 +       PK11_CIPHER_STATE *state, *state_to;
3740 +       CK_BYTE_PTR pstate = NULL;
3741 +       CK_ULONG ul_state_len;
3743 +       /* The copy-from state */
3744 +       state = (PK11_CIPHER_STATE *) from->md_data;
3745 +       if (state == NULL || state->sp == NULL)
3746 +               goto err;
3748 +       /* Initialize the copy-to state */
3749 +       if (!pk11_digest_init(to))
3750 +               goto err;
3751 +       state_to = (PK11_CIPHER_STATE *) to->md_data;
3753 +       /* Get the size of the operation state of the copy-from session */
3754 +       rv = pFuncList->C_GetOperationState(state->sp->session, NULL,
3755 +               &ul_state_len);
3757 +       if (rv != CKR_OK)
3758 +               {
3759 +               PK11err_add_data(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE,
3760 +                   rv);
3761 +               goto err;
3762 +               }
3763 +       if (ul_state_len == 0)
3764 +               {
3765 +               goto err;
3766 +               }
3768 +       pstate = OPENSSL_malloc(ul_state_len);
3769 +       if (pstate == NULL)
3770 +               {
3771 +               PK11err(PK11_F_DIGEST_COPY, PK11_R_MALLOC_FAILURE);
3772 +               goto err;
3773 +               }
3775 +       /* Get the operation state of the copy-from session */
3776 +       rv = pFuncList->C_GetOperationState(state->sp->session, pstate,
3777 +               &ul_state_len);
3779 +       if (rv != CKR_OK)
3780 +               {
3781 +               PK11err_add_data(PK11_F_DIGEST_COPY, PK11_R_GET_OPERATION_STATE,
3782 +                   rv);
3783 +               goto err;
3784 +               }
3786 +       /* Set the operation state of the copy-to session */
3787 +       rv = pFuncList->C_SetOperationState(state_to->sp->session, pstate,
3788 +               ul_state_len, 0, 0);
3790 +       if (rv != CKR_OK)
3791 +               {
3792 +               PK11err_add_data(PK11_F_DIGEST_COPY,
3793 +                   PK11_R_SET_OPERATION_STATE, rv);
3794 +               goto err;
3795 +               }
3797 +       ret = 1;
3798 +err:
3799 +       if (pstate != NULL)
3800 +               OPENSSL_free(pstate);
3802 +       return (ret);
3803 +       }
3805 +/* Return any pending session state to the pool */
3806 +static int
3807 +pk11_digest_cleanup(EVP_MD_CTX *ctx)
3808 +       {
3809 +       PK11_CIPHER_STATE *state = ctx->md_data;
3810 +       unsigned char buf[EVP_MAX_MD_SIZE];
3812 +       if (state != NULL && state->sp != NULL)
3813 +               {
3814 +               /*
3815 +                * If state->sp is not NULL then pk11_digest_final() has not
3816 +                * been called yet. We must call it now to free any memory
3817 +                * that might have been allocated in the token when
3818 +                * pk11_digest_init() was called. pk11_digest_final()
3819 +                * will return the session to the cache.
3820 +                */
3821 +               if (!pk11_digest_final(ctx, buf))
3822 +                       return (0);
3823 +               }
3825 +       return (1);
3826 +       }
3829 + * Check if the new key is the same as the key object in the session. If the key
3830 + * is the same, no need to create a new key object. Otherwise, the old key
3831 + * object needs to be destroyed and a new one will be created. Return 1 for
3832 + * cache hit, 0 for cache miss. Note that we must check the key length first
3833 + * otherwise we could end up reusing a different, longer key with the same
3834 + * prefix.
3835 + */
3836 +static int check_new_cipher_key(PK11_SESSION *sp, const unsigned char *key,
3837 +       int key_len)
3838 +       {
3839 +       if (sp->opdata_key_len != key_len ||
3840 +           memcmp(sp->opdata_key, key, key_len) != 0)
3841 +               {
3842 +               (void) pk11_destroy_cipher_key_objects(sp);
3843 +               return (0);
3844 +               }
3845 +       return (1);
3846 +       }
3848 +/* Destroy one or more secret key objects. */
3849 +static int pk11_destroy_cipher_key_objects(PK11_SESSION *session)
3850 +       {
3851 +       int ret = 0;
3852 +       PK11_SESSION *sp = NULL;
3853 +       PK11_SESSION *local_free_session;
3855 +       if (session != NULL)
3856 +               local_free_session = session;
3857 +       else
3858 +               {
3859 +#ifndef NOPTHREADS
3860 +               (void) pthread_mutex_lock(session_cache[OP_CIPHER].lock);
3861 +#else
3862 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
3863 +#endif
3864 +               local_free_session = session_cache[OP_CIPHER].head;
3865 +               }
3867 +       while ((sp = local_free_session) != NULL)
3868 +               {
3869 +               local_free_session = sp->next;
3871 +               if (sp->opdata_cipher_key != CK_INVALID_HANDLE)
3872 +                       {
3873 +                       /*
3874 +                        * The secret key object is created in the
3875 +                        * global_session. See pk11_get_cipher_key
3876 +                        */
3877 +                       if (pk11_destroy_object(global_session,
3878 +                               sp->opdata_cipher_key) == 0)
3879 +                               goto err;
3880 +                       sp->opdata_cipher_key = CK_INVALID_HANDLE;
3881 +                       }
3882 +               }
3883 +       ret = 1;
3884 +err:
3886 +#ifndef NOPTHREADS
3887 +       if (session == NULL)
3888 +               (void) pthread_mutex_unlock(session_cache[OP_CIPHER].lock);
3889 +#else
3890 +       if (session == NULL)
3891 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
3892 +#endif
3894 +       return (ret);
3895 +       }
3899 + * Public key mechanisms optionally supported
3900 + *
3901 + * CKM_RSA_X_509
3902 + * CKM_RSA_PKCS
3903 + * CKM_DSA
3904 + *
3905 + * The first slot that supports at least one of those mechanisms is chosen as a
3906 + * public key slot.
3907 + *
3908 + * Symmetric ciphers optionally supported
3909 + *
3910 + * CKM_DES3_CBC
3911 + * CKM_DES_CBC
3912 + * CKM_AES_CBC
3913 + * CKM_DES3_ECB
3914 + * CKM_DES_ECB
3915 + * CKM_AES_ECB
3916 + * CKM_AES_CTR
3917 + * CKM_RC4
3918 + * CKM_BLOWFISH_CBC
3919 + *
3920 + * Digests optionally supported
3921 + *
3922 + * CKM_MD5
3923 + * CKM_SHA_1
3924 + * CKM_SHA224
3925 + * CKM_SHA256
3926 + * CKM_SHA384
3927 + * CKM_SHA512
3928 + *
3929 + * The output of this function is a set of global variables indicating which
3930 + * mechanisms from RSA, DSA, DH and RAND are present, and also two arrays of
3931 + * mechanisms, one for symmetric ciphers and one for digests. Also, 3 global
3932 + * variables carry information about which slot was chosen for (a) public key
3933 + * mechanisms, (b) random operations, and (c) symmetric ciphers and digests.
3934 + */
3935 +static int
3936 +pk11_choose_slots(int *any_slot_found)
3937 +       {
3938 +       CK_SLOT_ID_PTR pSlotList = NULL_PTR;
3939 +       CK_ULONG ulSlotCount = 0;
3940 +       CK_MECHANISM_INFO mech_info;
3941 +       CK_TOKEN_INFO token_info;
3942 +       unsigned int i;
3943 +       CK_RV rv;
3944 +       CK_SLOT_ID best_slot_sofar = 0;
3945 +       CK_BBOOL found_candidate_slot = CK_FALSE;
3946 +       int slot_n_cipher = 0;
3947 +       int slot_n_digest = 0;
3948 +       CK_SLOT_ID current_slot = 0;
3949 +       int current_slot_n_cipher = 0;
3950 +       int current_slot_n_digest = 0;
3952 +       int local_cipher_nids[PK11_CIPHER_MAX];
3953 +       int local_digest_nids[PK11_DIGEST_MAX];
3955 +       /* let's initialize the output parameter */
3956 +       if (any_slot_found != NULL)
3957 +               *any_slot_found = 0;
3959 +       /* Get slot list for memory allocation */
3960 +       rv = pFuncList->C_GetSlotList(0, NULL_PTR, &ulSlotCount);
3962 +       if (rv != CKR_OK)
3963 +               {
3964 +               PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
3965 +               return (0);
3966 +               }
3968 +       /* it's not an error if we didn't find any providers */
3969 +       if (ulSlotCount == 0)
3970 +               {
3971 +#ifdef DEBUG_SLOT_SELECTION
3972 +               fprintf(stderr, "%s: no crypto providers found\n", PK11_DBG);
3973 +#endif /* DEBUG_SLOT_SELECTION */
3974 +               return (1);
3975 +               }
3977 +       pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
3979 +       if (pSlotList == NULL)
3980 +               {
3981 +               PK11err(PK11_F_CHOOSE_SLOT, PK11_R_MALLOC_FAILURE);
3982 +               return (0);
3983 +               }
3985 +       /* Get the slot list for processing */
3986 +       rv = pFuncList->C_GetSlotList(0, pSlotList, &ulSlotCount);
3987 +       if (rv != CKR_OK)
3988 +               {
3989 +               PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
3990 +               OPENSSL_free(pSlotList);
3991 +               return (0);
3992 +               }
3994 +#ifdef DEBUG_SLOT_SELECTION
3995 +       fprintf(stderr, "%s: provider: %s\n", PK11_DBG, def_PK11_LIBNAME);
3996 +       fprintf(stderr, "%s: number of slots: %d\n", PK11_DBG, ulSlotCount);
3998 +       fprintf(stderr, "%s: == checking rand slots ==\n", PK11_DBG);
3999 +#endif /* DEBUG_SLOT_SELECTION */
4000 +       for (i = 0; i < ulSlotCount; i++)
4001 +               {
4002 +               current_slot = pSlotList[i];
4004 +#ifdef DEBUG_SLOT_SELECTION
4005 +       fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
4006 +#endif /* DEBUG_SLOT_SELECTION */
4007 +               /* Check if slot has random support. */
4008 +               rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
4009 +               if (rv != CKR_OK)
4010 +                       continue;
4012 +#ifdef DEBUG_SLOT_SELECTION
4013 +       fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
4014 +#endif /* DEBUG_SLOT_SELECTION */
4016 +               if (token_info.flags & CKF_RNG)
4017 +                       {
4018 +#ifdef DEBUG_SLOT_SELECTION
4019 +       fprintf(stderr, "%s: this token has CKF_RNG flag\n", PK11_DBG);
4020 +#endif /* DEBUG_SLOT_SELECTION */
4021 +                       pk11_have_random = CK_TRUE;
4022 +                       rand_SLOTID = current_slot;
4023 +                       break;
4024 +                       }
4025 +               }
4027 +#ifdef DEBUG_SLOT_SELECTION
4028 +       fprintf(stderr, "%s: == checking pubkey slots ==\n", PK11_DBG);
4029 +#endif /* DEBUG_SLOT_SELECTION */
4031 +       pubkey_SLOTID = pSlotList[0];
4032 +       for (i = 0; i < ulSlotCount; i++)
4033 +               {
4034 +               CK_BBOOL slot_has_rsa = CK_FALSE;
4035 +               CK_BBOOL slot_has_recover = CK_FALSE;
4036 +               CK_BBOOL slot_has_dsa = CK_FALSE;
4037 +               CK_BBOOL slot_has_dh = CK_FALSE;
4038 +               current_slot = pSlotList[i];
4040 +#ifdef DEBUG_SLOT_SELECTION
4041 +       fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
4042 +#endif /* DEBUG_SLOT_SELECTION */
4043 +               rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
4044 +               if (rv != CKR_OK)
4045 +                       continue;
4047 +#ifdef DEBUG_SLOT_SELECTION
4048 +       fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
4049 +#endif /* DEBUG_SLOT_SELECTION */
4051 +#ifndef OPENSSL_NO_RSA
4052 +               /*
4053 +                * Check if this slot is capable of signing and
4054 +                * verifying with CKM_RSA_PKCS.
4055 +                */
4056 +               rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS,
4057 +                       &mech_info);
4059 +               if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
4060 +                               (mech_info.flags & CKF_VERIFY)))
4061 +                       {
4062 +                       /*
4063 +                        * Check if this slot is capable of encryption,
4064 +                        * decryption, sign, and verify with CKM_RSA_X_509.
4065 +                        */
4066 +                       rv = pFuncList->C_GetMechanismInfo(current_slot,
4067 +                           CKM_RSA_X_509, &mech_info);
4069 +                       if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
4070 +                           (mech_info.flags & CKF_VERIFY) &&
4071 +                           (mech_info.flags & CKF_ENCRYPT) &&
4072 +                           (mech_info.flags & CKF_DECRYPT)))
4073 +                               {
4074 +                               slot_has_rsa = CK_TRUE;
4075 +                               if (mech_info.flags & CKF_VERIFY_RECOVER)
4076 +                                       {
4077 +                                       slot_has_recover = CK_TRUE;
4078 +                                       }
4079 +                               }
4080 +                       }
4081 +#endif /* OPENSSL_NO_RSA */
4083 +#ifndef OPENSSL_NO_DSA
4084 +               /*
4085 +                * Check if this slot is capable of signing and
4086 +                * verifying with CKM_DSA.
4087 +                */
4088 +               rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_DSA,
4089 +                       &mech_info);
4090 +               if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN) &&
4091 +                   (mech_info.flags & CKF_VERIFY)))
4092 +                       {
4093 +                       slot_has_dsa = CK_TRUE;
4094 +                       }
4096 +#endif /* OPENSSL_NO_DSA */
4098 +#ifndef OPENSSL_NO_DH
4099 +               /*
4100 +                * Check if this slot is capable of DH key generataion and
4101 +                * derivation.
4102 +                */
4103 +               rv = pFuncList->C_GetMechanismInfo(current_slot,
4104 +                   CKM_DH_PKCS_KEY_PAIR_GEN, &mech_info);
4106 +               if (rv == CKR_OK && (mech_info.flags & CKF_GENERATE_KEY_PAIR))
4107 +                       {
4108 +                       rv = pFuncList->C_GetMechanismInfo(current_slot,
4109 +                               CKM_DH_PKCS_DERIVE, &mech_info);
4110 +                       if (rv == CKR_OK && (mech_info.flags & CKF_DERIVE))
4111 +                               {
4112 +                               slot_has_dh = CK_TRUE;
4113 +                               }
4114 +                       }
4115 +#endif /* OPENSSL_NO_DH */
4117 +               if (!found_candidate_slot &&
4118 +                   (slot_has_rsa || slot_has_dsa || slot_has_dh))
4119 +                       {
4120 +#ifdef DEBUG_SLOT_SELECTION
4121 +                       fprintf(stderr,
4122 +                           "%s: potential slot: %d\n", PK11_DBG, current_slot);
4123 +#endif /* DEBUG_SLOT_SELECTION */
4124 +                       best_slot_sofar = current_slot;
4125 +                       pk11_have_rsa = slot_has_rsa;
4126 +                       pk11_have_recover = slot_has_recover;
4127 +                       pk11_have_dsa = slot_has_dsa;
4128 +                       pk11_have_dh = slot_has_dh;
4129 +                       found_candidate_slot = CK_TRUE;
4130 +#ifdef DEBUG_SLOT_SELECTION
4131 +                       fprintf(stderr,
4132 +                           "%s: setting found_candidate_slot to CK_TRUE\n",
4133 +                           PK11_DBG);
4134 +                       fprintf(stderr,
4135 +                           "%s: best so far slot: %d\n", PK11_DBG,
4136 +                           best_slot_sofar);
4137 +                       }
4138 +               else
4139 +                       {
4140 +                       fprintf(stderr,
4141 +                           "%s: no rsa/dsa/dh\n", PK11_DBG);
4142 +                       }
4143 +#else
4144 +                       } /* if */
4145 +#endif /* DEBUG_SLOT_SELECTION */
4146 +               } /* for */
4148 +       if (found_candidate_slot)
4149 +               {
4150 +               pubkey_SLOTID = best_slot_sofar;
4151 +               }
4153 +       found_candidate_slot = CK_FALSE;
4154 +       best_slot_sofar = 0;
4156 +#ifdef DEBUG_SLOT_SELECTION
4157 +       fprintf(stderr, "%s: == checking cipher/digest ==\n", PK11_DBG);
4158 +#endif /* DEBUG_SLOT_SELECTION */
4160 +       SLOTID = pSlotList[0];
4161 +       for (i = 0; i < ulSlotCount; i++)
4162 +               {
4163 +#ifdef DEBUG_SLOT_SELECTION
4164 +       fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
4165 +#endif /* DEBUG_SLOT_SELECTION */
4167 +               current_slot = pSlotList[i];
4168 +               current_slot_n_cipher = 0;
4169 +               current_slot_n_digest = 0;
4170 +               (void) memset(local_cipher_nids, 0, sizeof (local_cipher_nids));
4171 +               (void) memset(local_digest_nids, 0, sizeof (local_digest_nids));
4173 +               pk11_find_symmetric_ciphers(pFuncList, current_slot,
4174 +                   &current_slot_n_cipher, local_cipher_nids);
4176 +               pk11_find_digests(pFuncList, current_slot,
4177 +                   &current_slot_n_digest, local_digest_nids);
4179 +#ifdef DEBUG_SLOT_SELECTION
4180 +               fprintf(stderr, "%s: current_slot_n_cipher %d\n", PK11_DBG,
4181 +                       current_slot_n_cipher);
4182 +               fprintf(stderr, "%s: current_slot_n_digest %d\n", PK11_DBG,
4183 +                       current_slot_n_digest);
4184 +               fprintf(stderr, "%s: best so far cipher/digest slot: %d\n",
4185 +                       PK11_DBG, best_slot_sofar);
4186 +#endif /* DEBUG_SLOT_SELECTION */
4188 +               /*
4189 +                * If the current slot supports more ciphers/digests than
4190 +                * the previous best one we change the current best to this one,
4191 +                * otherwise leave it where it is.
4192 +                */
4193 +               if ((current_slot_n_cipher + current_slot_n_digest) >
4194 +                   (slot_n_cipher + slot_n_digest))
4195 +                       {
4196 +#ifdef DEBUG_SLOT_SELECTION
4197 +                       fprintf(stderr,
4198 +                               "%s: changing best so far slot to %d\n",
4199 +                               PK11_DBG, current_slot);
4200 +#endif /* DEBUG_SLOT_SELECTION */
4201 +                       best_slot_sofar = SLOTID = current_slot;
4202 +                       cipher_count = slot_n_cipher = current_slot_n_cipher;
4203 +                       digest_count = slot_n_digest = current_slot_n_digest;
4204 +                       (void) memcpy(cipher_nids, local_cipher_nids,
4205 +                           sizeof (local_cipher_nids));
4206 +                       (void) memcpy(digest_nids, local_digest_nids, 
4207 +                           sizeof (local_digest_nids));
4208 +                       }
4209 +               }
4211 +#ifdef DEBUG_SLOT_SELECTION
4212 +       fprintf(stderr,
4213 +           "%s: chosen pubkey slot: %d\n", PK11_DBG, pubkey_SLOTID);
4214 +       fprintf(stderr,
4215 +           "%s: chosen rand slot: %d\n", PK11_DBG, rand_SLOTID);
4216 +       fprintf(stderr,
4217 +           "%s: chosen cipher/digest slot: %d\n", PK11_DBG, SLOTID);
4218 +       fprintf(stderr,
4219 +           "%s: pk11_have_rsa %d\n", PK11_DBG, pk11_have_rsa);
4220 +       fprintf(stderr,
4221 +           "%s: pk11_have_recover %d\n", PK11_DBG, pk11_have_recover);
4222 +       fprintf(stderr,
4223 +           "%s: pk11_have_dsa %d\n", PK11_DBG, pk11_have_dsa);
4224 +       fprintf(stderr,
4225 +           "%s: pk11_have_dh %d\n", PK11_DBG, pk11_have_dh);
4226 +       fprintf(stderr,
4227 +           "%s: pk11_have_random %d\n", PK11_DBG, pk11_have_random);
4228 +       fprintf(stderr,
4229 +           "%s: cipher_count %d\n", PK11_DBG, cipher_count);
4230 +       fprintf(stderr,
4231 +           "%s: digest_count %d\n", PK11_DBG, digest_count);
4232 +#endif /* DEBUG_SLOT_SELECTION */
4234 +       if (pSlotList != NULL)
4235 +               OPENSSL_free(pSlotList);
4237 +#ifdef SOLARIS_HW_SLOT_SELECTION
4238 +       OPENSSL_free(hw_cnids);
4239 +       OPENSSL_free(hw_dnids);
4240 +#endif /* SOLARIS_HW_SLOT_SELECTION */
4242 +       if (any_slot_found != NULL)
4243 +               *any_slot_found = 1;
4244 +       return (1);
4245 +       }
4247 +static void pk11_get_symmetric_cipher(CK_FUNCTION_LIST_PTR pflist,
4248 +    int slot_id, CK_MECHANISM_TYPE mech, int *current_slot_n_cipher,
4249 +    int *local_cipher_nids, int id)
4250 +       {
4251 +       CK_MECHANISM_INFO mech_info;
4252 +       CK_RV rv;
4254 +#ifdef DEBUG_SLOT_SELECTION
4255 +       fprintf(stderr, "%s: checking mech: %x", PK11_DBG, mech);
4256 +#endif /* DEBUG_SLOT_SELECTION */
4257 +       rv = pflist->C_GetMechanismInfo(slot_id, mech, &mech_info);
4259 +       if (rv != CKR_OK)
4260 +               {
4261 +#ifdef DEBUG_SLOT_SELECTION
4262 +               fprintf(stderr, " not found\n");
4263 +#endif /* DEBUG_SLOT_SELECTION */
4264 +               return;
4265 +               }
4267 +       if ((mech_info.flags & CKF_ENCRYPT) &&
4268 +           (mech_info.flags & CKF_DECRYPT))
4269 +               {
4270 +#ifdef SOLARIS_HW_SLOT_SELECTION
4271 +               if (nid_in_table(ciphers[id].nid, hw_cnids))
4272 +#endif /* SOLARIS_HW_SLOT_SELECTION */
4273 +                       {
4274 +#ifdef DEBUG_SLOT_SELECTION
4275 +               fprintf(stderr, " usable\n");
4276 +#endif /* DEBUG_SLOT_SELECTION */
4277 +                       local_cipher_nids[(*current_slot_n_cipher)++] =
4278 +                           ciphers[id].nid;
4279 +                       }
4280 +#ifdef SOLARIS_HW_SLOT_SELECTION
4281 +#ifdef DEBUG_SLOT_SELECTION
4282 +               else
4283 +                       {
4284 +               fprintf(stderr, " rejected, software implementation only\n");
4285 +                       }
4286 +#endif /* DEBUG_SLOT_SELECTION */
4287 +#endif /* SOLARIS_HW_SLOT_SELECTION */
4288 +               }
4289 +#ifdef DEBUG_SLOT_SELECTION
4290 +       else
4291 +               {
4292 +               fprintf(stderr, " unusable\n");
4293 +               }
4294 +#endif /* DEBUG_SLOT_SELECTION */
4296 +       return;
4297 +       }
4299 +static void pk11_get_digest(CK_FUNCTION_LIST_PTR pflist, int slot_id,
4300 +    CK_MECHANISM_TYPE mech, int *current_slot_n_digest, int *local_digest_nids,
4301 +    int id)
4302 +       {
4303 +       CK_MECHANISM_INFO mech_info;
4304 +       CK_RV rv;
4306 +#ifdef DEBUG_SLOT_SELECTION
4307 +       fprintf(stderr, "%s: checking mech: %x", PK11_DBG, mech);
4308 +#endif /* DEBUG_SLOT_SELECTION */
4309 +       rv = pflist->C_GetMechanismInfo(slot_id, mech, &mech_info);
4311 +       if (rv != CKR_OK)
4312 +               {
4313 +#ifdef DEBUG_SLOT_SELECTION
4314 +               fprintf(stderr, " not found\n");
4315 +#endif /* DEBUG_SLOT_SELECTION */
4316 +               return;
4317 +               }
4319 +       if (mech_info.flags & CKF_DIGEST)
4320 +               {
4321 +#ifdef SOLARIS_HW_SLOT_SELECTION
4322 +               if (nid_in_table(digests[id].nid, hw_dnids))
4323 +#endif /* SOLARIS_HW_SLOT_SELECTION */
4324 +                       {
4325 +#ifdef DEBUG_SLOT_SELECTION
4326 +               fprintf(stderr, " usable\n");
4327 +#endif /* DEBUG_SLOT_SELECTION */
4328 +                       local_digest_nids[(*current_slot_n_digest)++] =
4329 +                           digests[id].nid;
4330 +                       }
4331 +#ifdef SOLARIS_HW_SLOT_SELECTION
4332 +#ifdef DEBUG_SLOT_SELECTION
4333 +               else
4334 +                       {
4335 +               fprintf(stderr, " rejected, software implementation only\n");
4336 +                       }
4337 +#endif /* DEBUG_SLOT_SELECTION */
4338 +#endif /* SOLARIS_HW_SLOT_SELECTION */
4339 +               }
4340 +#ifdef DEBUG_SLOT_SELECTION
4341 +       else
4342 +               {
4343 +               fprintf(stderr, " unusable\n");
4344 +               }
4345 +#endif /* DEBUG_SLOT_SELECTION */
4347 +       return;
4348 +       }
4350 +#ifdef SOLARIS_AES_CTR
4351 +/* create a new NID when we have no OID for that mechanism */
4352 +static int pk11_add_NID(char *sn, char *ln)
4353 +       {
4354 +       ASN1_OBJECT *o;
4355 +       int nid;
4357 +       if ((o = ASN1_OBJECT_create(OBJ_new_nid(1), (unsigned char *)"",
4358 +           1, sn, ln)) == NULL)
4359 +               {
4360 +               return (0);
4361 +               }
4363 +       /* will return NID_undef on error */
4364 +       nid = OBJ_add_object(o);
4365 +       ASN1_OBJECT_free(o);
4367 +       return (nid);
4368 +       }
4371 + * Create new NIDs for AES counter mode. OpenSSL doesn't support them now so we
4372 + * have to help ourselves here.
4373 + */
4374 +static int pk11_add_aes_ctr_NIDs(void)
4375 +       {
4376 +       /* are we already set? */
4377 +       if (NID_aes_256_ctr != NID_undef)
4378 +               return (1);
4380 +       /*
4381 +        * There are no official names for AES counter modes yet so we just
4382 +        * follow the format of those that exist.
4383 +        */
4384 +       if ((NID_aes_128_ctr = pk11_add_NID("AES-128-CTR", "aes-128-ctr")) ==
4385 +           NID_undef)
4386 +               goto err;
4387 +       ciphers[PK11_AES_128_CTR].nid = pk11_aes_128_ctr.nid = NID_aes_128_ctr;
4388 +       if ((NID_aes_192_ctr = pk11_add_NID("AES-192-CTR", "aes-192-ctr")) ==
4389 +           NID_undef)
4390 +               goto err;
4391 +       ciphers[PK11_AES_192_CTR].nid = pk11_aes_192_ctr.nid = NID_aes_192_ctr;
4392 +       if ((NID_aes_256_ctr = pk11_add_NID("AES-256-CTR", "aes-256-ctr")) ==
4393 +           NID_undef)
4394 +               goto err;
4395 +       ciphers[PK11_AES_256_CTR].nid = pk11_aes_256_ctr.nid = NID_aes_256_ctr;
4396 +       return (1);
4398 +err:
4399 +       PK11err(PK11_F_ADD_AES_CTR_NIDS, PK11_R_ADD_NID_FAILED);
4400 +       return (0);
4401 +       }
4402 +#endif /* SOLARIS_AES_CTR */
4404 +/* Find what symmetric ciphers this slot supports. */
4405 +static void pk11_find_symmetric_ciphers(CK_FUNCTION_LIST_PTR pflist,
4406 +    CK_SLOT_ID current_slot, int *current_slot_n_cipher, int *local_cipher_nids)
4407 +       {
4408 +       int i;
4410 +       for (i = 0; i < PK11_CIPHER_MAX; ++i)
4411 +               {
4412 +               pk11_get_symmetric_cipher(pflist, current_slot,
4413 +                   ciphers[i].mech_type, current_slot_n_cipher,
4414 +                   local_cipher_nids, ciphers[i].id);
4415 +               }
4416 +       }
4418 +/* Find what digest algorithms this slot supports. */
4419 +static void pk11_find_digests(CK_FUNCTION_LIST_PTR pflist,
4420 +    CK_SLOT_ID current_slot, int *current_slot_n_digest, int *local_digest_nids)
4421 +       {
4422 +       int i;
4424 +       for (i = 0; i < PK11_DIGEST_MAX; ++i)
4425 +               {
4426 +               pk11_get_digest(pflist, current_slot, digests[i].mech_type,
4427 +                   current_slot_n_digest, local_digest_nids, digests[i].id);
4428 +               }
4429 +       }
4431 +#ifdef SOLARIS_HW_SLOT_SELECTION
4433 + * It would be great if we could use pkcs11_kernel directly since this library
4434 + * offers hardware slots only. That's the easiest way to achieve the situation
4435 + * where we use the hardware accelerators when present and OpenSSL native code
4436 + * otherwise. That presumes the fact that OpenSSL native code is faster than the
4437 + * code in the soft token. It's a logical assumption - Crypto Framework has some
4438 + * inherent overhead so going there for the software implementation of a
4439 + * mechanism should be logically slower in contrast to the OpenSSL native code,
4440 + * presuming that both implementations are of similar speed. For example, the
4441 + * soft token for AES is roughly three times slower than OpenSSL for 64 byte
4442 + * blocks and still 20% slower for 8KB blocks. So, if we want to ship products
4443 + * that use the PKCS#11 engine by default, we must somehow avoid that regression
4444 + * on machines without hardware acceleration. That's why switching to the
4445 + * pkcs11_kernel library seems like a very good idea.
4446 + *
4447 + * The problem is that OpenSSL built with SunStudio is roughly 2x slower for
4448 + * asymmetric operations (RSA/DSA/DH) than the soft token built with the same
4449 + * compiler. That means that if we switched to pkcs11_kernel from the libpkcs11
4450 + * library, we would have had a performance regression on machines without
4451 + * hardware acceleration for asymmetric operations for all applications that use
4452 + * the PKCS#11 engine. There is one such application - Apache web server since
4453 + * it's shipped configured to use the PKCS#11 engine by default. Having said
4454 + * that, we can't switch to the pkcs11_kernel library now and have to come with
4455 + * a solution that, on non-accelerated machines, uses the OpenSSL native code
4456 + * for all symmetric ciphers and digests while it uses the soft token for
4457 + * asymmetric operations.
4458 + *
4459 + * This is the idea: dlopen() pkcs11_kernel directly and find out what
4460 + * mechanisms are there. We don't care about duplications (more slots can
4461 + * support the same mechanism), we just want to know what mechanisms can be
4462 + * possibly supported in hardware on that particular machine. As said before,
4463 + * pkcs11_kernel will show you hardware providers only.
4464 + *
4465 + * Then, we rely on the fact that since we use libpkcs11 library we will find
4466 + * the metaslot. When we go through the metaslot's mechanisms for symmetric
4467 + * ciphers and digests, we check that any found mechanism is in the table
4468 + * created using the pkcs11_kernel library. So, as a result we have two arrays
4469 + * of mechanisms that were advertised as supported in hardware which was the
4470 + * goal of that whole excercise. Thus, we can use libpkcs11 but avoid soft token
4471 + * code for symmetric ciphers and digests. See pk11_choose_slots() for more
4472 + * information.
4473 + *
4474 + * This is Solaris specific code, if SOLARIS_HW_SLOT_SELECTION is not defined
4475 + * the code won't be used.
4476 + */
4477 +#if defined(__sparcv9) || defined(__x86_64) || defined(__amd64)
4478 +static const char pkcs11_kernel[] = "/usr/lib/security/64/pkcs11_kernel.so.1";
4479 +#else
4480 +static const char pkcs11_kernel[] = "/usr/lib/security/pkcs11_kernel.so.1";
4481 +#endif
4484 + * Check hardware capabilities of the machines. The output are two lists,
4485 + * hw_cnids and hw_dnids, that contain hardware mechanisms found in all hardware
4486 + * providers together. They are not sorted and may contain duplicate mechanisms.
4487 + */
4488 +static int check_hw_mechanisms(void)
4489 +       {
4490 +       int i;
4491 +       CK_RV rv;
4492 +       void *handle;
4493 +       CK_C_GetFunctionList p;
4494 +       CK_TOKEN_INFO token_info;
4495 +       CK_ULONG ulSlotCount = 0;
4496 +       int n_cipher = 0, n_digest = 0;
4497 +       CK_FUNCTION_LIST_PTR pflist = NULL;
4498 +       CK_SLOT_ID_PTR pSlotList = NULL_PTR;
4499 +       int *tmp_hw_cnids = NULL, *tmp_hw_dnids = NULL;
4500 +       int hw_ctable_size, hw_dtable_size;
4502 +#ifdef DEBUG_SLOT_SELECTION
4503 +       fprintf(stderr, "%s: SOLARIS_HW_SLOT_SELECTION code running\n",
4504 +           PK11_DBG);
4505 +#endif
4506 +       if ((handle = dlopen(pkcs11_kernel, RTLD_LAZY)) == NULL)
4507 +               {
4508 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
4509 +               goto err;
4510 +               }
4512 +       if ((p = (CK_C_GetFunctionList)dlsym(handle,
4513 +           PK11_GET_FUNCTION_LIST)) == NULL)
4514 +               {
4515 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
4516 +               goto err;
4517 +               }
4519 +       /* get the full function list from the loaded library */
4520 +       if (p(&pflist) != CKR_OK)
4521 +               {
4522 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_DSO_FAILURE);
4523 +               goto err;
4524 +               }
4526 +       rv = pflist->C_Initialize(NULL_PTR);
4527 +       if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
4528 +               {
4529 +               PK11err_add_data(PK11_F_CHECK_HW_MECHANISMS,
4530 +                   PK11_R_INITIALIZE, rv);
4531 +               goto err;
4532 +               }
4534 +       if (pflist->C_GetSlotList(0, NULL_PTR, &ulSlotCount) != CKR_OK)
4535 +               {
4536 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_GETSLOTLIST);
4537 +               goto err;
4538 +               }
4540 +       /* no slots, set the hw mechanism tables as empty */
4541 +       if (ulSlotCount == 0)
4542 +               {
4543 +#ifdef DEBUG_SLOT_SELECTION
4544 +       fprintf(stderr, "%s: no hardware mechanisms found\n", PK11_DBG);
4545 +#endif
4546 +               hw_cnids = OPENSSL_malloc(sizeof (int));
4547 +               hw_dnids = OPENSSL_malloc(sizeof (int));
4548 +               if (hw_cnids == NULL || hw_dnids == NULL)
4549 +                       {
4550 +                       PK11err(PK11_F_CHECK_HW_MECHANISMS,
4551 +                           PK11_R_MALLOC_FAILURE);
4552 +                       return (0);
4553 +                       }
4554 +               /* this means empty tables */
4555 +               hw_cnids[0] = NID_undef;
4556 +               hw_dnids[0] = NID_undef;
4557 +               return (1);
4558 +               }
4560 +       pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
4561 +       if (pSlotList == NULL)
4562 +               {
4563 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_MALLOC_FAILURE);
4564 +               goto err;
4565 +               }
4567 +       /* Get the slot list for processing */
4568 +       if (pflist->C_GetSlotList(0, pSlotList, &ulSlotCount) != CKR_OK)
4569 +               {
4570 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_GETSLOTLIST);
4571 +               goto err;
4572 +               }
4574 +       /*
4575 +        * We don't care about duplicit mechanisms in multiple slots and also
4576 +        * reserve one slot for the terminal NID_undef which we use to stop the
4577 +        * search.
4578 +        */
4579 +       hw_ctable_size = ulSlotCount * PK11_CIPHER_MAX + 1;
4580 +       hw_dtable_size = ulSlotCount * PK11_DIGEST_MAX + 1;
4581 +       tmp_hw_cnids = OPENSSL_malloc(hw_ctable_size * sizeof (int));
4582 +       tmp_hw_dnids = OPENSSL_malloc(hw_dtable_size * sizeof (int));
4583 +       if (tmp_hw_cnids == NULL || tmp_hw_dnids == NULL)
4584 +               {
4585 +               PK11err(PK11_F_CHECK_HW_MECHANISMS, PK11_R_MALLOC_FAILURE);
4586 +               goto err;
4587 +               }
4589 +       /*
4590 +        * Do not use memset since we should not rely on the fact that NID_undef
4591 +        * is zero now.
4592 +        */
4593 +       for (i = 0; i < hw_ctable_size; ++i)
4594 +               tmp_hw_cnids[i] = NID_undef;
4595 +       for (i = 0; i < hw_dtable_size; ++i)
4596 +               tmp_hw_dnids[i] = NID_undef;
4598 +#ifdef DEBUG_SLOT_SELECTION
4599 +       fprintf(stderr, "%s: provider: %s\n", PK11_DBG, pkcs11_kernel);
4600 +       fprintf(stderr, "%s: found %d hardware slots\n", PK11_DBG, ulSlotCount);
4601 +       fprintf(stderr, "%s: now looking for mechs supported in hw\n",
4602 +           PK11_DBG);
4603 +#endif /* DEBUG_SLOT_SELECTION */
4605 +       for (i = 0; i < ulSlotCount; i++)
4606 +               {
4607 +               if (pflist->C_GetTokenInfo(pSlotList[i], &token_info) != CKR_OK)
4608 +                       continue;
4610 +#ifdef DEBUG_SLOT_SELECTION
4611 +       fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
4612 +#endif /* DEBUG_SLOT_SELECTION */
4614 +               /*
4615 +                * We are filling the hw mech tables here. Global tables are
4616 +                * still NULL so all mechanisms are put into tmp tables.
4617 +                */
4618 +               pk11_find_symmetric_ciphers(pflist, pSlotList[i],
4619 +                   &n_cipher, tmp_hw_cnids);
4620 +               pk11_find_digests(pflist, pSlotList[i],
4621 +                   &n_digest, tmp_hw_dnids);
4622 +               }
4624 +       /*
4625 +        * Since we are part of a library (libcrypto.so), calling this function
4626 +        * may have side-effects. Also, C_Finalize() is triggered by
4627 +        * dlclose(3C).
4628 +        */
4629 +#if 0
4630 +       pflist->C_Finalize(NULL);
4631 +#endif
4632 +       OPENSSL_free(pSlotList);
4633 +       (void) dlclose(handle);
4634 +       hw_cnids = tmp_hw_cnids;
4635 +       hw_dnids = tmp_hw_dnids;
4637 +#ifdef DEBUG_SLOT_SELECTION
4638 +       fprintf(stderr, "%s: hw mechs check complete\n", PK11_DBG);
4639 +#endif /* DEBUG_SLOT_SELECTION */
4640 +       return (1);
4642 +err:
4643 +       if (pSlotList != NULL)
4644 +               OPENSSL_free(pSlotList);
4645 +       if (tmp_hw_cnids != NULL)
4646 +               OPENSSL_free(tmp_hw_cnids);
4647 +       if (tmp_hw_dnids != NULL)
4648 +               OPENSSL_free(tmp_hw_dnids);
4650 +       return (0);
4651 +       }
4654 + * Check presence of a NID in the table of NIDs. The table may be NULL (i.e.,
4655 + * non-existent).
4656 + */
4657 +static int nid_in_table(int nid, int *nid_table)
4658 +       {
4659 +       int i = 0;
4661 +       /*
4662 +        * a special case. NULL means that we are initializing a new
4663 +        * table.
4664 +        */
4665 +       if (nid_table == NULL)
4666 +               return (1);
4668 +       /*
4669 +        * the table is never full, there is always at least one
4670 +        * NID_undef.
4671 +        */
4672 +       while (nid_table[i] != NID_undef)
4673 +               {
4674 +               if (nid_table[i++] == nid)
4675 +                       {
4676 +#ifdef DEBUG_SLOT_SELECTION
4677 +       fprintf(stderr, " (NID %d in hw table, idx %d)", nid, i);
4678 +#endif /* DEBUG_SLOT_SELECTION */
4679 +                       return (1);
4680 +                       }
4681 +               }
4683 +       return (0);
4684 +       }
4685 +#endif /* SOLARIS_HW_SLOT_SELECTION */
4687 +#endif /* OPENSSL_NO_HW_PK11CA */
4688 +#endif /* OPENSSL_NO_HW_PK11 */
4689 +#endif /* OPENSSL_NO_HW */
4690 Index: openssl/crypto/engine/hw_pk11_err.c
4691 diff -u /dev/null openssl/crypto/engine/hw_pk11_err.c:1.4
4692 --- /dev/null   Mon Oct  5 13:17:24 2009
4693 +++ openssl/crypto/engine/hw_pk11_err.c Wed Dec 17 16:14:26 2008
4694 @@ -0,0 +1,259 @@
4696 + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
4697 + * Use is subject to license terms.
4698 + */
4700 +/* crypto/engine/hw_pk11_err.c */
4702 + * This product includes software developed by the OpenSSL Project for
4703 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
4704 + *
4705 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
4706 + * Afchine Madjlessi.
4707 + */
4709 + * ====================================================================
4710 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
4711 + *
4712 + * Redistribution and use in source and binary forms, with or without
4713 + * modification, are permitted provided that the following conditions
4714 + * are met:
4715 + *
4716 + * 1. Redistributions of source code must retain the above copyright
4717 + *    notice, this list of conditions and the following disclaimer.
4718 + *
4719 + * 2. Redistributions in binary form must reproduce the above copyright
4720 + *    notice, this list of conditions and the following disclaimer in
4721 + *    the documentation and/or other materials provided with the
4722 + *    distribution.
4723 + *
4724 + * 3. All advertising materials mentioning features or use of this
4725 + *    software must display the following acknowledgment:
4726 + *    "This product includes software developed by the OpenSSL Project
4727 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
4728 + *
4729 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
4730 + *    endorse or promote products derived from this software without
4731 + *    prior written permission. For written permission, please contact
4732 + *    licensing@OpenSSL.org.
4733 + *
4734 + * 5. Products derived from this software may not be called "OpenSSL"
4735 + *    nor may "OpenSSL" appear in their names without prior written
4736 + *    permission of the OpenSSL Project.
4737 + *
4738 + * 6. Redistributions of any form whatsoever must retain the following
4739 + *    acknowledgment:
4740 + *    "This product includes software developed by the OpenSSL Project
4741 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
4742 + *
4743 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
4744 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4745 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
4746 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
4747 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4748 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
4749 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
4750 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4751 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4752 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
4753 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
4754 + * OF THE POSSIBILITY OF SUCH DAMAGE.
4755 + * ====================================================================
4756 + *
4757 + * This product includes cryptographic software written by Eric Young
4758 + * (eay@cryptsoft.com).  This product includes software written by Tim
4759 + * Hudson (tjh@cryptsoft.com).
4760 + *
4761 + */
4763 +#include <stdio.h>
4764 +#include <openssl/err.h>
4765 +#include "hw_pk11_err.h"
4767 +/* BEGIN ERROR CODES */
4768 +#ifndef OPENSSL_NO_ERR
4769 +static ERR_STRING_DATA pk11_str_functs[]=
4771 +{ ERR_PACK(0, PK11_F_INIT, 0),                 "PK11_INIT"},
4772 +{ ERR_PACK(0, PK11_F_FINISH, 0),               "PK11_FINISH"},
4773 +{ ERR_PACK(0, PK11_F_DESTROY, 0),              "PK11_DESTROY"},
4774 +{ ERR_PACK(0, PK11_F_CTRL, 0),                 "PK11_CTRL"},
4775 +{ ERR_PACK(0, PK11_F_RSA_INIT, 0),             "PK11_RSA_INIT"},
4776 +{ ERR_PACK(0, PK11_F_RSA_FINISH, 0),           "PK11_RSA_FINISH"},
4777 +{ ERR_PACK(0, PK11_F_GET_PUB_RSA_KEY, 0),      "PK11_GET_PUB_RSA_KEY"},
4778 +{ ERR_PACK(0, PK11_F_GET_PRIV_RSA_KEY, 0),     "PK11_GET_PRIV_RSA_KEY"},
4779 +{ ERR_PACK(0, PK11_F_RSA_GEN_KEY, 0),          "PK11_RSA_GEN_KEY"},
4780 +{ ERR_PACK(0, PK11_F_RSA_PUB_ENC, 0),          "PK11_RSA_PUB_ENC"},
4781 +{ ERR_PACK(0, PK11_F_RSA_PRIV_ENC, 0),         "PK11_RSA_PRIV_ENC"},
4782 +{ ERR_PACK(0, PK11_F_RSA_PUB_DEC, 0),          "PK11_RSA_PUB_DEC"},
4783 +{ ERR_PACK(0, PK11_F_RSA_PRIV_DEC, 0),         "PK11_RSA_PRIV_DEC"},
4784 +{ ERR_PACK(0, PK11_F_RSA_SIGN, 0),             "PK11_RSA_SIGN"},
4785 +{ ERR_PACK(0, PK11_F_RSA_VERIFY, 0),           "PK11_RSA_VERIFY"},
4786 +{ ERR_PACK(0, PK11_F_RAND_ADD, 0),             "PK11_RAND_ADD"},
4787 +{ ERR_PACK(0, PK11_F_RAND_BYTES, 0),           "PK11_RAND_BYTES"},
4788 +{ ERR_PACK(0, PK11_F_GET_SESSION, 0),          "PK11_GET_SESSION"},
4789 +{ ERR_PACK(0, PK11_F_FREE_SESSION, 0),         "PK11_FREE_SESSION"},
4790 +{ ERR_PACK(0, PK11_F_LOAD_PUBKEY, 0),          "PK11_LOAD_PUBKEY"},
4791 +{ ERR_PACK(0, PK11_F_LOAD_PRIVKEY, 0),         "PK11_LOAD_PRIV_KEY"},
4792 +{ ERR_PACK(0, PK11_F_RSA_PUB_ENC_LOW, 0),      "PK11_RSA_PUB_ENC_LOW"},
4793 +{ ERR_PACK(0, PK11_F_RSA_PRIV_ENC_LOW, 0),     "PK11_RSA_PRIV_ENC_LOW"},
4794 +{ ERR_PACK(0, PK11_F_RSA_PUB_DEC_LOW, 0),      "PK11_RSA_PUB_DEC_LOW"},
4795 +{ ERR_PACK(0, PK11_F_RSA_PRIV_DEC_LOW, 0),     "PK11_RSA_PRIV_DEC_LOW"},
4796 +{ ERR_PACK(0, PK11_F_DSA_SIGN, 0),             "PK11_DSA_SIGN"},
4797 +{ ERR_PACK(0, PK11_F_DSA_VERIFY, 0),           "PK11_DSA_VERIFY"},
4798 +{ ERR_PACK(0, PK11_F_DSA_INIT, 0),             "PK11_DSA_INIT"},
4799 +{ ERR_PACK(0, PK11_F_DSA_FINISH, 0),           "PK11_DSA_FINISH"},
4800 +{ ERR_PACK(0, PK11_F_GET_PUB_DSA_KEY, 0),      "PK11_GET_PUB_DSA_KEY"},
4801 +{ ERR_PACK(0, PK11_F_GET_PRIV_DSA_KEY, 0),     "PK11_GET_PRIV_DSA_KEY"},
4802 +{ ERR_PACK(0, PK11_F_DH_INIT, 0),              "PK11_DH_INIT"},
4803 +{ ERR_PACK(0, PK11_F_DH_FINISH, 0),            "PK11_DH_FINISH"},
4804 +{ ERR_PACK(0, PK11_F_MOD_EXP_DH, 0),           "PK11_MOD_EXP_DH"},
4805 +{ ERR_PACK(0, PK11_F_GET_DH_KEY, 0),           "PK11_GET_DH_KEY"},
4806 +{ ERR_PACK(0, PK11_F_FREE_ALL_SESSIONS, 0),    "PK11_FREE_ALL_SESSIONS"},
4807 +{ ERR_PACK(0, PK11_F_SETUP_SESSION, 0),                "PK11_SETUP_SESSION"},
4808 +{ ERR_PACK(0, PK11_F_DESTROY_OBJECT, 0),       "PK11_DESTROY_OBJECT"},
4809 +{ ERR_PACK(0, PK11_F_CIPHER_INIT, 0),          "PK11_CIPHER_INIT"},
4810 +{ ERR_PACK(0, PK11_F_CIPHER_DO_CIPHER, 0),     "PK11_CIPHER_DO_CIPHER"},
4811 +{ ERR_PACK(0, PK11_F_GET_CIPHER_KEY, 0),       "PK11_GET_CIPHER_KEY"},
4812 +{ ERR_PACK(0, PK11_F_DIGEST_INIT, 0),          "PK11_DIGEST_INIT"},
4813 +{ ERR_PACK(0, PK11_F_DIGEST_UPDATE, 0),                "PK11_DIGEST_UPDATE"},
4814 +{ ERR_PACK(0, PK11_F_DIGEST_FINAL, 0),         "PK11_DIGEST_FINAL"},
4815 +{ ERR_PACK(0, PK11_F_CHOOSE_SLOT, 0),          "PK11_CHOOSE_SLOT"},
4816 +{ ERR_PACK(0, PK11_F_CIPHER_FINAL, 0),         "PK11_CIPHER_FINAL"},
4817 +{ ERR_PACK(0, PK11_F_LIBRARY_INIT, 0),         "PK11_LIBRARY_INIT"},
4818 +{ ERR_PACK(0, PK11_F_LOAD, 0),                 "ENGINE_LOAD_PK11"},
4819 +{ ERR_PACK(0, PK11_F_DH_GEN_KEY, 0),           "PK11_DH_GEN_KEY"},
4820 +{ ERR_PACK(0, PK11_F_DH_COMP_KEY, 0),          "PK11_DH_COMP_KEY"},
4821 +{ ERR_PACK(0, PK11_F_DIGEST_COPY, 0),          "PK11_DIGEST_COPY"},
4822 +{ ERR_PACK(0, PK11_F_CIPHER_CLEANUP, 0),       "PK11_CIPHER_CLEANUP"},
4823 +{ ERR_PACK(0, PK11_F_ACTIVE_ADD, 0),           "PK11_ACTIVE_ADD"},
4824 +{ ERR_PACK(0, PK11_F_ACTIVE_DELETE, 0),                "PK11_ACTIVE_DELETE"},
4825 +{ ERR_PACK(0, PK11_F_CHECK_HW_MECHANISMS, 0),  "PK11_CHECK_HW_MECHANISMS"},
4826 +{ ERR_PACK(0, PK11_F_INIT_SYMMETRIC, 0),       "PK11_INIT_SYMMETRIC"},
4827 +{ ERR_PACK(0, PK11_F_ADD_AES_CTR_NIDS, 0),     "PK11_ADD_AES_CTR_NIDS"},
4828 +{ 0, NULL}
4831 +static ERR_STRING_DATA pk11_str_reasons[]=
4833 +{ PK11_R_ALREADY_LOADED,               "PKCS#11 DSO already loaded"},
4834 +{ PK11_R_DSO_FAILURE,                  "unable to load PKCS#11 DSO"},
4835 +{ PK11_R_NOT_LOADED,                   "PKCS#11 DSO not loaded"},
4836 +{ PK11_R_PASSED_NULL_PARAMETER,                "null parameter passed"},
4837 +{ PK11_R_COMMAND_NOT_IMPLEMENTED,      "command not implemented"},
4838 +{ PK11_R_INITIALIZE,                   "C_Initialize failed"},
4839 +{ PK11_R_FINALIZE,                     "C_Finalize failed"},
4840 +{ PK11_R_GETINFO,                      "C_GetInfo faile"},
4841 +{ PK11_R_GETSLOTLIST,                  "C_GetSlotList failed"},
4842 +{ PK11_R_NO_MODULUS_OR_NO_EXPONENT,    "no modulus or no exponent"},
4843 +{ PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID,        "attr sensitive or invalid"},
4844 +{ PK11_R_GETATTRIBUTVALUE,             "C_GetAttributeValue failed"},
4845 +{ PK11_R_NO_MODULUS,                   "no modulus"},
4846 +{ PK11_R_NO_EXPONENT,                  "no exponent"},
4847 +{ PK11_R_FINDOBJECTSINIT,              "C_FindObjectsInit failed"},
4848 +{ PK11_R_FINDOBJECTS,                  "C_FindObjects failed"},
4849 +{ PK11_R_FINDOBJECTSFINAL,             "C_FindObjectsFinal failed"},
4850 +{ PK11_R_CREATEOBJECT,                 "C_CreateObject failed"},
4851 +{ PK11_R_DESTROYOBJECT,                        "C_DestroyObject failed"},
4852 +{ PK11_R_OPENSESSION,                  "C_OpenSession failed"},
4853 +{ PK11_R_CLOSESESSION,                 "C_CloseSession failed"},
4854 +{ PK11_R_ENCRYPTINIT,                  "C_EncryptInit failed"},
4855 +{ PK11_R_ENCRYPT,                      "C_Encrypt failed"},
4856 +{ PK11_R_SIGNINIT,                     "C_SignInit failed"},
4857 +{ PK11_R_SIGN,                         "C_Sign failed"},
4858 +{ PK11_R_DECRYPTINIT,                  "C_DecryptInit failed"},
4859 +{ PK11_R_DECRYPT,                      "C_Decrypt failed"},
4860 +{ PK11_R_VERIFYINIT,                   "C_VerifyRecover failed"},
4861 +{ PK11_R_VERIFY,                       "C_Verify failed"},
4862 +{ PK11_R_VERIFYRECOVERINIT,            "C_VerifyRecoverInit failed"},
4863 +{ PK11_R_VERIFYRECOVER,                        "C_VerifyRecover failed"},
4864 +{ PK11_R_GEN_KEY,                      "C_GenerateKeyPair failed"},
4865 +{ PK11_R_SEEDRANDOM,                   "C_SeedRandom failed"},
4866 +{ PK11_R_GENERATERANDOM,               "C_GenerateRandom failed"},
4867 +{ PK11_R_INVALID_MESSAGE_LENGTH,       "invalid message length"},
4868 +{ PK11_R_UNKNOWN_ALGORITHM_TYPE,       "unknown algorithm type"},
4869 +{ PK11_R_UNKNOWN_ASN1_OBJECT_ID,       "unknown asn1 onject id"},
4870 +{ PK11_R_UNKNOWN_PADDING_TYPE,         "unknown padding type"},
4871 +{ PK11_R_PADDING_CHECK_FAILED,         "padding check failed"},
4872 +{ PK11_R_DIGEST_TOO_BIG,               "digest too big"},
4873 +{ PK11_R_MALLOC_FAILURE,               "malloc failure"},
4874 +{ PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED, "ctl command not implemented"},
4875 +{ PK11_R_DATA_GREATER_THAN_MOD_LEN,    "data is bigger than mod"},
4876 +{ PK11_R_DATA_TOO_LARGE_FOR_MODULUS,   "data is too larger for mod"},
4877 +{ PK11_R_MISSING_KEY_COMPONENT,                "a dsa component is missing"},
4878 +{ PK11_R_INVALID_SIGNATURE_LENGTH,     "invalid signature length"},
4879 +{ PK11_R_INVALID_DSA_SIGNATURE_R,      "missing r in dsa verify"},
4880 +{ PK11_R_INVALID_DSA_SIGNATURE_S,      "missing s in dsa verify"},
4881 +{ PK11_R_INCONSISTENT_KEY,             "inconsistent key type"},
4882 +{ PK11_R_ENCRYPTUPDATE,                        "C_EncryptUpdate failed"},
4883 +{ PK11_R_DECRYPTUPDATE,                        "C_DecryptUpdate failed"},
4884 +{ PK11_R_DIGESTINIT,                   "C_DigestInit failed"},
4885 +{ PK11_R_DIGESTUPDATE,                 "C_DigestUpdate failed"},
4886 +{ PK11_R_DIGESTFINAL,                  "C_DigestFinal failed"},
4887 +{ PK11_R_ENCRYPTFINAL,                 "C_EncryptFinal failed"},
4888 +{ PK11_R_DECRYPTFINAL,                 "C_DecryptFinal failed"},
4889 +{ PK11_R_NO_PRNG_SUPPORT,              "Slot does not support PRNG"},
4890 +{ PK11_R_GETTOKENINFO,                 "C_GetTokenInfo failed"},
4891 +{ PK11_R_DERIVEKEY,                    "C_DeriveKey failed"},
4892 +{ PK11_R_GET_OPERATION_STATE,          "C_GetOperationState failed"},
4893 +{ PK11_R_SET_OPERATION_STATE,          "C_SetOperationState failed"},
4894 +{ PK11_R_INVALID_PIN,                  "invalid PIN"},
4895 +{ PK11_R_TOO_MANY_OBJECTS,             "too many objects"},
4896 +{ PK11_R_OBJECT_NOT_FOUND,             "object not found"},
4897 +{ PK11_R_INVALID_HANDLE,               "invalid PKCS#11 object handle"},
4898 +{ PK11_R_KEY_OR_IV_LEN_PROBLEM,                "IV or key length incorrect"},
4899 +{ PK11_R_INVALID_OPERATION_TYPE,       "invalid operation type"},
4900 +{ PK11_R_ADD_NID_FAILED,               "failed to add NID" },
4901 +{ 0,   NULL}
4903 +#endif /* OPENSSL_NO_ERR */
4905 +static int pk11_lib_error_code = 0;
4906 +static int pk11_error_init = 1;
4908 +static void
4909 +ERR_load_pk11_strings(void)
4910 +       {
4911 +       if (pk11_lib_error_code == 0)
4912 +               pk11_lib_error_code = ERR_get_next_error_library();
4914 +       if (pk11_error_init)
4915 +               {
4916 +               pk11_error_init = 0;
4917 +#ifndef OPENSSL_NO_ERR
4918 +               ERR_load_strings(pk11_lib_error_code, pk11_str_functs);
4919 +               ERR_load_strings(pk11_lib_error_code, pk11_str_reasons);
4920 +#endif
4921 +               }
4924 +static void
4925 +ERR_unload_pk11_strings(void)
4926 +       {
4927 +       if (pk11_error_init == 0)
4928 +               {
4929 +#ifndef OPENSSL_NO_ERR
4930 +               ERR_unload_strings(pk11_lib_error_code, pk11_str_functs);
4931 +               ERR_unload_strings(pk11_lib_error_code, pk11_str_reasons);
4932 +#endif
4933 +               pk11_error_init = 1;
4934 +               }
4937 +void
4938 +ERR_pk11_error(int function, int reason, char *file, int line)
4940 +       if (pk11_lib_error_code == 0)
4941 +               pk11_lib_error_code = ERR_get_next_error_library();
4942 +       ERR_PUT_error(pk11_lib_error_code, function, reason, file, line);
4945 +void
4946 +PK11err_add_data(int function, int reason, CK_RV rv)
4948 +       char tmp_buf[20];
4950 +       PK11err(function, reason);
4951 +       (void) BIO_snprintf(tmp_buf, sizeof (tmp_buf), "%lx", rv);
4952 +       ERR_add_error_data(2, "PK11 CK_RV=0X", tmp_buf);
4954 Index: openssl/crypto/engine/hw_pk11_err.h
4955 diff -u /dev/null openssl/crypto/engine/hw_pk11_err.h:1.9
4956 --- /dev/null   Mon Oct  5 13:17:24 2009
4957 +++ openssl/crypto/engine/hw_pk11_err.h Wed Dec 17 15:01:45 2008
4958 @@ -0,0 +1,402 @@
4960 + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
4961 + * Use is subject to license terms.
4962 + */
4964 +/* crypto/engine/hw_pk11_err.h */
4966 + * This product includes software developed by the OpenSSL Project for
4967 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
4968 + *
4969 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
4970 + * Afchine Madjlessi.
4971 + */
4973 + * ====================================================================
4974 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
4975 + *
4976 + * Redistribution and use in source and binary forms, with or without
4977 + * modification, are permitted provided that the following conditions
4978 + * are met:
4979 + *
4980 + * 1. Redistributions of source code must retain the above copyright
4981 + *    notice, this list of conditions and the following disclaimer.
4982 + *
4983 + * 2. Redistributions in binary form must reproduce the above copyright
4984 + *    notice, this list of conditions and the following disclaimer in
4985 + *    the documentation and/or other materials provided with the
4986 + *    distribution.
4987 + *
4988 + * 3. All advertising materials mentioning features or use of this
4989 + *    software must display the following acknowledgment:
4990 + *    "This product includes software developed by the OpenSSL Project
4991 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
4992 + *
4993 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
4994 + *    endorse or promote products derived from this software without
4995 + *    prior written permission. For written permission, please contact
4996 + *    licensing@OpenSSL.org.
4997 + *
4998 + * 5. Products derived from this software may not be called "OpenSSL"
4999 + *    nor may "OpenSSL" appear in their names without prior written
5000 + *    permission of the OpenSSL Project.
5001 + *
5002 + * 6. Redistributions of any form whatsoever must retain the following
5003 + *    acknowledgment:
5004 + *    "This product includes software developed by the OpenSSL Project
5005 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
5006 + *
5007 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
5008 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5009 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
5010 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
5011 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
5012 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
5013 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5014 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5015 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
5016 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
5017 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
5018 + * OF THE POSSIBILITY OF SUCH DAMAGE.
5019 + * ====================================================================
5020 + *
5021 + * This product includes cryptographic software written by Eric Young
5022 + * (eay@cryptsoft.com).  This product includes software written by Tim
5023 + * Hudson (tjh@cryptsoft.com).
5024 + *
5025 + */
5027 +#ifndef        HW_PK11_ERR_H
5028 +#define        HW_PK11_ERR_H
5030 +void ERR_pk11_error(int function, int reason, char *file, int line);
5031 +void PK11err_add_data(int function, int reason, CK_RV rv);
5032 +#define        PK11err(f, r)   ERR_pk11_error((f), (r), __FILE__, __LINE__)
5034 +/* Error codes for the PK11 functions. */
5036 +/* Function codes. */
5038 +#define        PK11_F_INIT                             100
5039 +#define        PK11_F_FINISH                           101
5040 +#define        PK11_F_DESTROY                          102
5041 +#define        PK11_F_CTRL                             103
5042 +#define        PK11_F_RSA_INIT                         104
5043 +#define        PK11_F_RSA_FINISH                       105
5044 +#define        PK11_F_GET_PUB_RSA_KEY                  106
5045 +#define        PK11_F_GET_PRIV_RSA_KEY                 107
5046 +#define        PK11_F_RSA_GEN_KEY                      108
5047 +#define        PK11_F_RSA_PUB_ENC                      109
5048 +#define        PK11_F_RSA_PRIV_ENC                     110
5049 +#define        PK11_F_RSA_PUB_DEC                      111
5050 +#define        PK11_F_RSA_PRIV_DEC                     112
5051 +#define        PK11_F_RSA_SIGN                         113
5052 +#define        PK11_F_RSA_VERIFY                       114
5053 +#define        PK11_F_RAND_ADD                         115
5054 +#define        PK11_F_RAND_BYTES                       116
5055 +#define        PK11_F_GET_SESSION                      117
5056 +#define        PK11_F_FREE_SESSION                     118
5057 +#define        PK11_F_LOAD_PUBKEY                      119
5058 +#define        PK11_F_LOAD_PRIVKEY                     120
5059 +#define        PK11_F_RSA_PUB_ENC_LOW                  121
5060 +#define        PK11_F_RSA_PRIV_ENC_LOW                 122
5061 +#define        PK11_F_RSA_PUB_DEC_LOW                  123
5062 +#define        PK11_F_RSA_PRIV_DEC_LOW                 124
5063 +#define        PK11_F_DSA_SIGN                         125
5064 +#define        PK11_F_DSA_VERIFY                       126
5065 +#define        PK11_F_DSA_INIT                         127
5066 +#define        PK11_F_DSA_FINISH                       128
5067 +#define        PK11_F_GET_PUB_DSA_KEY                  129
5068 +#define        PK11_F_GET_PRIV_DSA_KEY                 130
5069 +#define        PK11_F_DH_INIT                          131
5070 +#define        PK11_F_DH_FINISH                        132
5071 +#define        PK11_F_MOD_EXP_DH                       133
5072 +#define        PK11_F_GET_DH_KEY                       134
5073 +#define        PK11_F_FREE_ALL_SESSIONS                135
5074 +#define        PK11_F_SETUP_SESSION                    136
5075 +#define        PK11_F_DESTROY_OBJECT                   137
5076 +#define        PK11_F_CIPHER_INIT                      138
5077 +#define        PK11_F_CIPHER_DO_CIPHER                 139
5078 +#define        PK11_F_GET_CIPHER_KEY                   140
5079 +#define        PK11_F_DIGEST_INIT                      141
5080 +#define        PK11_F_DIGEST_UPDATE                    142
5081 +#define        PK11_F_DIGEST_FINAL                     143
5082 +#define        PK11_F_CHOOSE_SLOT                      144
5083 +#define        PK11_F_CIPHER_FINAL                     145
5084 +#define        PK11_F_LIBRARY_INIT                     146
5085 +#define        PK11_F_LOAD                             147
5086 +#define        PK11_F_DH_GEN_KEY                       148
5087 +#define        PK11_F_DH_COMP_KEY                      149
5088 +#define        PK11_F_DIGEST_COPY                      150
5089 +#define        PK11_F_CIPHER_CLEANUP                   151
5090 +#define        PK11_F_ACTIVE_ADD                       152
5091 +#define        PK11_F_ACTIVE_DELETE                    153
5092 +#define        PK11_F_CHECK_HW_MECHANISMS              154
5093 +#define        PK11_F_INIT_SYMMETRIC                   155
5094 +#define        PK11_F_ADD_AES_CTR_NIDS                 156
5095 +#define        PK11_F_INIT_ALL_LOCKS                   157
5096 +#define        PK11_F_RETURN_SESSION                   158
5098 +/* Reason codes. */
5099 +#define        PK11_R_ALREADY_LOADED                   100
5100 +#define        PK11_R_DSO_FAILURE                      101
5101 +#define        PK11_R_NOT_LOADED                       102
5102 +#define        PK11_R_PASSED_NULL_PARAMETER            103
5103 +#define        PK11_R_COMMAND_NOT_IMPLEMENTED          104
5104 +#define        PK11_R_INITIALIZE                       105
5105 +#define        PK11_R_FINALIZE                         106
5106 +#define        PK11_R_GETINFO                          107
5107 +#define        PK11_R_GETSLOTLIST                      108
5108 +#define        PK11_R_NO_MODULUS_OR_NO_EXPONENT        109
5109 +#define        PK11_R_ATTRIBUT_SENSITIVE_OR_INVALID    110
5110 +#define        PK11_R_GETATTRIBUTVALUE                 111
5111 +#define        PK11_R_NO_MODULUS                       112
5112 +#define        PK11_R_NO_EXPONENT                      113
5113 +#define        PK11_R_FINDOBJECTSINIT                  114
5114 +#define        PK11_R_FINDOBJECTS                      115
5115 +#define        PK11_R_FINDOBJECTSFINAL                 116
5116 +#define        PK11_R_CREATEOBJECT                     118
5117 +#define        PK11_R_DESTROYOBJECT                    119
5118 +#define        PK11_R_OPENSESSION                      120
5119 +#define        PK11_R_CLOSESESSION                     121
5120 +#define        PK11_R_ENCRYPTINIT                      122
5121 +#define        PK11_R_ENCRYPT                          123
5122 +#define        PK11_R_SIGNINIT                         124
5123 +#define        PK11_R_SIGN                             125
5124 +#define        PK11_R_DECRYPTINIT                      126
5125 +#define        PK11_R_DECRYPT                          127
5126 +#define        PK11_R_VERIFYINIT                       128
5127 +#define        PK11_R_VERIFY                           129
5128 +#define        PK11_R_VERIFYRECOVERINIT                130
5129 +#define        PK11_R_VERIFYRECOVER                    131
5130 +#define        PK11_R_GEN_KEY                          132
5131 +#define        PK11_R_SEEDRANDOM                       133
5132 +#define        PK11_R_GENERATERANDOM                   134
5133 +#define        PK11_R_INVALID_MESSAGE_LENGTH           135
5134 +#define        PK11_R_UNKNOWN_ALGORITHM_TYPE           136
5135 +#define        PK11_R_UNKNOWN_ASN1_OBJECT_ID           137
5136 +#define        PK11_R_UNKNOWN_PADDING_TYPE             138
5137 +#define        PK11_R_PADDING_CHECK_FAILED             139
5138 +#define        PK11_R_DIGEST_TOO_BIG                   140
5139 +#define        PK11_R_MALLOC_FAILURE                   141
5140 +#define        PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED     142
5141 +#define        PK11_R_DATA_GREATER_THAN_MOD_LEN        143
5142 +#define        PK11_R_DATA_TOO_LARGE_FOR_MODULUS       144
5143 +#define        PK11_R_MISSING_KEY_COMPONENT            145
5144 +#define        PK11_R_INVALID_SIGNATURE_LENGTH         146
5145 +#define        PK11_R_INVALID_DSA_SIGNATURE_R          147
5146 +#define        PK11_R_INVALID_DSA_SIGNATURE_S          148
5147 +#define        PK11_R_INCONSISTENT_KEY                 149
5148 +#define        PK11_R_ENCRYPTUPDATE                    150
5149 +#define        PK11_R_DECRYPTUPDATE                    151
5150 +#define        PK11_R_DIGESTINIT                       152
5151 +#define        PK11_R_DIGESTUPDATE                     153
5152 +#define        PK11_R_DIGESTFINAL                      154
5153 +#define        PK11_R_ENCRYPTFINAL                     155
5154 +#define        PK11_R_DECRYPTFINAL                     156
5155 +#define        PK11_R_NO_PRNG_SUPPORT                  157
5156 +#define        PK11_R_GETTOKENINFO                     158
5157 +#define        PK11_R_DERIVEKEY                        159
5158 +#define        PK11_R_GET_OPERATION_STATE              160
5159 +#define        PK11_R_SET_OPERATION_STATE              161
5160 +#define        PK11_R_INVALID_HANDLE                   162
5161 +#define        PK11_R_KEY_OR_IV_LEN_PROBLEM            163
5162 +#define        PK11_R_INVALID_OPERATION_TYPE           164
5163 +#define        PK11_R_ADD_NID_FAILED                   165
5164 +#define        PK11_R_ATFORK_FAILED                    166
5165 +#define        PK11_R_INVALID_PIN                      167
5166 +#define        PK11_R_TOO_MANY_OBJECTS                 168
5167 +#define        PK11_R_OBJECT_NOT_FOUND                 169
5169 +/* max byte length of a symetric key we support */
5170 +#define        PK11_KEY_LEN_MAX                        32
5172 +#ifdef NOPTHREADS
5174 + * CRYPTO_LOCK_PK11_ENGINE lock is primarily used for the protection of the
5175 + * free_session list and active_list but generally serves as a global
5176 + * per-process lock for the whole engine.
5177 + *
5178 + * We reuse CRYPTO_LOCK_EC lock (which is defined in OpenSSL for EC method) as
5179 + * the global engine lock. This is not optimal w.r.t. performance but
5180 + * it's safe.
5181 + */
5182 +#define CRYPTO_LOCK_PK11_ENGINE        CRYPTO_LOCK_EC
5183 +#endif
5186 + * This structure encapsulates all reusable information for a PKCS#11
5187 + * session. A list of these objects is created on behalf of the
5188 + * calling application using an on-demand method. Each operation
5189 + * type (see PK11_OPTYPE below) has its own per-process list.
5190 + * Each of the lists is basically a cache for faster PKCS#11 object
5191 + * access to avoid expensive C_Find{,Init,Final}Object() calls.
5192 + *
5193 + * When a new request comes in, an object will be taken from the list
5194 + * (if there is one) or a new one is created to handle the request
5195 + * (if the list is empty). See pk11_get_session() on how it is done.
5196 + */
5197 +typedef struct PK11_st_SESSION
5198 +       {
5199 +       struct PK11_st_SESSION  *next;
5200 +       CK_SESSION_HANDLE       session;        /* PK11 session handle */
5201 +       pid_t                   pid;            /* Current process ID */
5202 +       union
5203 +               {
5204 +#ifndef OPENSSL_NO_RSA
5205 +               struct
5206 +                       {
5207 +                       CK_OBJECT_HANDLE        rsa_pub_key; /* pub handle */
5208 +                       CK_OBJECT_HANDLE        rsa_priv_key; /* priv handle */
5209 +                       RSA                     *rsa_pub; /* pub key addr */
5210 +                       BIGNUM                  *rsa_n_num; /* pub modulus */
5211 +                       BIGNUM                  *rsa_e_num; /* pub exponent */
5212 +                       RSA                     *rsa_priv; /* priv key addr */
5213 +                       BIGNUM                  *rsa_d_num; /* priv exponent */
5214 +                       } u_RSA;
5215 +#endif /* OPENSSL_NO_RSA */
5216 +#ifndef OPENSSL_NO_DSA
5217 +               struct
5218 +                       {
5219 +                       CK_OBJECT_HANDLE        dsa_pub_key; /* pub handle */
5220 +                       CK_OBJECT_HANDLE        dsa_priv_key; /* priv handle */
5221 +                       DSA                     *dsa_pub; /* pub key addr */
5222 +                       BIGNUM                  *dsa_pub_num; /* pub key */
5223 +                       DSA                     *dsa_priv; /* priv key addr */
5224 +                       BIGNUM                  *dsa_priv_num; /* priv key */
5225 +                       } u_DSA;
5226 +#endif /* OPENSSL_NO_DSA */
5227 +#ifndef OPENSSL_NO_DH
5228 +               struct
5229 +                       {
5230 +                       CK_OBJECT_HANDLE        dh_key; /* key handle */
5231 +                       DH                      *dh; /* dh key addr */
5232 +                       BIGNUM                  *dh_priv_num; /* priv dh key */
5233 +                       } u_DH;
5234 +#endif /* OPENSSL_NO_DH */
5235 +               struct
5236 +                       {
5237 +                       CK_OBJECT_HANDLE        cipher_key; /* key handle */
5238 +                       unsigned char           key[PK11_KEY_LEN_MAX];
5239 +                       int                     key_len; /* priv key len */
5240 +                       int                     encrypt; /* 1/0 enc/decr */
5241 +                       } u_cipher;
5242 +               } opdata_u;
5243 +       } PK11_SESSION;
5245 +#define        opdata_rsa_pub_key      opdata_u.u_RSA.rsa_pub_key
5246 +#define        opdata_rsa_priv_key     opdata_u.u_RSA.rsa_priv_key
5247 +#define        opdata_rsa_pub          opdata_u.u_RSA.rsa_pub
5248 +#define        opdata_rsa_priv         opdata_u.u_RSA.rsa_priv
5249 +#define        opdata_rsa_n_num        opdata_u.u_RSA.rsa_n_num
5250 +#define        opdata_rsa_e_num        opdata_u.u_RSA.rsa_e_num
5251 +#define        opdata_rsa_d_num        opdata_u.u_RSA.rsa_d_num
5252 +#define        opdata_dsa_pub_key      opdata_u.u_DSA.dsa_pub_key
5253 +#define        opdata_dsa_priv_key     opdata_u.u_DSA.dsa_priv_key
5254 +#define        opdata_dsa_pub          opdata_u.u_DSA.dsa_pub
5255 +#define        opdata_dsa_pub_num      opdata_u.u_DSA.dsa_pub_num
5256 +#define        opdata_dsa_priv         opdata_u.u_DSA.dsa_priv
5257 +#define        opdata_dsa_priv_num     opdata_u.u_DSA.dsa_priv_num
5258 +#define        opdata_dh_key           opdata_u.u_DH.dh_key
5259 +#define        opdata_dh               opdata_u.u_DH.dh
5260 +#define        opdata_dh_priv_num      opdata_u.u_DH.dh_priv_num
5261 +#define        opdata_cipher_key       opdata_u.u_cipher.cipher_key
5262 +#define        opdata_key              opdata_u.u_cipher.key
5263 +#define        opdata_key_len          opdata_u.u_cipher.key_len
5264 +#define        opdata_encrypt          opdata_u.u_cipher.encrypt
5267 + * We have 3 different groups of operation types:
5268 + *   1) asymmetric operations
5269 + *   2) random operations
5270 + *   3) symmetric and digest operations
5271 + *
5272 + * This division into groups stems from the fact that it's common that hardware
5273 + * providers may support operations from one group only. For example, hardware
5274 + * providers on UltraSPARC T2, n2rng(7d), ncp(7d), and n2cp(7d), each support
5275 + * only a single group of operations.
5276 + *
5277 + * For every group a different slot can be chosen. That means that we must have
5278 + * at least 3 different lists of cached PKCS#11 sessions since sessions from
5279 + * different groups may be initialized in different slots.
5280 + *
5281 + * To provide locking granularity in multithreaded environment, the groups are
5282 + * further splitted into types with each type having a separate session cache.
5283 + */
5284 +typedef enum PK11_OPTYPE_ENUM
5285 +       {
5286 +       OP_RAND,
5287 +       OP_RSA,
5288 +       OP_DSA,
5289 +       OP_DH,
5290 +       OP_CIPHER,
5291 +       OP_DIGEST,
5292 +       OP_MAX
5293 +       } PK11_OPTYPE;
5296 + * This structure contains the heads of the lists forming the object caches
5297 + * and locks associated with the lists.
5298 + */
5299 +typedef struct PK11_st_CACHE
5300 +       {
5301 +       PK11_SESSION *head;
5302 +#ifndef NOPTHREADS
5303 +       pthread_mutex_t *lock;
5304 +#endif
5305 +       } PK11_CACHE;
5307 +/* structure for tracking handles of asymmetric key objects */
5308 +typedef struct PK11_active_st
5309 +       {
5310 +       CK_OBJECT_HANDLE h;
5311 +       unsigned int refcnt;
5312 +       struct PK11_active_st *prev;
5313 +       struct PK11_active_st *next;
5314 +       } PK11_active;
5316 +#ifndef NOPTHREADS
5317 +extern pthread_mutex_t *find_lock[];
5318 +#endif
5319 +extern PK11_active *active_list[];
5321 +#ifndef NOPTHREADS
5322 +#define        LOCK_OBJSTORE(alg_type) \
5323 +       (void) pthread_mutex_lock(find_lock[alg_type])
5324 +#define        UNLOCK_OBJSTORE(alg_type)       \
5325 +       (void) pthread_mutex_unlock(find_lock[alg_type])
5326 +#else
5327 +#define        LOCK_OBJSTORE(alg_type) \
5328 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE)
5329 +#define        UNLOCK_OBJSTORE(alg_type)       \
5330 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE)
5331 +#endif
5333 +extern PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
5334 +extern void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
5336 +#ifndef OPENSSL_NO_RSA
5337 +extern int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
5338 +extern int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
5339 +extern int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
5340 +extern EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *pubkey_file,
5341 +       UI_METHOD *ui_method, void *callback_data);
5342 +extern EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
5343 +       UI_METHOD *ui_method, void *callback_data);
5344 +extern RSA_METHOD *PK11_RSA(void);
5345 +#endif /* OPENSSL_NO_RSA */
5346 +#ifndef OPENSSL_NO_DSA
5347 +extern int pk11_destroy_dsa_key_objects(PK11_SESSION *session);
5348 +extern int pk11_destroy_dsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
5349 +extern int pk11_destroy_dsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
5350 +extern DSA_METHOD *PK11_DSA(void);
5351 +#endif /* OPENSSL_NO_DSA */
5352 +#ifndef OPENSSL_NO_DH
5353 +extern int pk11_destroy_dh_key_objects(PK11_SESSION *session);
5354 +extern int pk11_destroy_dh_object(PK11_SESSION *sp, CK_BBOOL uselock);
5355 +extern DH_METHOD *PK11_DH(void);
5356 +#endif /* OPENSSL_NO_DH */
5358 +extern CK_FUNCTION_LIST_PTR pFuncList;
5360 +#endif /* HW_PK11_ERR_H */
5361 Index: openssl/crypto/engine/hw_pk11_pub.c
5362 diff -u /dev/null openssl/crypto/engine/hw_pk11_pub.c:1.32
5363 --- /dev/null   Mon Oct  5 13:17:24 2009
5364 +++ openssl/crypto/engine/hw_pk11_pub.c Mon Oct  5 13:16:55 2009
5365 @@ -0,0 +1,3140 @@
5367 + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
5368 + * Use is subject to license terms.
5369 + */
5371 +/* crypto/engine/hw_pk11_pub.c */
5373 + * This product includes software developed by the OpenSSL Project for
5374 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
5375 + *
5376 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
5377 + * Afchine Madjlessi.
5378 + */
5380 + * ====================================================================
5381 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
5382 + *
5383 + * Redistribution and use in source and binary forms, with or without
5384 + * modification, are permitted provided that the following conditions
5385 + * are met:
5386 + *
5387 + * 1. Redistributions of source code must retain the above copyright
5388 + *    notice, this list of conditions and the following disclaimer.
5389 + *
5390 + * 2. Redistributions in binary form must reproduce the above copyright
5391 + *    notice, this list of conditions and the following disclaimer in
5392 + *    the documentation and/or other materials provided with the
5393 + *    distribution.
5394 + *
5395 + * 3. All advertising materials mentioning features or use of this
5396 + *    software must display the following acknowledgment:
5397 + *    "This product includes software developed by the OpenSSL Project
5398 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
5399 + *
5400 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
5401 + *    endorse or promote products derived from this software without
5402 + *    prior written permission. For written permission, please contact
5403 + *    licensing@OpenSSL.org.
5404 + *
5405 + * 5. Products derived from this software may not be called "OpenSSL"
5406 + *    nor may "OpenSSL" appear in their names without prior written
5407 + *    permission of the OpenSSL Project.
5408 + *
5409 + * 6. Redistributions of any form whatsoever must retain the following
5410 + *    acknowledgment:
5411 + *    "This product includes software developed by the OpenSSL Project
5412 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
5413 + *
5414 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
5415 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
5416 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
5417 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
5418 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
5419 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
5420 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
5421 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
5422 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
5423 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
5424 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
5425 + * OF THE POSSIBILITY OF SUCH DAMAGE.
5426 + * ====================================================================
5427 + *
5428 + * This product includes cryptographic software written by Eric Young
5429 + * (eay@cryptsoft.com).  This product includes software written by Tim
5430 + * Hudson (tjh@cryptsoft.com).
5431 + *
5432 + */
5434 +#include <stdio.h>
5435 +#include <stdlib.h>
5436 +#include <string.h>
5437 +#include <sys/types.h>
5439 +#include <openssl/e_os2.h>
5440 +#include <openssl/crypto.h>
5441 +#include <cryptlib.h>
5442 +#include <openssl/engine.h>
5443 +#include <openssl/dso.h>
5444 +#include <openssl/err.h>
5445 +#include <openssl/bn.h>
5446 +#include <openssl/pem.h>
5447 +#ifndef OPENSSL_NO_RSA
5448 +#include <openssl/rsa.h>
5449 +#endif /* OPENSSL_NO_RSA */
5450 +#ifndef OPENSSL_NO_DSA
5451 +#include <openssl/dsa.h>
5452 +#endif /* OPENSSL_NO_DSA */
5453 +#ifndef OPENSSL_NO_DH
5454 +#include <openssl/dh.h>
5455 +#endif /* OPENSSL_NO_DH */
5456 +#include <openssl/rand.h>
5457 +#include <openssl/objects.h>
5458 +#include <openssl/x509.h>
5460 +#ifdef OPENSSL_SYS_WIN32
5461 +#define NOPTHREADS
5462 +typedef int pid_t;
5463 +#define HAVE_GETPASSPHRASE
5464 +static char *getpassphrase(const char *prompt);
5465 +#ifndef NULL_PTR
5466 +#define NULL_PTR NULL
5467 +#endif
5468 +#define CK_DEFINE_FUNCTION(returnType, name) \
5469 +       returnType __declspec(dllexport) name
5470 +#define CK_DECLARE_FUNCTION(returnType, name) \
5471 +       returnType __declspec(dllimport) name
5472 +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
5473 +       returnType __declspec(dllimport) (* name)
5474 +#else
5475 +#include <unistd.h>
5476 +#endif
5478 +#ifndef NOPTHREADS
5479 +#include <pthread.h>
5480 +#endif
5482 +#ifndef OPENSSL_NO_HW
5483 +#ifndef OPENSSL_NO_HW_PK11
5484 +#ifndef OPENSSL_NO_HW_PK11CA
5486 +#ifdef OPENSSL_SYS_WIN32
5487 +#pragma pack(push, cryptoki, 1)
5488 +#include "cryptoki.h"
5489 +#include "pkcs11.h"
5490 +#pragma pack(pop, cryptoki)
5491 +#else
5492 +#include "cryptoki.h"
5493 +#include "pkcs11.h"
5494 +#endif
5495 +#include "hw_pk11ca.h"
5496 +#include "hw_pk11_err.h"
5498 +#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun)))
5499 +#define getpassphrase(x)       getpass(x)
5500 +#endif
5502 +#ifndef OPENSSL_NO_RSA
5503 +/* RSA stuff */
5504 +static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
5505 +       unsigned char *to, RSA *rsa, int padding);
5506 +static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
5507 +       unsigned char *to, RSA *rsa, int padding);
5508 +static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
5509 +       unsigned char *to, RSA *rsa, int padding);
5510 +static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
5511 +       unsigned char *to, RSA *rsa, int padding);
5512 +static int pk11_RSA_init(RSA *rsa);
5513 +static int pk11_RSA_finish(RSA *rsa);
5514 +static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
5515 +       unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
5516 +static int pk11_RSA_verify(int dtype, const unsigned char *m,
5517 +       unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
5518 +       const RSA *rsa);
5519 +EVP_PKEY *pk11_load_privkey(ENGINE*, const char *pubkey_file,
5520 +       UI_METHOD *ui_method, void *callback_data);
5521 +EVP_PKEY *pk11_load_pubkey(ENGINE*, const char *pubkey_file,
5522 +       UI_METHOD *ui_method, void *callback_data);
5524 +static int pk11_RSA_public_encrypt_low(int flen, const unsigned char *from,
5525 +       unsigned char *to, RSA *rsa);
5526 +static int pk11_RSA_private_encrypt_low(int flen, const unsigned char *from,
5527 +       unsigned char *to, RSA *rsa);
5528 +static int pk11_RSA_public_decrypt_low(int flen, const unsigned char *from,
5529 +       unsigned char *to, RSA *rsa);
5530 +static int pk11_RSA_private_decrypt_low(int flen, const unsigned char *from,
5531 +       unsigned char *to, RSA *rsa);
5533 +static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA* rsa, RSA** key_ptr,
5534 +       BIGNUM **rsa_n_num, BIGNUM **rsa_e_num, CK_SESSION_HANDLE session);
5535 +static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa, RSA** key_ptr,
5536 +       BIGNUM **rsa_d_num, CK_SESSION_HANDLE session);
5538 +static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa);
5539 +static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa);
5540 +#endif
5542 +/* DSA stuff */
5543 +#ifndef OPENSSL_NO_DSA
5544 +static int pk11_DSA_init(DSA *dsa);
5545 +static int pk11_DSA_finish(DSA *dsa);
5546 +static DSA_SIG *pk11_dsa_do_sign(const unsigned char *dgst, int dlen,
5547 +       DSA *dsa);
5548 +static int pk11_dsa_do_verify(const unsigned char *dgst, int dgst_len,
5549 +       DSA_SIG *sig, DSA *dsa);
5551 +static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa, DSA **key_ptr,
5552 +       BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session);
5553 +static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa, DSA **key_ptr,
5554 +       BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session);
5556 +static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa);
5557 +static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa);
5558 +#endif
5560 +/* DH stuff */
5561 +#ifndef OPENSSL_NO_DH
5562 +static int pk11_DH_init(DH *dh);
5563 +static int pk11_DH_finish(DH *dh);
5564 +static int pk11_DH_generate_key(DH *dh);
5565 +static int pk11_DH_compute_key(unsigned char *key,
5566 +       const BIGNUM *pub_key, DH *dh);
5568 +static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh, DH **key_ptr,
5569 +       BIGNUM **priv_key, CK_SESSION_HANDLE session);
5571 +static int check_new_dh_key(PK11_SESSION *sp, DH *dh);
5572 +#endif
5574 +static int init_template_value(BIGNUM *bn, CK_VOID_PTR *pValue,
5575 +       CK_ULONG *ulValueLen);
5576 +static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn);
5578 +/* Read mode string to be used for fopen() */
5579 +#if SOLARIS_OPENSSL
5580 +static char *read_mode_flags = "rF";
5581 +#else
5582 +static char *read_mode_flags = "r";
5583 +#endif
5586 + * increment/create reference for an asymmetric key handle via active list
5587 + * manipulation. If active list operation fails, unlock (if locked), set error
5588 + * variable and jump to the specified label.
5589 + */
5590 +#define        KEY_HANDLE_REFHOLD(key_handle, alg_type, unlock, var, label)    \
5591 +       {                                                               \
5592 +       if (pk11_active_add(key_handle, alg_type) < 0)                  \
5593 +               {                                                       \
5594 +               var = TRUE;                                             \
5595 +               if (unlock)                                             \
5596 +                       UNLOCK_OBJSTORE(alg_type);                      \
5597 +               goto label;                                             \
5598 +               }                                                       \
5599 +       }
5602 + * Find active list entry according to object handle and return pointer to the
5603 + * entry otherwise return NULL.
5604 + *
5605 + * This function presumes it is called with lock protecting the active list
5606 + * held.
5607 + */
5608 +static PK11_active *pk11_active_find(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
5609 +       {
5610 +       PK11_active *entry;
5612 +       for (entry = active_list[type]; entry != NULL; entry = entry->next)
5613 +               if (entry->h == h)
5614 +                       return (entry);
5616 +       return (NULL);
5617 +       }
5620 + * Search for an entry in the active list using PKCS#11 object handle as a
5621 + * search key and return refcnt of the found/created entry or -1 in case of
5622 + * failure.
5623 + *
5624 + * This function presumes it is called with lock protecting the active list
5625 + * held.
5626 + */
5627 +int
5628 +pk11_active_add(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
5629 +       {
5630 +       PK11_active *entry = NULL;
5632 +       if (h == CK_INVALID_HANDLE)
5633 +               {
5634 +               PK11err(PK11_F_ACTIVE_ADD, PK11_R_INVALID_HANDLE);
5635 +               return (-1);
5636 +               }
5638 +       /* search for entry in the active list */
5639 +       if ((entry = pk11_active_find(h, type)) != NULL)
5640 +               entry->refcnt++;
5641 +       else
5642 +               {
5643 +               /* not found, create new entry and add it to the list */
5644 +               entry = OPENSSL_malloc(sizeof (PK11_active));
5645 +               if (entry == NULL)
5646 +                       {
5647 +                       PK11err(PK11_F_ACTIVE_ADD, PK11_R_MALLOC_FAILURE);
5648 +                       return (-1);
5649 +                       }
5650 +               entry->h = h;
5651 +               entry->refcnt = 1;
5652 +               entry->prev = NULL;
5653 +               entry->next = NULL;
5654 +               /* connect the newly created entry to the list */
5655 +               if (active_list[type] == NULL)
5656 +                       active_list[type] = entry;
5657 +               else /* make the entry first in the list */
5658 +                       {
5659 +                       entry->next = active_list[type];
5660 +                       active_list[type]->prev = entry;
5661 +                       active_list[type] = entry;
5662 +                       }
5663 +               }
5665 +       return (entry->refcnt);
5666 +       }
5669 + * Remove active list entry from the list and free it.
5670 + *
5671 + * This function presumes it is called with lock protecting the active list
5672 + * held.
5673 + */
5674 +void
5675 +pk11_active_remove(PK11_active *entry, PK11_OPTYPE type)
5676 +       {
5677 +       PK11_active *prev_entry;
5679 +       /* remove the entry from the list and free it */
5680 +       if ((prev_entry = entry->prev) != NULL)
5681 +               {
5682 +               prev_entry->next = entry->next;
5683 +               if (entry->next != NULL)
5684 +                       entry->next->prev = prev_entry;
5685 +               }
5686 +       else
5687 +               {
5688 +               active_list[type] = entry->next;
5689 +               /* we were the first but not the only one */
5690 +               if (entry->next != NULL)
5691 +                       entry->next->prev = NULL;
5692 +               }
5694 +       /* sanitization */
5695 +       entry->h = CK_INVALID_HANDLE;
5696 +       entry->prev = NULL;
5697 +       entry->next = NULL;
5698 +       OPENSSL_free(entry);
5699 +       }
5701 +/* Free all entries from the active list. */
5702 +void
5703 +pk11_free_active_list(PK11_OPTYPE type)
5704 +       {
5705 +       PK11_active *entry;
5707 +       /* only for asymmetric types since only they have C_Find* locks. */
5708 +       switch (type)
5709 +               {
5710 +               case OP_RSA:
5711 +               case OP_DSA:
5712 +               case OP_DH:
5713 +                       break;
5714 +               default:
5715 +                       return;
5716 +               }
5718 +       /* see find_lock array definition for more info on object locking */
5719 +       LOCK_OBJSTORE(type);
5720 +       while ((entry = active_list[type]) != NULL)
5721 +               pk11_active_remove(entry, type);
5722 +       UNLOCK_OBJSTORE(type);
5723 +       }
5726 + * Search for active list entry associated with given PKCS#11 object handle,
5727 + * decrement its refcnt and if it drops to 0, disconnect the entry and free it.
5728 + *
5729 + * Return 1 if the PKCS#11 object associated with the entry has no references,
5730 + * return 0 if there is at least one reference, -1 on error.
5731 + *
5732 + * This function presumes it is called with lock protecting the active list
5733 + * held.
5734 + */
5735 +int
5736 +pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
5737 +       {
5738 +       PK11_active *entry = NULL;
5740 +       if ((entry = pk11_active_find(h, type)) == NULL)
5741 +               {
5742 +               PK11err(PK11_F_ACTIVE_DELETE, PK11_R_INVALID_HANDLE);
5743 +               return (-1);
5744 +               }
5746 +       OPENSSL_assert(entry->refcnt > 0);
5747 +       entry->refcnt--;
5748 +       if (entry->refcnt == 0)
5749 +               {
5750 +               pk11_active_remove(entry, type);
5751 +               return (1);
5752 +               }
5754 +       return (0);
5755 +       }
5757 +#ifndef OPENSSL_NO_RSA
5758 +/* Our internal RSA_METHOD that we provide pointers to */
5759 +static RSA_METHOD pk11_rsa =
5760 +       {
5761 +       "PKCS#11 RSA method",
5762 +       pk11_RSA_public_encrypt,                /* rsa_pub_encrypt */
5763 +       pk11_RSA_public_decrypt,                /* rsa_pub_decrypt */
5764 +       pk11_RSA_private_encrypt,               /* rsa_priv_encrypt */
5765 +       pk11_RSA_private_decrypt,               /* rsa_priv_decrypt */
5766 +       NULL,                                   /* rsa_mod_exp */
5767 +       NULL,                                   /* bn_mod_exp */
5768 +       pk11_RSA_init,                          /* init */
5769 +       pk11_RSA_finish,                        /* finish */
5770 +       RSA_FLAG_SIGN_VER,                      /* flags */
5771 +       NULL,                                   /* app_data */
5772 +       pk11_RSA_sign,                          /* rsa_sign */
5773 +       pk11_RSA_verify                         /* rsa_verify */
5774 +       };
5776 +RSA_METHOD *
5777 +PK11_RSA(void)
5778 +       {
5779 +       return (&pk11_rsa);
5780 +       }
5781 +#endif
5783 +#ifndef OPENSSL_NO_DSA
5784 +/* Our internal DSA_METHOD that we provide pointers to */
5785 +static DSA_METHOD pk11_dsa =
5786 +       {
5787 +       "PKCS#11 DSA method",
5788 +       pk11_dsa_do_sign,       /* dsa_do_sign */
5789 +       NULL,                   /* dsa_sign_setup */
5790 +       pk11_dsa_do_verify,     /* dsa_do_verify */
5791 +       NULL,                   /* dsa_mod_exp */
5792 +       NULL,                   /* bn_mod_exp */
5793 +       pk11_DSA_init,          /* init */
5794 +       pk11_DSA_finish,        /* finish */
5795 +       0,                      /* flags */
5796 +       NULL                    /* app_data */
5797 +       };
5799 +DSA_METHOD *
5800 +PK11_DSA(void)
5801 +       {
5802 +       return (&pk11_dsa);
5803 +       }
5804 +#endif
5806 +#ifndef OPENSSL_NO_DH
5808 + * PKCS #11 V2.20, section 11.2 specifies that the number of bytes needed for
5809 + * output buffer may somewhat exceed the precise number of bytes needed, but
5810 + * should not exceed it by a large amount. That may be caused, for example, by
5811 + * rounding it up to multiple of X in the underlying bignum library. 8 should be
5812 + * enough.
5813 + */
5814 +#define        DH_BUF_RESERVE  8
5816 +/* Our internal DH_METHOD that we provide pointers to */
5817 +static DH_METHOD pk11_dh =
5818 +       {
5819 +       "PKCS#11 DH method",
5820 +       pk11_DH_generate_key,   /* generate_key */
5821 +       pk11_DH_compute_key,    /* compute_key */
5822 +       NULL,                   /* bn_mod_exp */
5823 +       pk11_DH_init,           /* init */
5824 +       pk11_DH_finish,         /* finish */
5825 +       0,                      /* flags */
5826 +       NULL,                   /* app_data */
5827 +       NULL                    /* generate_params */
5828 +       };
5830 +DH_METHOD *
5831 +PK11_DH(void)
5832 +       {
5833 +       return (&pk11_dh);
5834 +       }
5835 +#endif
5837 +/* Size of an SSL signature: MD5+SHA1 */
5838 +#define        SSL_SIG_LENGTH          36
5840 +/* Lengths of DSA data and signature */
5841 +#define        DSA_DATA_LEN            20
5842 +#define        DSA_SIGNATURE_LEN       40
5844 +static CK_BBOOL true = TRUE;
5845 +static CK_BBOOL false = FALSE;
5847 +#ifndef OPENSSL_NO_RSA
5849 + * Similiar to OpenSSL to take advantage of the paddings. The goal is to
5850 + * support all paddings in this engine although PK11 library does not
5851 + * support all the paddings used in OpenSSL.
5852 + * The input errors should have been checked in the padding functions.
5853 + */
5854 +static int pk11_RSA_public_encrypt(int flen, const unsigned char *from,
5855 +               unsigned char *to, RSA *rsa, int padding)
5856 +       {
5857 +       int i, num = 0, r = -1;
5858 +       unsigned char *buf = NULL;
5860 +       num = BN_num_bytes(rsa->n);
5861 +       if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
5862 +               {
5863 +               RSAerr(PK11_F_RSA_PUB_ENC, PK11_R_MALLOC_FAILURE);
5864 +               goto err;
5865 +               }
5867 +       switch (padding)
5868 +               {
5869 +       case RSA_PKCS1_PADDING:
5870 +               i = RSA_padding_add_PKCS1_type_2(buf, num, from, flen);
5871 +               break;
5872 +#ifndef OPENSSL_NO_SHA
5873 +       case RSA_PKCS1_OAEP_PADDING:
5874 +               i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0);
5875 +               break;
5876 +#endif
5877 +       case RSA_SSLV23_PADDING:
5878 +               i = RSA_padding_add_SSLv23(buf, num, from, flen);
5879 +               break;
5880 +       case RSA_NO_PADDING:
5881 +               i = RSA_padding_add_none(buf, num, from, flen);
5882 +               break;
5883 +       default:
5884 +               RSAerr(PK11_F_RSA_PUB_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
5885 +               goto err;
5886 +               }
5887 +       if (i <= 0) goto err;
5889 +       /* PK11 functions are called here */
5890 +       r = pk11_RSA_public_encrypt_low(num, buf, to, rsa);
5891 +err:
5892 +       if (buf != NULL)
5893 +               {
5894 +               OPENSSL_cleanse(buf, num);
5895 +               OPENSSL_free(buf);
5896 +               }
5897 +       return (r);
5898 +       }
5902 + * Similar to Openssl to take advantage of the paddings. The input errors
5903 + * should be catched in the padding functions
5904 + */
5905 +static int pk11_RSA_private_encrypt(int flen, const unsigned char *from,
5906 +       unsigned char *to, RSA *rsa, int padding)
5907 +       {
5908 +       int i, num = 0, r = -1;
5909 +       unsigned char *buf = NULL;
5911 +       num = BN_num_bytes(rsa->n);
5912 +       if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
5913 +               {
5914 +               RSAerr(PK11_F_RSA_PRIV_ENC, PK11_R_MALLOC_FAILURE);
5915 +               goto err;
5916 +               }
5918 +       switch (padding)
5919 +               {
5920 +       case RSA_PKCS1_PADDING:
5921 +               i = RSA_padding_add_PKCS1_type_1(buf, num, from, flen);
5922 +               break;
5923 +       case RSA_NO_PADDING:
5924 +               i = RSA_padding_add_none(buf, num, from, flen);
5925 +               break;
5926 +       case RSA_SSLV23_PADDING:
5927 +       default:
5928 +               RSAerr(PK11_F_RSA_PRIV_ENC, PK11_R_UNKNOWN_PADDING_TYPE);
5929 +               goto err;
5930 +               }
5931 +       if (i <= 0) goto err;
5933 +       /* PK11 functions are called here */
5934 +       r = pk11_RSA_private_encrypt_low(num, buf, to, rsa);
5935 +err:
5936 +       if (buf != NULL)
5937 +               {
5938 +               OPENSSL_cleanse(buf, num);
5939 +               OPENSSL_free(buf);
5940 +               }
5941 +       return (r);
5942 +       }
5944 +/* Similar to OpenSSL code. Input errors are also checked here */
5945 +static int pk11_RSA_private_decrypt(int flen, const unsigned char *from,
5946 +       unsigned char *to, RSA *rsa, int padding)
5947 +       {
5948 +       BIGNUM f;
5949 +       int j, num = 0, r = -1;
5950 +       unsigned char *p;
5951 +       unsigned char *buf = NULL;
5953 +       BN_init(&f);
5955 +       num = BN_num_bytes(rsa->n);
5957 +       if ((buf = (unsigned char *)OPENSSL_malloc(num)) == NULL)
5958 +               {
5959 +               RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_MALLOC_FAILURE);
5960 +               goto err;
5961 +               }
5963 +       /*
5964 +        * This check was for equality but PGP does evil things
5965 +        * and chops off the top '0' bytes
5966 +        */
5967 +       if (flen > num)
5968 +               {
5969 +               RSAerr(PK11_F_RSA_PRIV_DEC,
5970 +                       PK11_R_DATA_GREATER_THAN_MOD_LEN);
5971 +               goto err;
5972 +               }
5974 +       /* make data into a big number */
5975 +       if (BN_bin2bn(from, (int)flen, &f) == NULL)
5976 +               goto err;
5978 +       if (BN_ucmp(&f, rsa->n) >= 0)
5979 +               {
5980 +               RSAerr(PK11_F_RSA_PRIV_DEC,
5981 +                       PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
5982 +               goto err;
5983 +               }
5985 +       /* PK11 functions are called here */
5986 +       r = pk11_RSA_private_decrypt_low(flen, from, buf, rsa);
5988 +       /*
5989 +        * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
5990 +        * Needs to skip these 0's paddings here.
5991 +        */
5992 +       for (j = 0; j < r; j++)
5993 +               if (buf[j] != 0)
5994 +                       break;
5996 +       p = buf + j;
5997 +       j = r - j;  /* j is only used with no-padding mode */
5999 +       switch (padding)
6000 +               {
6001 +       case RSA_PKCS1_PADDING:
6002 +               r = RSA_padding_check_PKCS1_type_2(to, num, p, j, num);
6003 +               break;
6004 +#ifndef OPENSSL_NO_SHA
6005 +       case RSA_PKCS1_OAEP_PADDING:
6006 +               r = RSA_padding_check_PKCS1_OAEP(to, num, p, j, num, NULL, 0);
6007 +               break;
6008 +#endif
6009 +       case RSA_SSLV23_PADDING:
6010 +               r = RSA_padding_check_SSLv23(to, num, p, j, num);
6011 +               break;
6012 +       case RSA_NO_PADDING:
6013 +               r = RSA_padding_check_none(to, num, p, j, num);
6014 +               break;
6015 +       default:
6016 +               RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
6017 +               goto err;
6018 +               }
6019 +       if (r < 0)
6020 +               RSAerr(PK11_F_RSA_PRIV_DEC, PK11_R_PADDING_CHECK_FAILED);
6022 +err:
6023 +       BN_clear_free(&f);
6024 +       if (buf != NULL)
6025 +               {
6026 +               OPENSSL_cleanse(buf, num);
6027 +               OPENSSL_free(buf);
6028 +               }
6029 +       return (r);
6030 +       }
6032 +/* Similar to OpenSSL code. Input errors are also checked here */
6033 +static int pk11_RSA_public_decrypt(int flen, const unsigned char *from,
6034 +       unsigned char *to, RSA *rsa, int padding)
6035 +       {
6036 +       BIGNUM f;
6037 +       int i, num = 0, r = -1;
6038 +       unsigned char *p;
6039 +       unsigned char *buf = NULL;
6041 +       BN_init(&f);
6042 +       num = BN_num_bytes(rsa->n);
6043 +       buf = (unsigned char *)OPENSSL_malloc(num);
6044 +       if (buf == NULL)
6045 +               {
6046 +               RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_MALLOC_FAILURE);
6047 +               goto err;
6048 +               }
6050 +       /*
6051 +        * This check was for equality but PGP does evil things
6052 +        * and chops off the top '0' bytes
6053 +        */
6054 +       if (flen > num)
6055 +               {
6056 +               RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_DATA_GREATER_THAN_MOD_LEN);
6057 +               goto err;
6058 +               }
6060 +       if (BN_bin2bn(from, flen, &f) == NULL)
6061 +               goto err;
6063 +       if (BN_ucmp(&f, rsa->n) >= 0)
6064 +               {
6065 +               RSAerr(PK11_F_RSA_PUB_DEC,
6066 +                       PK11_R_DATA_TOO_LARGE_FOR_MODULUS);
6067 +               goto err;
6068 +               }
6070 +       /* PK11 functions are called here */
6071 +       r = pk11_RSA_public_decrypt_low(flen, from, buf, rsa);
6073 +       /*
6074 +        * PK11 CKM_RSA_X_509 mechanism pads 0's at the beginning.
6075 +        * Needs to skip these 0's here
6076 +        */
6077 +       for (i = 0; i < r; i++)
6078 +               if (buf[i] != 0)
6079 +                       break;
6081 +       p = buf + i;
6082 +       i = r - i;  /* i is only used with no-padding mode */
6084 +       switch (padding)
6085 +               {
6086 +       case RSA_PKCS1_PADDING:
6087 +               r = RSA_padding_check_PKCS1_type_1(to, num, p, i, num);
6088 +               break;
6089 +       case RSA_NO_PADDING:
6090 +               r = RSA_padding_check_none(to, num, p, i, num);
6091 +               break;
6092 +       default:
6093 +               RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_UNKNOWN_PADDING_TYPE);
6094 +               goto err;
6095 +               }
6096 +       if (r < 0)
6097 +               RSAerr(PK11_F_RSA_PUB_DEC, PK11_R_PADDING_CHECK_FAILED);
6099 +err:
6100 +       BN_clear_free(&f);
6101 +       if (buf != NULL)
6102 +               {
6103 +               OPENSSL_cleanse(buf, num);
6104 +               OPENSSL_free(buf);
6105 +               }
6106 +       return (r);
6107 +       }
6110 + * This function implements RSA public encryption using C_EncryptInit and
6111 + * C_Encrypt pk11 interfaces. Note that the CKM_RSA_X_509 is used here.
6112 + * The calling function allocated sufficient memory in "to" to store results.
6113 + */
6114 +static int pk11_RSA_public_encrypt_low(int flen,
6115 +       const unsigned char *from, unsigned char *to, RSA *rsa)
6116 +       {
6117 +       CK_ULONG bytes_encrypted = flen;
6118 +       int retval = -1;
6119 +       CK_RV rv;
6120 +       CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6121 +       CK_MECHANISM *p_mech = &mech_rsa;
6122 +       CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
6123 +       PK11_SESSION *sp;
6125 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6126 +               return (-1);
6128 +       (void) check_new_rsa_key_pub(sp, rsa);
6130 +       h_pub_key = sp->opdata_rsa_pub_key;
6131 +       if (h_pub_key == CK_INVALID_HANDLE)
6132 +               h_pub_key = sp->opdata_rsa_pub_key =
6133 +                       pk11_get_public_rsa_key(rsa, &sp->opdata_rsa_pub,
6134 +                           &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
6135 +                           sp->session);
6137 +       if (h_pub_key != CK_INVALID_HANDLE)
6138 +               {
6139 +               rv = pFuncList->C_EncryptInit(sp->session, p_mech,
6140 +                       h_pub_key);
6142 +               if (rv != CKR_OK)
6143 +                       {
6144 +                       PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
6145 +                           PK11_R_ENCRYPTINIT, rv);
6146 +                       pk11_return_session(sp, OP_RSA);
6147 +                       return (-1);
6148 +                       }
6150 +               rv = pFuncList->C_Encrypt(sp->session,
6151 +                       (unsigned char *)from, flen, to, &bytes_encrypted);
6153 +               if (rv != CKR_OK)
6154 +                       {
6155 +                       PK11err_add_data(PK11_F_RSA_PUB_ENC_LOW,
6156 +                           PK11_R_ENCRYPT, rv);
6157 +                       pk11_return_session(sp, OP_RSA);
6158 +                       return (-1);
6159 +                       }
6160 +               retval = bytes_encrypted;
6161 +               }
6163 +       pk11_return_session(sp, OP_RSA);
6164 +       return (retval);
6165 +       }
6169 + * This function implements RSA private encryption using C_SignInit and
6170 + * C_Sign pk11 APIs. Note that CKM_RSA_X_509 is used here.
6171 + * The calling function allocated sufficient memory in "to" to store results.
6172 + */
6173 +static int pk11_RSA_private_encrypt_low(int flen,
6174 +       const unsigned char *from, unsigned char *to, RSA *rsa)
6175 +       {
6176 +       CK_ULONG ul_sig_len = flen;
6177 +       int retval = -1;
6178 +       CK_RV rv;
6179 +       CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6180 +       CK_MECHANISM *p_mech = &mech_rsa;
6181 +       CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
6182 +       PK11_SESSION *sp;
6184 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6185 +               return (-1);
6187 +       (void) check_new_rsa_key_priv(sp, rsa);
6189 +       h_priv_key = sp->opdata_rsa_priv_key;
6190 +       if (h_priv_key == CK_INVALID_HANDLE)
6191 +               h_priv_key = sp->opdata_rsa_priv_key =
6192 +                       pk11_get_private_rsa_key(rsa, &sp->opdata_rsa_priv,
6193 +                           &sp->opdata_rsa_d_num, sp->session);
6195 +       if (h_priv_key != CK_INVALID_HANDLE)
6196 +               {
6197 +               rv = pFuncList->C_SignInit(sp->session, p_mech,
6198 +                       h_priv_key);
6200 +               if (rv != CKR_OK)
6201 +                       {
6202 +                       PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW,
6203 +                           PK11_R_SIGNINIT, rv);
6204 +                       pk11_return_session(sp, OP_RSA);
6205 +                       return (-1);
6206 +                       }
6208 +               rv = pFuncList->C_Sign(sp->session,
6209 +                       (unsigned char *)from, flen, to, &ul_sig_len);
6211 +               if (rv != CKR_OK)
6212 +                       {
6213 +                       PK11err_add_data(PK11_F_RSA_PRIV_ENC_LOW, PK11_R_SIGN,
6214 +                           rv);
6215 +                       pk11_return_session(sp, OP_RSA);
6216 +                       return (-1);
6217 +                       }
6219 +               retval = ul_sig_len;
6220 +               }
6222 +       pk11_return_session(sp, OP_RSA);
6223 +       return (retval);
6224 +       }
6228 + * This function implements RSA private decryption using C_DecryptInit and
6229 + * C_Decrypt pk11 APIs. Note that CKM_RSA_X_509 mechanism is used here.
6230 + * The calling function allocated sufficient memory in "to" to store results.
6231 + */
6232 +static int pk11_RSA_private_decrypt_low(int flen,
6233 +       const unsigned char *from, unsigned char *to, RSA *rsa)
6234 +       {
6235 +       CK_ULONG bytes_decrypted = flen;
6236 +       int retval = -1;
6237 +       CK_RV rv;
6238 +       CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6239 +       CK_MECHANISM *p_mech = &mech_rsa;
6240 +       CK_OBJECT_HANDLE h_priv_key;
6241 +       PK11_SESSION *sp;
6243 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6244 +               return (-1);
6246 +       (void) check_new_rsa_key_priv(sp, rsa);
6248 +       h_priv_key = sp->opdata_rsa_priv_key;
6249 +       if (h_priv_key == CK_INVALID_HANDLE)
6250 +               h_priv_key = sp->opdata_rsa_priv_key =
6251 +                       pk11_get_private_rsa_key(rsa, &sp->opdata_rsa_priv,
6252 +                           &sp->opdata_rsa_d_num, sp->session);
6254 +       if (h_priv_key != CK_INVALID_HANDLE)
6255 +               {
6256 +               rv = pFuncList->C_DecryptInit(sp->session, p_mech,
6257 +                       h_priv_key);
6259 +               if (rv != CKR_OK)
6260 +                       {
6261 +                       PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
6262 +                               PK11_R_DECRYPTINIT, rv);
6263 +                       pk11_return_session(sp, OP_RSA);
6264 +                       return (-1);
6265 +                       }
6267 +               rv = pFuncList->C_Decrypt(sp->session,
6268 +                       (unsigned char *)from, flen, to, &bytes_decrypted);
6270 +               if (rv != CKR_OK)
6271 +                       {
6272 +                       PK11err_add_data(PK11_F_RSA_PRIV_DEC_LOW,
6273 +                           PK11_R_DECRYPT, rv);
6274 +                       pk11_return_session(sp, OP_RSA);
6275 +                       return (-1);
6276 +                       }
6277 +               retval = bytes_decrypted;
6278 +               }
6280 +       pk11_return_session(sp, OP_RSA);
6281 +       return (retval);
6282 +       }
6286 + * This function implements RSA public decryption using C_VerifyRecoverInit
6287 + * and C_VerifyRecover pk11 APIs. Note that CKM_RSA_X_509 is used here.
6288 + * The calling function allocated sufficient memory in "to" to store results.
6289 + */
6290 +static int pk11_RSA_public_decrypt_low(int flen,
6291 +       const unsigned char *from, unsigned char *to, RSA *rsa)
6292 +       {
6293 +       CK_ULONG bytes_decrypted = flen;
6294 +       int retval = -1;
6295 +       CK_RV rv;
6296 +       CK_MECHANISM mech_rsa = {CKM_RSA_X_509, NULL, 0};
6297 +       CK_MECHANISM *p_mech = &mech_rsa;
6298 +       CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
6299 +       PK11_SESSION *sp;
6301 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6302 +               return (-1);
6304 +       (void) check_new_rsa_key_pub(sp, rsa);
6306 +       h_pub_key = sp->opdata_rsa_pub_key;
6307 +       if (h_pub_key == CK_INVALID_HANDLE)
6308 +               h_pub_key = sp->opdata_rsa_pub_key =
6309 +                       pk11_get_public_rsa_key(rsa, &sp->opdata_rsa_pub,
6310 +                           &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
6311 +                           sp->session);
6313 +       if (h_pub_key != CK_INVALID_HANDLE)
6314 +               {
6315 +               rv = pFuncList->C_VerifyRecoverInit(sp->session,
6316 +                       p_mech, h_pub_key);
6318 +               if (rv != CKR_OK)
6319 +                       {
6320 +                       PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
6321 +                               PK11_R_VERIFYRECOVERINIT, rv);
6322 +                       pk11_return_session(sp, OP_RSA);
6323 +                       return (-1);
6324 +                       }
6326 +               rv = pFuncList->C_VerifyRecover(sp->session,
6327 +                       (unsigned char *)from, flen, to, &bytes_decrypted);
6329 +               if (rv != CKR_OK)
6330 +                       {
6331 +                       PK11err_add_data(PK11_F_RSA_PUB_DEC_LOW,
6332 +                           PK11_R_VERIFYRECOVER, rv);
6333 +                       pk11_return_session(sp, OP_RSA);
6334 +                       return (-1);
6335 +                       }
6336 +               retval = bytes_decrypted;
6337 +               }
6339 +       pk11_return_session(sp, OP_RSA);
6340 +       return (retval);
6341 +       }
6343 +static int pk11_RSA_init(RSA *rsa)
6344 +       {
6345 +       /*
6346 +        * This flag in the RSA_METHOD enables the new rsa_sign,
6347 +        * rsa_verify functions. See rsa.h for details.
6348 +        */
6349 +       rsa->flags |= RSA_FLAG_SIGN_VER;
6351 +       return (1);
6352 +       }
6354 +static int pk11_RSA_finish(RSA *rsa)
6355 +       {
6356 +       /*
6357 +        * Since we are overloading OpenSSL's native RSA_eay_finish() we need
6358 +        * to do the same as in the original function, i.e. to free bignum
6359 +        * structures.
6360 +        */
6361 +       if (rsa->_method_mod_n != NULL)
6362 +               BN_MONT_CTX_free(rsa->_method_mod_n);
6363 +       if (rsa->_method_mod_p != NULL)
6364 +               BN_MONT_CTX_free(rsa->_method_mod_p);
6365 +       if (rsa->_method_mod_q != NULL)
6366 +               BN_MONT_CTX_free(rsa->_method_mod_q);
6368 +       return (1);
6369 +       }
6372 + * Standard engine interface function. Majority codes here are from
6373 + * rsa/rsa_sign.c. We replaced the decrypt function call by C_Sign of PKCS#11.
6374 + * See more details in rsa/rsa_sign.c
6375 + */
6376 +static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
6377 +       unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
6378 +       {
6379 +       X509_SIG sig;
6380 +       ASN1_TYPE parameter;
6381 +       int i, j = 0;
6382 +       unsigned char *p, *s = NULL;
6383 +       X509_ALGOR algor;
6384 +       ASN1_OCTET_STRING digest;
6385 +       CK_RV rv;
6386 +       CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
6387 +       CK_MECHANISM *p_mech = &mech_rsa;
6388 +       CK_OBJECT_HANDLE h_priv_key;
6389 +       PK11_SESSION *sp = NULL;
6390 +       int ret = 0;
6391 +       unsigned long ulsiglen;
6393 +       /* Encode the digest */
6394 +       /* Special case: SSL signature, just check the length */
6395 +       if (type == NID_md5_sha1)
6396 +               {
6397 +               if (m_len != SSL_SIG_LENGTH)
6398 +                       {
6399 +                       PK11err(PK11_F_RSA_SIGN,
6400 +                               PK11_R_INVALID_MESSAGE_LENGTH);
6401 +                       goto err;
6402 +                       }
6403 +               i = SSL_SIG_LENGTH;
6404 +               s = (unsigned char *)m;
6405 +               }
6406 +       else
6407 +               {
6408 +               sig.algor = &algor;
6409 +               sig.algor->algorithm = OBJ_nid2obj(type);
6410 +               if (sig.algor->algorithm == NULL)
6411 +                       {
6412 +                       PK11err(PK11_F_RSA_SIGN,
6413 +                               PK11_R_UNKNOWN_ALGORITHM_TYPE);
6414 +                       goto err;
6415 +                       }
6416 +               if (sig.algor->algorithm->length == 0)
6417 +                       {
6418 +                       PK11err(PK11_F_RSA_SIGN,
6419 +                               PK11_R_UNKNOWN_ASN1_OBJECT_ID);
6420 +                       goto err;
6421 +                       }
6422 +               parameter.type = V_ASN1_NULL;
6423 +               parameter.value.ptr = NULL;
6424 +               sig.algor->parameter = &parameter;
6426 +               sig.digest = &digest;
6427 +               sig.digest->data = (unsigned char *)m;
6428 +               sig.digest->length = m_len;
6430 +               i = i2d_X509_SIG(&sig, NULL);
6431 +               }
6433 +       j = RSA_size(rsa);
6434 +       if ((i - RSA_PKCS1_PADDING) > j)
6435 +               {
6436 +               PK11err(PK11_F_RSA_SIGN, PK11_R_DIGEST_TOO_BIG);
6437 +               goto err;
6438 +               }
6440 +       if (type != NID_md5_sha1)
6441 +               {
6442 +               s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
6443 +               if (s == NULL)
6444 +                       {
6445 +                       PK11err(PK11_F_RSA_SIGN, PK11_R_MALLOC_FAILURE);
6446 +                       goto err;
6447 +                       }
6448 +               p = s;
6449 +               (void) i2d_X509_SIG(&sig, &p);
6450 +               }
6452 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6453 +               goto err;
6455 +       (void) check_new_rsa_key_priv(sp, rsa);
6457 +       h_priv_key = sp->opdata_rsa_priv_key;
6458 +       if (h_priv_key == CK_INVALID_HANDLE)
6459 +               h_priv_key = sp->opdata_rsa_priv_key =
6460 +                       pk11_get_private_rsa_key((RSA *)rsa,
6461 +                           &sp->opdata_rsa_priv,
6462 +                           &sp->opdata_rsa_d_num, sp->session);
6464 +       if (h_priv_key != CK_INVALID_HANDLE)
6465 +               {
6466 +               rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
6468 +               if (rv != CKR_OK)
6469 +                       {
6470 +                       PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGNINIT, rv);
6471 +                       goto err;
6472 +                       }
6474 +               ulsiglen = j;
6475 +               rv = pFuncList->C_Sign(sp->session, s, i, sigret,
6476 +                       (CK_ULONG_PTR) &ulsiglen);
6477 +               *siglen = ulsiglen;
6479 +               if (rv != CKR_OK)
6480 +                       {
6481 +                       PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGN, rv);
6482 +                       goto err;
6483 +                       }
6484 +               ret = 1;
6485 +               }
6487 +err:
6488 +       if ((type != NID_md5_sha1) && (s != NULL))
6489 +               {
6490 +               (void) memset(s, 0, (unsigned int)(j + 1));
6491 +               OPENSSL_free(s);
6492 +               }
6494 +       pk11_return_session(sp, OP_RSA);
6495 +       return (ret);
6496 +       }
6498 +static int pk11_RSA_verify(int type, const unsigned char *m,
6499 +       unsigned int m_len, unsigned char *sigbuf, unsigned int siglen,
6500 +       const RSA *rsa)
6501 +       {
6502 +       X509_SIG sig;
6503 +       ASN1_TYPE parameter;
6504 +       int i, j = 0;
6505 +       unsigned char *p, *s = NULL;
6506 +       X509_ALGOR algor;
6507 +       ASN1_OCTET_STRING digest;
6508 +       CK_RV rv;
6509 +       CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
6510 +       CK_MECHANISM *p_mech = &mech_rsa;
6511 +       CK_OBJECT_HANDLE h_pub_key;
6512 +       PK11_SESSION *sp = NULL;
6513 +       int ret = 0;
6515 +       /* Encode the digest    */
6516 +       /* Special case: SSL signature, just check the length */
6517 +       if (type == NID_md5_sha1)
6518 +               {
6519 +               if (m_len != SSL_SIG_LENGTH)
6520 +                       {
6521 +                       PK11err(PK11_F_RSA_VERIFY,
6522 +                               PK11_R_INVALID_MESSAGE_LENGTH);
6523 +                       goto err;
6524 +                       }
6525 +               i = SSL_SIG_LENGTH;
6526 +               s = (unsigned char *)m;
6527 +               }
6528 +       else
6529 +               {
6530 +               sig.algor = &algor;
6531 +               sig.algor->algorithm = OBJ_nid2obj(type);
6532 +               if (sig.algor->algorithm == NULL)
6533 +                       {
6534 +                       PK11err(PK11_F_RSA_VERIFY,
6535 +                               PK11_R_UNKNOWN_ALGORITHM_TYPE);
6536 +                       goto err;
6537 +                       }
6538 +               if (sig.algor->algorithm->length == 0)
6539 +                       {
6540 +                       PK11err(PK11_F_RSA_VERIFY,
6541 +                               PK11_R_UNKNOWN_ASN1_OBJECT_ID);
6542 +                       goto err;
6543 +                       }
6544 +               parameter.type = V_ASN1_NULL;
6545 +               parameter.value.ptr = NULL;
6546 +               sig.algor->parameter = &parameter;
6547 +               sig.digest = &digest;
6548 +               sig.digest->data = (unsigned char *)m;
6549 +               sig.digest->length = m_len;
6550 +               i = i2d_X509_SIG(&sig, NULL);
6551 +               }
6553 +       j = RSA_size(rsa);
6554 +       if ((i - RSA_PKCS1_PADDING) > j)
6555 +               {
6556 +               PK11err(PK11_F_RSA_VERIFY, PK11_R_DIGEST_TOO_BIG);
6557 +               goto err;
6558 +               }
6560 +       if (type != NID_md5_sha1)
6561 +               {
6562 +               s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
6563 +               if (s == NULL)
6564 +                       {
6565 +                       PK11err(PK11_F_RSA_VERIFY, PK11_R_MALLOC_FAILURE);
6566 +                       goto err;
6567 +                       }
6568 +               p = s;
6569 +               (void) i2d_X509_SIG(&sig, &p);
6570 +               }
6572 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6573 +               goto err;
6575 +       (void) check_new_rsa_key_pub(sp, rsa);
6577 +       h_pub_key = sp->opdata_rsa_pub_key;
6578 +       if (h_pub_key == CK_INVALID_HANDLE)
6579 +               h_pub_key = sp->opdata_rsa_pub_key =
6580 +                       pk11_get_public_rsa_key((RSA *)rsa, &sp->opdata_rsa_pub,
6581 +                           &sp->opdata_rsa_n_num, &sp->opdata_rsa_e_num,
6582 +                           sp->session);
6584 +       if (h_pub_key != CK_INVALID_HANDLE)
6585 +               {
6586 +               rv = pFuncList->C_VerifyInit(sp->session, p_mech,
6587 +                       h_pub_key);
6589 +               if (rv != CKR_OK)
6590 +                       {
6591 +                       PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFYINIT,
6592 +                           rv);
6593 +                       goto err;
6594 +                       }
6595 +               rv = pFuncList->C_Verify(sp->session, s, i, sigbuf,
6596 +                       (CK_ULONG)siglen);
6598 +               if (rv != CKR_OK)
6599 +                       {
6600 +                       PK11err_add_data(PK11_F_RSA_VERIFY, PK11_R_VERIFY, rv);
6601 +                       goto err;
6602 +                       }
6603 +               ret = 1;
6604 +               }
6606 +err:
6607 +       if ((type != NID_md5_sha1) && (s != NULL))
6608 +               {
6609 +               (void) memset(s, 0, (unsigned int)(j + 1));
6610 +               OPENSSL_free(s);
6611 +               }
6613 +       pk11_return_session(sp, OP_RSA);
6614 +       return (ret);
6615 +       }
6617 +static int hndidx_rsa = -1;
6619 +/* load RSA private key from a file */
6620 +/* ARGSUSED */
6621 +EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *privkey_file,
6622 +       UI_METHOD *ui_method, void *callback_data)
6623 +       {
6624 +       EVP_PKEY *pkey = NULL;
6625 +       FILE *privkey;
6626 +       CK_OBJECT_HANDLE  h_priv_key = CK_INVALID_HANDLE;
6627 +       RSA *rsa;
6628 +       PK11_SESSION *sp;
6629 +       /* everything else below needed for key by reference extension */
6630 +       CK_RV rv;
6631 +       CK_ULONG objcnt = 0;
6632 +       CK_BBOOL is_token = TRUE;
6633 +       CK_BYTE attr_data[2][1024];
6634 +       CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
6635 +       CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;    /* key in keystore */
6636 +       extern char *pk11_pin;
6638 +       /* we look for private keys only */
6639 +       CK_ATTRIBUTE search_templ[] =
6640 +               {
6641 +               {CKA_TOKEN, &is_token, sizeof(is_token)},
6642 +               {CKA_CLASS, &key_class, sizeof(key_class)},
6643 +               {CKA_LABEL, NULL, 0}
6644 +               };
6646 +       /* these attributes are needed to initialize OpenSSL RSA structure */
6647 +       CK_ATTRIBUTE get_templ[] =
6648 +               {
6649 +               {CKA_MODULUS, (void *)attr_data[0], 1024},          /* n */
6650 +               {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], 1024},  /* e */
6651 +               };
6653 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6654 +               return (NULL);
6656 +       /*
6657 +        * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
6658 +        */
6659 +       if (strstr(privkey_file, "pkcs11:") == privkey_file)
6660 +               {
6661 +               search_templ[2].pValue = strstr(privkey_file, ":") + 1;
6662 +               search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
6664 +               if (pk11_pin == NULL)
6665 +                       {
6666 +                       pk11_pin = BUF_strdup(getpassphrase("Enter PIN: "));
6668 +                       if (pk11_pin == NULL)
6669 +                               {
6670 +                               PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_MALLOC_FAILURE);
6671 +                               goto err;
6672 +                               }
6673 +                       }
6674 +               if ((rv = pFuncList->C_Login(sp->session, CKU_USER, (CK_UTF8CHAR*)pk11_pin,
6675 +                   strlen(pk11_pin))) != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN)
6676 +                       {
6677 +                       PK11err_add_data(PK11_F_LOAD_PRIVKEY,
6678 +                                        PK11_R_INVALID_PIN, rv);
6679 +                       goto err;
6680 +                       }
6682 +               LOCK_OBJSTORE(OP_RSA);
6683 +               if ((rv = pFuncList->C_FindObjectsInit(sp->session,
6684 +                   search_templ, 3)) != CKR_OK)
6685 +                       {
6686 +                       UNLOCK_OBJSTORE(OP_RSA);
6687 +                       PK11err_add_data(PK11_F_LOAD_PRIVKEY,
6688 +                                        PK11_R_FINDOBJECTSINIT, rv);
6689 +                       goto err;
6690 +                       }
6692 +               rv = pFuncList->C_FindObjects(sp->session, &ks_key, 1, &objcnt);
6693 +               if (rv != CKR_OK)
6694 +                       {
6695 +                       UNLOCK_OBJSTORE(OP_RSA);
6696 +                       PK11err_add_data(PK11_F_LOAD_PRIVKEY,
6697 +                                        PK11_R_FINDOBJECTS, rv);
6698 +                       goto err;
6699 +                       }
6701 +               if (objcnt > 1)
6702 +                       {
6703 +                       UNLOCK_OBJSTORE(OP_RSA);
6704 +                       PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_TOO_MANY_OBJECTS);
6705 +                       goto err;
6706 +                       }
6708 +               if (objcnt != 1)
6709 +                       {
6710 +                       UNLOCK_OBJSTORE(OP_RSA);
6711 +                       PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_OBJECT_NOT_FOUND);
6712 +                       goto err;
6713 +                       }
6715 +               (void) pFuncList->C_FindObjectsFinal(sp->session);
6716 +               UNLOCK_OBJSTORE(OP_RSA);
6718 +               if (hndidx_rsa == -1)
6719 +                       hndidx_rsa = RSA_get_ex_new_index(0,
6720 +                                       "pkcs11 RSA HSM key handle",
6721 +                                       NULL, NULL, NULL);
6723 +               pkey = EVP_PKEY_new();
6724 +               if (pkey == NULL)
6725 +                       goto err;
6727 +               rsa = RSA_new_method(e);
6728 +               if (rsa == NULL) {
6729 +                       EVP_PKEY_free(pkey);
6730 +                       pkey = NULL;
6731 +                       goto err;
6732 +               }
6733 +               EVP_PKEY_assign_RSA(pkey, rsa);
6735 +               if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
6736 +                   get_templ, 2)) != CKR_OK)
6737 +                       {
6738 +                       PK11err_add_data(PK11_F_LOAD_PRIVKEY,
6739 +                                        PK11_R_GETATTRIBUTVALUE, rv);
6740 +                       EVP_PKEY_free(pkey);
6741 +                       pkey = NULL;
6742 +                       goto err;
6743 +                       }
6745 +               /*
6746 +                * Now we have to initialize an OpenSSL RSA structure,
6747 +                * everything else is 0 or NULL.
6748 +                */
6749 +               rsa->flags = RSA_FLAG_SIGN_VER | RSA_FLAG_EXT_PKEY;
6750 +               RSA_set_ex_data(rsa, hndidx_rsa, (void *) ks_key);
6751 +               (void) check_new_rsa_key_priv(sp, rsa);
6752 +               sp->opdata_rsa_priv = rsa;
6753 +               sp->opdata_rsa_priv_key = ks_key;
6755 +               attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
6756 +               attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
6757 +               }
6758 +       else if ((privkey = fopen(privkey_file, read_mode_flags)) != NULL)
6759 +               {
6760 +               pkey = PEM_read_PrivateKey(privkey, NULL, NULL, NULL);
6761 +               (void) fclose(privkey);
6762 +               if (pkey != NULL)
6763 +                       {
6764 +                       rsa = EVP_PKEY_get1_RSA(pkey);
6765 +                       if (rsa != NULL)
6766 +                               {
6767 +                               (void) check_new_rsa_key_priv(sp, rsa);
6769 +                               h_priv_key = sp->opdata_rsa_priv_key =
6770 +                                   pk11_get_private_rsa_key(rsa,
6771 +                                   &sp->opdata_rsa_priv, &sp->opdata_rsa_d_num,
6772 +                                   sp->session);
6773 +                               if (h_priv_key == CK_INVALID_HANDLE)
6774 +                                       {
6775 +                                       EVP_PKEY_free(pkey);
6776 +                                       pkey = NULL;
6777 +                                       }
6778 +                               }
6779 +                       else
6780 +                               {
6781 +                               EVP_PKEY_free(pkey);
6782 +                               pkey = NULL;
6783 +                               }
6784 +                       }
6785 +               }
6787 +err:
6788 +       pk11_return_session(sp, OP_RSA);
6789 +       return (pkey);
6790 +       }
6792 +/* load RSA public key from a file */
6793 +/* ARGSUSED */
6794 +EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
6795 +       UI_METHOD *ui_method, void *callback_data)
6796 +       {
6797 +       EVP_PKEY *pkey = NULL;
6798 +       FILE *pubkey;
6799 +       CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
6800 +       RSA *rsa;
6801 +       PK11_SESSION *sp;
6802 +       /* everything else below needed for key by reference extension */
6803 +       CK_RV rv;
6804 +       CK_ULONG objcnt = 0;
6805 +       CK_BBOOL is_token = TRUE;
6806 +       CK_BYTE attr_data[2][1024];
6807 +       CK_OBJECT_CLASS key_class = CKO_PUBLIC_KEY;
6808 +       CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;    /* key in keystore */
6809 +       extern char *pk11_pin;
6811 +       /* we look for public keys only */
6812 +       CK_ATTRIBUTE search_templ[] =
6813 +               {
6814 +               {CKA_TOKEN, &is_token, sizeof(is_token)},
6815 +               {CKA_CLASS, &key_class, sizeof(key_class)},
6816 +               {CKA_LABEL, NULL, 0}
6817 +               };
6819 +       /* these attributes are needed to initialize OpenSSL RSA structure */
6820 +       CK_ATTRIBUTE get_templ[] =
6821 +               {
6822 +               {CKA_MODULUS, (void *)attr_data[0], 1024},          /* n */
6823 +               {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], 1024},  /* e */
6824 +               };
6826 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
6827 +               return (NULL);
6829 +       /*
6830 +        * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
6831 +        */
6832 +       if (strstr(pubkey_file, "pkcs11:") == pubkey_file)
6833 +               {
6834 +               search_templ[2].pValue = strstr(pubkey_file, ":") + 1;
6835 +               search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
6837 +#define ALLWAYS_LOGIN
6838 +#ifdef ALLWAYS_LOGIN
6839 +               if (pk11_pin == NULL)
6840 +                       {
6841 +                       pk11_pin = BUF_strdup(getpassphrase("Enter PIN: "));
6843 +                       if (pk11_pin == NULL)
6844 +                               {
6845 +                               PK11err(PK11_F_LOAD_PUBKEY, PK11_R_MALLOC_FAILURE);
6846 +                               goto err;
6847 +                               }
6848 +                       }
6849 +               if ((rv = pFuncList->C_Login(sp->session, CKU_USER, (CK_UTF8CHAR*)pk11_pin,
6850 +                   strlen(pk11_pin))) != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN)
6851 +                       {
6852 +                       PK11err_add_data(PK11_F_LOAD_PUBKEY,
6853 +                                        PK11_R_INVALID_PIN, rv);
6854 +                       goto err;
6855 +                       }
6856 +#endif
6858 +               LOCK_OBJSTORE(OP_RSA);
6859 +               if (pFuncList->C_FindObjectsInit(sp->session, search_templ, 3) != CKR_OK)
6860 +                       {
6861 +                       UNLOCK_OBJSTORE(OP_RSA);
6862 +                       PK11err_add_data(PK11_F_LOAD_PUBKEY,
6863 +                                        PK11_R_FINDOBJECTSINIT, rv);
6864 +                       goto err;
6865 +                       }
6866 +               rv = pFuncList->C_FindObjects(sp->session, &ks_key, 1, &objcnt);
6867 +               if (rv != CKR_OK)
6868 +                       {
6869 +                       UNLOCK_OBJSTORE(OP_RSA);
6870 +                       PK11err_add_data(PK11_F_LOAD_PUBKEY,
6871 +                                        PK11_R_FINDOBJECTS, rv);
6872 +                       goto err;
6873 +                       }
6875 +               if (objcnt > 1)
6876 +                       {
6877 +                       UNLOCK_OBJSTORE(OP_RSA);
6878 +                       PK11err(PK11_F_LOAD_PUBKEY, PK11_R_TOO_MANY_OBJECTS);
6879 +                       goto err;
6880 +                       }
6882 +               if (objcnt != 1)
6883 +                       {
6884 +                       UNLOCK_OBJSTORE(OP_RSA);
6885 +                       PK11err(PK11_F_LOAD_PUBKEY, PK11_R_OBJECT_NOT_FOUND);
6886 +                       goto err;
6887 +                       }
6889 +               (void) pFuncList->C_FindObjectsFinal(sp->session);
6890 +               UNLOCK_OBJSTORE(OP_RSA);
6892 +               sp->opdata_rsa_pub_key = ks_key;
6893 +               pkey = EVP_PKEY_new();
6894 +               if (pkey == NULL)
6895 +                       goto err;
6897 +               rsa = RSA_new_method(e);
6898 +               if (rsa == NULL) {
6899 +                       EVP_PKEY_free(pkey);
6900 +                       pkey = NULL;
6901 +                       goto err;
6902 +               }
6903 +               EVP_PKEY_assign_RSA(pkey, rsa);
6905 +               if (pFuncList->C_GetAttributeValue(sp->session, ks_key,
6906 +                   get_templ, 2) != CKR_OK)
6907 +                       {
6908 +                       PK11err_add_data(PK11_F_LOAD_PUBKEY,
6909 +                                        PK11_R_GETATTRIBUTVALUE, rv);
6910 +                       goto err;
6911 +                       }
6913 +               /*
6914 +                * Now we have to initialize an OpenSSL RSA structure,
6915 +                * everything else is 0 or NULL.
6916 +                */
6917 +               rsa->flags = RSA_FLAG_SIGN_VER;
6918 +               (void) check_new_rsa_key_pub(sp, rsa);
6919 +               sp->opdata_rsa_pub = rsa;
6921 +               attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
6922 +               attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
6923 +               }
6924 +       else if ((pubkey = fopen(pubkey_file, read_mode_flags)) != NULL)
6925 +               {
6926 +               pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL);
6927 +               (void) fclose(pubkey);
6928 +               if (pkey != NULL)
6929 +                       {
6930 +                       rsa = EVP_PKEY_get1_RSA(pkey);
6931 +                       if (rsa != NULL)
6932 +                               {
6933 +                               (void) check_new_rsa_key_pub(sp, rsa);
6935 +                               h_pub_key = sp->opdata_rsa_pub_key =
6936 +                                   pk11_get_public_rsa_key(rsa,
6937 +                                   &sp->opdata_rsa_pub, &sp->opdata_rsa_n_num,
6938 +                                   &sp->opdata_rsa_e_num, sp->session);
6939 +                               if (h_pub_key == CK_INVALID_HANDLE)
6940 +                                       {
6941 +                                       EVP_PKEY_free(pkey);
6942 +                                       pkey = NULL;
6943 +                                       }
6944 +                               }
6945 +                       else
6946 +                               {
6947 +                               EVP_PKEY_free(pkey);
6948 +                               pkey = NULL;
6949 +                               }
6950 +                       }
6951 +               }
6953 +err:
6954 +       pk11_return_session(sp, OP_RSA);
6955 +       return (pkey);
6956 +       }
6959 + * Create a public key object in a session from a given rsa structure.
6960 + * The *rsa_n_num and *rsa_e_num pointers are non-NULL for RSA public keys.
6961 + */
6962 +static CK_OBJECT_HANDLE pk11_get_public_rsa_key(RSA *rsa,
6963 +    RSA **key_ptr, BIGNUM **rsa_n_num, BIGNUM **rsa_e_num,
6964 +    CK_SESSION_HANDLE session)
6965 +       {
6966 +       CK_RV rv;
6967 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
6968 +       CK_ULONG found;
6969 +       CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
6970 +       CK_KEY_TYPE k_type = CKK_RSA;
6971 +       CK_ULONG ul_key_attr_count = 8;
6972 +       CK_BBOOL rollback = FALSE;
6974 +       CK_ATTRIBUTE  a_key_template[] =
6975 +               {
6976 +               {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
6977 +               {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
6978 +               {CKA_TOKEN, &false, sizeof (true)},
6979 +               {CKA_ENCRYPT, &true, sizeof (true)},
6980 +               {CKA_VERIFY, &true, sizeof (true)},
6981 +               {CKA_VERIFY_RECOVER, &true, sizeof (true)},
6982 +               {CKA_MODULUS, (void *)NULL, 0},
6983 +               {CKA_PUBLIC_EXPONENT, (void *)NULL, 0}
6984 +               };
6986 +       int i;
6988 +       a_key_template[0].pValue = &o_key;
6989 +       a_key_template[1].pValue = &k_type;
6991 +       a_key_template[6].ulValueLen = BN_num_bytes(rsa->n);
6992 +       a_key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
6993 +               (size_t)a_key_template[6].ulValueLen);
6994 +       if (a_key_template[6].pValue == NULL)
6995 +               {
6996 +               PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
6997 +               goto malloc_err;
6998 +               }
7000 +       BN_bn2bin(rsa->n, a_key_template[6].pValue);
7002 +       a_key_template[7].ulValueLen = BN_num_bytes(rsa->e);
7003 +       a_key_template[7].pValue = (CK_VOID_PTR)OPENSSL_malloc(
7004 +               (size_t)a_key_template[7].ulValueLen);
7005 +       if (a_key_template[7].pValue == NULL)
7006 +               {
7007 +               PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
7008 +               goto malloc_err;
7009 +               }
7011 +       BN_bn2bin(rsa->e, a_key_template[7].pValue);
7013 +       /* see find_lock array definition for more info on object locking */
7014 +       LOCK_OBJSTORE(OP_RSA);
7015 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template,
7016 +               ul_key_attr_count);
7018 +       if (rv != CKR_OK)
7019 +               {
7020 +               PK11err_add_data(PK11_F_GET_PUB_RSA_KEY, PK11_R_FINDOBJECTSINIT,
7021 +                   rv);
7022 +               goto err;
7023 +               }
7025 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
7027 +       if (rv != CKR_OK)
7028 +               {
7029 +               PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
7030 +                   PK11_R_FINDOBJECTS, rv);
7031 +               goto err;
7032 +               }
7034 +       rv = pFuncList->C_FindObjectsFinal(session);
7036 +       if (rv != CKR_OK)
7037 +               {
7038 +               PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
7039 +                   PK11_R_FINDOBJECTSFINAL, rv);
7040 +               goto err;
7041 +               }
7043 +       if (found == 0)
7044 +               {
7045 +               rv = pFuncList->C_CreateObject(session,
7046 +                       a_key_template, ul_key_attr_count, &h_key);
7047 +               if (rv != CKR_OK)
7048 +                       {
7049 +                       PK11err_add_data(PK11_F_GET_PUB_RSA_KEY,
7050 +                           PK11_R_CREATEOBJECT, rv);
7051 +                       goto err;
7052 +                       }
7053 +               }
7055 +       if (rsa_n_num != NULL)
7056 +               if ((*rsa_n_num = BN_dup(rsa->n)) == NULL)
7057 +                       {
7058 +                       PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
7059 +                       rollback = TRUE;
7060 +                       goto err;
7061 +                       }
7062 +       if (rsa_e_num != NULL)
7063 +               if ((*rsa_e_num = BN_dup(rsa->e)) == NULL)
7064 +                       {
7065 +                       PK11err(PK11_F_GET_PUB_RSA_KEY, PK11_R_MALLOC_FAILURE);
7066 +                       BN_free(*rsa_n_num);
7067 +                       *rsa_n_num = NULL;
7068 +                       rollback = TRUE;
7069 +                       goto err;
7070 +                       }
7072 +       /* LINTED: E_CONSTANT_CONDITION */
7073 +       KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
7074 +       if (key_ptr != NULL)
7075 +               *key_ptr = rsa;
7077 +err:
7078 +       if (rollback)
7079 +               {
7080 +               /*
7081 +                * We do not care about the return value from C_DestroyObject()
7082 +                * since we are doing rollback.
7083 +                */
7084 +               if (found == 0)
7085 +                       (void) pFuncList->C_DestroyObject(session, h_key);
7086 +               h_key = CK_INVALID_HANDLE;
7087 +               }
7089 +       UNLOCK_OBJSTORE(OP_RSA);
7091 +malloc_err:
7092 +       for (i = 6; i <= 7; i++)
7093 +               {
7094 +               if (a_key_template[i].pValue != NULL)
7095 +                       {
7096 +                       OPENSSL_free(a_key_template[i].pValue);
7097 +                       a_key_template[i].pValue = NULL;
7098 +                       }
7099 +               }
7101 +       return (h_key);
7102 +       }
7105 + * Create a private key object in the session from a given rsa structure.
7106 + * The *rsa_d_num pointer is non-NULL for RSA private keys.
7107 + */
7108 +static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA *rsa,
7109 +    RSA **key_ptr, BIGNUM **rsa_d_num, CK_SESSION_HANDLE session)
7110 +       {
7111 +       CK_RV rv;
7112 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
7113 +       int i;
7114 +       CK_ULONG found;
7115 +       CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
7116 +       CK_KEY_TYPE k_type = CKK_RSA;
7117 +       CK_ULONG ul_key_attr_count = 14;
7118 +       CK_BBOOL rollback = FALSE;
7120 +       /* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys */
7121 +       CK_ATTRIBUTE  a_key_template[] =
7122 +               {
7123 +               {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
7124 +               {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
7125 +               {CKA_TOKEN, &false, sizeof (true)},
7126 +               {CKA_SENSITIVE, &false, sizeof (true)},
7127 +               {CKA_DECRYPT, &true, sizeof (true)},
7128 +               {CKA_SIGN, &true, sizeof (true)},
7129 +               {CKA_MODULUS, (void *)NULL, 0},
7130 +               {CKA_PUBLIC_EXPONENT, (void *)NULL, 0},
7131 +               {CKA_PRIVATE_EXPONENT, (void *)NULL, 0},
7132 +               {CKA_PRIME_1, (void *)NULL, 0},
7133 +               {CKA_PRIME_2, (void *)NULL, 0},
7134 +               {CKA_EXPONENT_1, (void *)NULL, 0},
7135 +               {CKA_EXPONENT_2, (void *)NULL, 0},
7136 +               {CKA_COEFFICIENT, (void *)NULL, 0}
7137 +               };
7139 +       if ((rsa->flags & RSA_FLAG_EXT_PKEY) != 0) {
7140 +               h_key = (CK_OBJECT_HANDLE)RSA_get_ex_data(rsa, hndidx_rsa);
7141 +               LOCK_OBJSTORE(OP_RSA);
7142 +               goto set;
7143 +       }
7144 +       
7145 +       a_key_template[0].pValue = &o_key;
7146 +       a_key_template[1].pValue = &k_type;
7148 +       /* Put the private key components into the template */
7149 +       if (init_template_value(rsa->n, &a_key_template[6].pValue,
7150 +               &a_key_template[6].ulValueLen) == 0 ||
7151 +           init_template_value(rsa->e, &a_key_template[7].pValue,
7152 +               &a_key_template[7].ulValueLen) == 0 ||
7153 +           init_template_value(rsa->d, &a_key_template[8].pValue,
7154 +               &a_key_template[8].ulValueLen) == 0 ||
7155 +           init_template_value(rsa->p, &a_key_template[9].pValue,
7156 +               &a_key_template[9].ulValueLen) == 0 ||
7157 +           init_template_value(rsa->q, &a_key_template[10].pValue,
7158 +               &a_key_template[10].ulValueLen) == 0 ||
7159 +           init_template_value(rsa->dmp1, &a_key_template[11].pValue,
7160 +               &a_key_template[11].ulValueLen) == 0 ||
7161 +           init_template_value(rsa->dmq1, &a_key_template[12].pValue,
7162 +               &a_key_template[12].ulValueLen) == 0 ||
7163 +           init_template_value(rsa->iqmp, &a_key_template[13].pValue,
7164 +               &a_key_template[13].ulValueLen) == 0)
7165 +               {
7166 +               PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
7167 +               goto malloc_err;
7168 +               }
7170 +       /* see find_lock array definition for more info on object locking */
7171 +       LOCK_OBJSTORE(OP_RSA);
7172 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template,
7173 +               ul_key_attr_count);
7175 +       if (rv != CKR_OK)
7176 +               {
7177 +               PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7178 +                   PK11_R_FINDOBJECTSINIT, rv);
7179 +               goto err;
7180 +               }
7182 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
7184 +       if (rv != CKR_OK)
7185 +               {
7186 +               PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7187 +                   PK11_R_FINDOBJECTS, rv);
7188 +               goto err;
7189 +               }
7191 +       rv = pFuncList->C_FindObjectsFinal(session);
7193 +       if (rv != CKR_OK)
7194 +               {
7195 +               PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7196 +                   PK11_R_FINDOBJECTSFINAL, rv);
7197 +               goto err;
7198 +               }
7200 +       if (found == 0)
7201 +               {
7202 +               rv = pFuncList->C_CreateObject(session,
7203 +                       a_key_template, ul_key_attr_count, &h_key);
7204 +               if (rv != CKR_OK)
7205 +                       {
7206 +                       PK11err_add_data(PK11_F_GET_PRIV_RSA_KEY,
7207 +                               PK11_R_CREATEOBJECT, rv);
7208 +                       goto err;
7209 +                       }
7210 +               }
7212 +set:
7213 +       if (rsa_d_num != NULL)
7214 +               {
7215 +               if (rsa->d == NULL)
7216 +                       *rsa_d_num = NULL;
7217 +               else if ((*rsa_d_num = BN_dup(rsa->d)) == NULL)
7218 +                       {
7219 +                       PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
7220 +                       rollback = TRUE;
7221 +                       goto err;
7222 +                       }
7223 +               }
7225 +       /* LINTED: E_CONSTANT_CONDITION */
7226 +       KEY_HANDLE_REFHOLD(h_key, OP_RSA, FALSE, rollback, err);
7227 +       if (key_ptr != NULL)
7228 +               *key_ptr = rsa;
7230 +err:
7231 +       if (rollback)
7232 +               {
7233 +               /*
7234 +                * We do not care about the return value from C_DestroyObject()
7235 +                * since we are doing rollback.
7236 +                */
7237 +               if (found == 0 &&
7238 +                   (rsa->flags & RSA_FLAG_EXT_PKEY) == 0)
7239 +                       (void) pFuncList->C_DestroyObject(session, h_key);
7240 +               h_key = CK_INVALID_HANDLE;
7241 +               }
7243 +       UNLOCK_OBJSTORE(OP_RSA);
7245 +malloc_err:
7246 +       /*
7247 +        * 6 to 13 entries in the key template are key components.
7248 +        * They need to be freed apon exit or error.
7249 +        */
7250 +       for (i = 6; i <= 13; i++)
7251 +               {
7252 +               if (a_key_template[i].pValue != NULL)
7253 +                       {
7254 +                       (void) memset(a_key_template[i].pValue, 0,
7255 +                               a_key_template[i].ulValueLen);
7256 +                       OPENSSL_free(a_key_template[i].pValue);
7257 +                       a_key_template[i].pValue = NULL;
7258 +                       }
7259 +               }
7261 +       return (h_key);
7262 +       }
7265 + * Check for cache miss and clean the object pointer and handle
7266 + * in such case. Return 1 for cache hit, 0 for cache miss.
7267 + */
7268 +static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa)
7269 +       {
7270 +       /*
7271 +        * Provide protection against RSA structure reuse by making the
7272 +        * check for cache hit stronger. Only public components of RSA
7273 +        * key matter here so it is sufficient to compare them with values
7274 +        * cached in PK11_SESSION structure.
7275 +        */
7276 +       if ((sp->opdata_rsa_pub != rsa) ||
7277 +           (BN_cmp(sp->opdata_rsa_n_num, rsa->n) != 0) ||
7278 +           (BN_cmp(sp->opdata_rsa_e_num, rsa->e) != 0))
7279 +               {
7280 +               /*
7281 +                * We do not check the return value because even in case of
7282 +                * failure the sp structure will have both key pointer
7283 +                * and object handle cleaned and pk11_destroy_object()
7284 +                * reports the failure to the OpenSSL error message buffer.
7285 +                */
7286 +               (void) pk11_destroy_rsa_object_pub(sp, TRUE);
7287 +               return (0);
7288 +               }
7289 +       return (1);
7290 +       }
7293 + * Check for cache miss and clean the object pointer and handle
7294 + * in such case. Return 1 for cache hit, 0 for cache miss.
7295 + */
7296 +static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa)
7297 +       {
7298 +       /*
7299 +        * Provide protection against RSA structure reuse by making the
7300 +        * check for cache hit stronger. Comparing private exponent of RSA
7301 +        * key with value cached in PK11_SESSION structure should
7302 +        * be sufficient.
7303 +        */
7304 +       if ((sp->opdata_rsa_priv != rsa) ||
7305 +           (BN_cmp(sp->opdata_rsa_d_num, rsa->d) != 0) ||
7306 +           ((rsa->flags & RSA_FLAG_EXT_PKEY) != 0))
7307 +               {
7308 +               /*
7309 +                * We do not check the return value because even in case of
7310 +                * failure the sp structure will have both key pointer
7311 +                * and object handle cleaned and pk11_destroy_object()
7312 +                * reports the failure to the OpenSSL error message buffer.
7313 +                */
7314 +               (void) pk11_destroy_rsa_object_priv(sp, TRUE);
7315 +               return (0);
7316 +               }
7317 +       return (1);
7318 +       }
7319 +#endif
7321 +#ifndef OPENSSL_NO_DSA
7322 +/* The DSA function implementation */
7323 +/* ARGSUSED */
7324 +static int pk11_DSA_init(DSA *dsa)
7325 +       {
7326 +       return (1);
7327 +       }
7329 +/* ARGSUSED */
7330 +static int pk11_DSA_finish(DSA *dsa)
7331 +       {
7332 +       return (1);
7333 +       }
7336 +static DSA_SIG *
7337 +pk11_dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa)
7338 +       {
7339 +       BIGNUM *r = NULL, *s = NULL;
7340 +       int i;
7341 +       DSA_SIG *dsa_sig = NULL;
7343 +       CK_RV rv;
7344 +       CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
7345 +       CK_MECHANISM *p_mech = &Mechanism_dsa;
7346 +       CK_OBJECT_HANDLE h_priv_key;
7348 +       /*
7349 +        * The signature is the concatenation of r and s,
7350 +        * each is 20 bytes long
7351 +        */
7352 +       unsigned char sigret[DSA_SIGNATURE_LEN];
7353 +       unsigned long siglen = DSA_SIGNATURE_LEN;
7354 +       unsigned int siglen2 = DSA_SIGNATURE_LEN / 2;
7356 +       PK11_SESSION *sp = NULL;
7358 +       if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
7359 +               {
7360 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MISSING_KEY_COMPONENT);
7361 +               goto ret;
7362 +               }
7364 +       i = BN_num_bytes(dsa->q); /* should be 20 */
7365 +       if (dlen > i)
7366 +               {
7367 +               PK11err(PK11_F_DSA_SIGN, PK11_R_INVALID_SIGNATURE_LENGTH);
7368 +               goto ret;
7369 +               }
7371 +       if ((sp = pk11_get_session(OP_DSA)) == NULL)
7372 +               goto ret;
7374 +       (void) check_new_dsa_key_priv(sp, dsa);
7376 +       h_priv_key = sp->opdata_dsa_priv_key;
7377 +       if (h_priv_key == CK_INVALID_HANDLE)
7378 +               h_priv_key = sp->opdata_dsa_priv_key =
7379 +                       pk11_get_private_dsa_key((DSA *)dsa,
7380 +                           &sp->opdata_dsa_priv,
7381 +                           &sp->opdata_dsa_priv_num, sp->session);
7383 +       if (h_priv_key != CK_INVALID_HANDLE)
7384 +               {
7385 +               rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
7387 +               if (rv != CKR_OK)
7388 +                       {
7389 +                       PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGNINIT, rv);
7390 +                       goto ret;
7391 +                       }
7393 +               (void) memset(sigret, 0, siglen);
7394 +               rv = pFuncList->C_Sign(sp->session,
7395 +                       (unsigned char*) dgst, dlen, sigret,
7396 +                       (CK_ULONG_PTR) &siglen);
7398 +               if (rv != CKR_OK)
7399 +                       {
7400 +                       PK11err_add_data(PK11_F_DSA_SIGN, PK11_R_SIGN, rv);
7401 +                       goto ret;
7402 +                       }
7403 +               }
7406 +       if ((s = BN_new()) == NULL)
7407 +               {
7408 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7409 +               goto ret;
7410 +               }
7412 +       if ((r = BN_new()) == NULL)
7413 +               {
7414 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7415 +               goto ret;
7416 +               }
7418 +       if ((dsa_sig = DSA_SIG_new()) == NULL)
7419 +               {
7420 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7421 +               goto ret;
7422 +               }
7424 +       if (BN_bin2bn(sigret, siglen2, r) == NULL ||
7425 +           BN_bin2bn(&sigret[siglen2], siglen2, s) == NULL)
7426 +               {
7427 +               PK11err(PK11_F_DSA_SIGN, PK11_R_MALLOC_FAILURE);
7428 +               goto ret;
7429 +               }
7431 +       dsa_sig->r = r;
7432 +       dsa_sig->s = s;
7434 +ret:
7435 +       if (dsa_sig == NULL)
7436 +               {
7437 +               if (r != NULL)
7438 +                       BN_free(r);
7439 +               if (s != NULL)
7440 +                       BN_free(s);
7441 +               }
7443 +       pk11_return_session(sp, OP_DSA);
7444 +       return (dsa_sig);
7445 +       }
7447 +static int
7448 +pk11_dsa_do_verify(const unsigned char *dgst, int dlen, DSA_SIG *sig,
7449 +       DSA *dsa)
7450 +       {
7451 +       int i;
7452 +       CK_RV rv;
7453 +       int retval = 0;
7454 +       CK_MECHANISM Mechanism_dsa = {CKM_DSA, NULL, 0};
7455 +       CK_MECHANISM *p_mech = &Mechanism_dsa;
7456 +       CK_OBJECT_HANDLE h_pub_key;
7458 +       unsigned char sigbuf[DSA_SIGNATURE_LEN];
7459 +       unsigned long siglen = DSA_SIGNATURE_LEN;
7460 +       unsigned long siglen2 = DSA_SIGNATURE_LEN/2;
7462 +       PK11_SESSION *sp = NULL;
7464 +       if (BN_is_zero(sig->r) || sig->r->neg || BN_ucmp(sig->r, dsa->q) >= 0)
7465 +               {
7466 +               PK11err(PK11_F_DSA_VERIFY,
7467 +                       PK11_R_INVALID_DSA_SIGNATURE_R);
7468 +               goto ret;
7469 +               }
7471 +       if (BN_is_zero(sig->s) || sig->s->neg || BN_ucmp(sig->s, dsa->q) >= 0)
7472 +               {
7473 +               PK11err(PK11_F_DSA_VERIFY,
7474 +                       PK11_R_INVALID_DSA_SIGNATURE_S);
7475 +               goto ret;
7476 +               }
7478 +       i = BN_num_bytes(dsa->q); /* should be 20 */
7480 +       if (dlen > i)
7481 +               {
7482 +               PK11err(PK11_F_DSA_VERIFY,
7483 +                       PK11_R_INVALID_SIGNATURE_LENGTH);
7484 +               goto ret;
7485 +               }
7487 +       if ((sp = pk11_get_session(OP_DSA)) == NULL)
7488 +               goto ret;
7490 +       (void) check_new_dsa_key_pub(sp, dsa);
7492 +       h_pub_key = sp->opdata_dsa_pub_key;
7493 +       if (h_pub_key == CK_INVALID_HANDLE)
7494 +               h_pub_key = sp->opdata_dsa_pub_key =
7495 +                       pk11_get_public_dsa_key((DSA *)dsa, &sp->opdata_dsa_pub,
7496 +                           &sp->opdata_dsa_pub_num, sp->session);
7498 +       if (h_pub_key != CK_INVALID_HANDLE)
7499 +               {
7500 +               rv = pFuncList->C_VerifyInit(sp->session, p_mech,
7501 +                       h_pub_key);
7503 +               if (rv != CKR_OK)
7504 +                       {
7505 +                       PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFYINIT,
7506 +                           rv);
7507 +                       goto ret;
7508 +                       }
7510 +               /*
7511 +                * The representation of each of the two big numbers could
7512 +                * be shorter than DSA_SIGNATURE_LEN/2 bytes so we need
7513 +                * to act accordingly and shift if necessary.
7514 +                */
7515 +               (void) memset(sigbuf, 0, siglen);
7516 +               BN_bn2bin(sig->r, sigbuf + siglen2 - BN_num_bytes(sig->r));
7517 +               BN_bn2bin(sig->s, &sigbuf[siglen2] + siglen2 -
7518 +                   BN_num_bytes(sig->s));
7520 +               rv = pFuncList->C_Verify(sp->session,
7521 +                       (unsigned char *) dgst, dlen, sigbuf, (CK_ULONG)siglen);
7523 +               if (rv != CKR_OK)
7524 +                       {
7525 +                       PK11err_add_data(PK11_F_DSA_VERIFY, PK11_R_VERIFY, rv);
7526 +                       goto ret;
7527 +                       }
7528 +               }
7530 +       retval = 1;
7531 +ret:
7533 +       pk11_return_session(sp, OP_DSA);
7534 +       return (retval);
7535 +       }
7539 + * Create a public key object in a session from a given dsa structure.
7540 + * The *dsa_pub_num pointer is non-NULL for DSA public keys.
7541 + */
7542 +static CK_OBJECT_HANDLE pk11_get_public_dsa_key(DSA* dsa,
7543 +    DSA **key_ptr, BIGNUM **dsa_pub_num, CK_SESSION_HANDLE session)
7544 +       {
7545 +       CK_RV rv;
7546 +       CK_OBJECT_CLASS o_key = CKO_PUBLIC_KEY;
7547 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
7548 +       CK_ULONG found;
7549 +       CK_KEY_TYPE k_type = CKK_DSA;
7550 +       CK_ULONG ul_key_attr_count = 8;
7551 +       CK_BBOOL rollback = FALSE;
7552 +       int i;
7554 +       CK_ATTRIBUTE  a_key_template[] =
7555 +               {
7556 +               {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
7557 +               {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
7558 +               {CKA_TOKEN, &false, sizeof (true)},
7559 +               {CKA_VERIFY, &true, sizeof (true)},
7560 +               {CKA_PRIME, (void *)NULL, 0},           /* p */
7561 +               {CKA_SUBPRIME, (void *)NULL, 0},        /* q */
7562 +               {CKA_BASE, (void *)NULL, 0},            /* g */
7563 +               {CKA_VALUE, (void *)NULL, 0}            /* pub_key - y */
7564 +               };
7566 +       a_key_template[0].pValue = &o_key;
7567 +       a_key_template[1].pValue = &k_type;
7569 +       if (init_template_value(dsa->p, &a_key_template[4].pValue,
7570 +               &a_key_template[4].ulValueLen) == 0 ||
7571 +           init_template_value(dsa->q, &a_key_template[5].pValue,
7572 +               &a_key_template[5].ulValueLen) == 0 ||
7573 +           init_template_value(dsa->g, &a_key_template[6].pValue,
7574 +               &a_key_template[6].ulValueLen) == 0 ||
7575 +           init_template_value(dsa->pub_key, &a_key_template[7].pValue,
7576 +               &a_key_template[7].ulValueLen) == 0)
7577 +               {
7578 +               PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
7579 +               goto malloc_err;
7580 +               }
7582 +       /* see find_lock array definition for more info on object locking */
7583 +       LOCK_OBJSTORE(OP_DSA);
7584 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template,
7585 +               ul_key_attr_count);
7587 +       if (rv != CKR_OK)
7588 +               {
7589 +               PK11err_add_data(PK11_F_GET_PUB_DSA_KEY, PK11_R_FINDOBJECTSINIT,
7590 +                   rv);
7591 +               goto err;
7592 +               }
7594 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
7596 +       if (rv != CKR_OK)
7597 +               {
7598 +               PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
7599 +                   PK11_R_FINDOBJECTS, rv);
7600 +               goto err;
7601 +               }
7603 +       rv = pFuncList->C_FindObjectsFinal(session);
7605 +       if (rv != CKR_OK)
7606 +               {
7607 +               PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
7608 +                   PK11_R_FINDOBJECTSFINAL, rv);
7609 +               goto err;
7610 +               }
7612 +       if (found == 0)
7613 +               {
7614 +               rv = pFuncList->C_CreateObject(session,
7615 +                       a_key_template, ul_key_attr_count, &h_key);
7616 +               if (rv != CKR_OK)
7617 +                       {
7618 +                       PK11err_add_data(PK11_F_GET_PUB_DSA_KEY,
7619 +                           PK11_R_CREATEOBJECT, rv);
7620 +                       goto err;
7621 +                       }
7622 +               }
7624 +       if (dsa_pub_num != NULL)
7625 +               if ((*dsa_pub_num = BN_dup(dsa->pub_key)) == NULL)
7626 +                       {
7627 +                       PK11err(PK11_F_GET_PUB_DSA_KEY, PK11_R_MALLOC_FAILURE);
7628 +                       rollback = TRUE;
7629 +                       goto err;
7630 +                       }
7632 +       /* LINTED: E_CONSTANT_CONDITION */
7633 +       KEY_HANDLE_REFHOLD(h_key, OP_DSA, FALSE, rollback, err);
7634 +       if (key_ptr != NULL)
7635 +               *key_ptr = dsa;
7637 +err:
7638 +       if (rollback)
7639 +               {
7640 +               /*
7641 +                * We do not care about the return value from C_DestroyObject()
7642 +                * since we are doing rollback.
7643 +                */
7644 +               if (found == 0)
7645 +                       (void) pFuncList->C_DestroyObject(session, h_key);
7646 +               h_key = CK_INVALID_HANDLE;
7647 +               }
7649 +       UNLOCK_OBJSTORE(OP_DSA);
7651 +malloc_err:
7652 +       for (i = 4; i <= 7; i++)
7653 +               {
7654 +               if (a_key_template[i].pValue != NULL)
7655 +                       {
7656 +                       OPENSSL_free(a_key_template[i].pValue);
7657 +                       a_key_template[i].pValue = NULL;
7658 +                       }
7659 +               }
7661 +       return (h_key);
7662 +       }
7665 + * Create a private key object in the session from a given dsa structure
7666 + * The *dsa_priv_num pointer is non-NULL for DSA private keys.
7667 + */
7668 +static CK_OBJECT_HANDLE pk11_get_private_dsa_key(DSA* dsa,
7669 +    DSA **key_ptr, BIGNUM **dsa_priv_num, CK_SESSION_HANDLE session)
7670 +       {
7671 +       CK_RV rv;
7672 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
7673 +       CK_OBJECT_CLASS o_key = CKO_PRIVATE_KEY;
7674 +       int i;
7675 +       CK_ULONG found;
7676 +       CK_KEY_TYPE k_type = CKK_DSA;
7677 +       CK_ULONG ul_key_attr_count = 9;
7678 +       CK_BBOOL rollback = FALSE;
7680 +       /* Both CKA_TOKEN and CKA_SENSITIVE have to be FALSE for session keys */
7681 +       CK_ATTRIBUTE  a_key_template[] =
7682 +               {
7683 +               {CKA_CLASS, (void *) NULL, sizeof (CK_OBJECT_CLASS)},
7684 +               {CKA_KEY_TYPE, (void *) NULL, sizeof (CK_KEY_TYPE)},
7685 +               {CKA_TOKEN, &false, sizeof (true)},
7686 +               {CKA_SENSITIVE, &false, sizeof (true)},
7687 +               {CKA_SIGN, &true, sizeof (true)},
7688 +               {CKA_PRIME, (void *)NULL, 0},           /* p */
7689 +               {CKA_SUBPRIME, (void *)NULL, 0},        /* q */
7690 +               {CKA_BASE, (void *)NULL, 0},            /* g */
7691 +               {CKA_VALUE, (void *)NULL, 0}            /* priv_key - x */
7692 +               };
7694 +       a_key_template[0].pValue = &o_key;
7695 +       a_key_template[1].pValue = &k_type;
7697 +       /* Put the private key components into the template */
7698 +       if (init_template_value(dsa->p, &a_key_template[5].pValue,
7699 +               &a_key_template[5].ulValueLen) == 0 ||
7700 +           init_template_value(dsa->q, &a_key_template[6].pValue,
7701 +               &a_key_template[6].ulValueLen) == 0 ||
7702 +           init_template_value(dsa->g, &a_key_template[7].pValue,
7703 +               &a_key_template[7].ulValueLen) == 0 ||
7704 +           init_template_value(dsa->priv_key, &a_key_template[8].pValue,
7705 +               &a_key_template[8].ulValueLen) == 0)
7706 +               {
7707 +               PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
7708 +               goto malloc_err;
7709 +               }
7711 +       /* see find_lock array definition for more info on object locking */
7712 +       LOCK_OBJSTORE(OP_DSA);
7713 +       rv = pFuncList->C_FindObjectsInit(session, a_key_template,
7714 +               ul_key_attr_count);
7716 +       if (rv != CKR_OK)
7717 +               {
7718 +               PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
7719 +                   PK11_R_FINDOBJECTSINIT, rv);
7720 +               goto err;
7721 +               }
7723 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
7725 +       if (rv != CKR_OK)
7726 +               {
7727 +               PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
7728 +                   PK11_R_FINDOBJECTS, rv);
7729 +               goto err;
7730 +               }
7732 +       rv = pFuncList->C_FindObjectsFinal(session);
7734 +       if (rv != CKR_OK)
7735 +               {
7736 +               PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
7737 +                   PK11_R_FINDOBJECTSFINAL, rv);
7738 +               goto err;
7739 +               }
7741 +       if (found == 0)
7742 +               {
7743 +               rv = pFuncList->C_CreateObject(session,
7744 +                       a_key_template, ul_key_attr_count, &h_key);
7745 +               if (rv != CKR_OK)
7746 +                       {
7747 +                       PK11err_add_data(PK11_F_GET_PRIV_DSA_KEY,
7748 +                           PK11_R_CREATEOBJECT, rv);
7749 +                       goto err;
7750 +                       }
7751 +               }
7753 +       if (dsa_priv_num != NULL)
7754 +               if ((*dsa_priv_num = BN_dup(dsa->priv_key)) == NULL)
7755 +                       {
7756 +                       PK11err(PK11_F_GET_PRIV_DSA_KEY, PK11_R_MALLOC_FAILURE);
7757 +                       rollback = TRUE;
7758 +                       goto err;
7759 +                       }
7761 +       /* LINTED: E_CONSTANT_CONDITION */
7762 +       KEY_HANDLE_REFHOLD(h_key, OP_DSA, FALSE, rollback, err);
7763 +       if (key_ptr != NULL)
7764 +               *key_ptr = dsa;
7766 +err:
7767 +       if (rollback)
7768 +               {
7769 +               /*
7770 +                * We do not care about the return value from C_DestroyObject()
7771 +                * since we are doing rollback.
7772 +                */
7773 +               if (found == 0)
7774 +                       (void) pFuncList->C_DestroyObject(session, h_key);
7775 +               h_key = CK_INVALID_HANDLE;
7776 +               }
7778 +       UNLOCK_OBJSTORE(OP_DSA);
7780 +malloc_err:
7781 +       /*
7782 +        * 5 to 8 entries in the key template are key components.
7783 +        * They need to be freed apon exit or error.
7784 +        */
7785 +       for (i = 5; i <= 8; i++)
7786 +               {
7787 +               if (a_key_template[i].pValue != NULL)
7788 +                       {
7789 +                       (void) memset(a_key_template[i].pValue, 0,
7790 +                               a_key_template[i].ulValueLen);
7791 +                       OPENSSL_free(a_key_template[i].pValue);
7792 +                       a_key_template[i].pValue = NULL;
7793 +                       }
7794 +               }
7796 +       return (h_key);
7797 +       }
7800 + * Check for cache miss and clean the object pointer and handle
7801 + * in such case. Return 1 for cache hit, 0 for cache miss.
7802 + */
7803 +static int check_new_dsa_key_pub(PK11_SESSION *sp, DSA *dsa)
7804 +       {
7805 +       /*
7806 +        * Provide protection against DSA structure reuse by making the
7807 +        * check for cache hit stronger. Only public key component of DSA
7808 +        * key matters here so it is sufficient to compare it with value
7809 +        * cached in PK11_SESSION structure.
7810 +        */
7811 +       if ((sp->opdata_dsa_pub != dsa) ||
7812 +           (BN_cmp(sp->opdata_dsa_pub_num, dsa->pub_key) != 0))
7813 +               {
7814 +               /*
7815 +                * We do not check the return value because even in case of
7816 +                * failure the sp structure will have both key pointer
7817 +                * and object handle cleaned and pk11_destroy_object()
7818 +                * reports the failure to the OpenSSL error message buffer.
7819 +                */
7820 +               (void) pk11_destroy_dsa_object_pub(sp, TRUE);
7821 +               return (0);
7822 +               }
7823 +       return (1);
7824 +       }
7827 + * Check for cache miss and clean the object pointer and handle
7828 + * in such case. Return 1 for cache hit, 0 for cache miss.
7829 + */
7830 +static int check_new_dsa_key_priv(PK11_SESSION *sp, DSA *dsa)
7831 +       {
7832 +       /*
7833 +        * Provide protection against DSA structure reuse by making the
7834 +        * check for cache hit stronger. Only private key component of DSA
7835 +        * key matters here so it is sufficient to compare it with value
7836 +        * cached in PK11_SESSION structure.
7837 +        */
7838 +       if ((sp->opdata_dsa_priv != dsa) ||
7839 +           (BN_cmp(sp->opdata_dsa_priv_num, dsa->priv_key) != 0))
7840 +               {
7841 +               /*
7842 +                * We do not check the return value because even in case of
7843 +                * failure the sp structure will have both key pointer
7844 +                * and object handle cleaned and pk11_destroy_object()
7845 +                * reports the failure to the OpenSSL error message buffer.
7846 +                */
7847 +               (void) pk11_destroy_dsa_object_priv(sp, TRUE);
7848 +               return (0);
7849 +               }
7850 +       return (1);
7851 +       }
7852 +#endif
7855 +#ifndef OPENSSL_NO_DH
7856 +/* The DH function implementation */
7857 +/* ARGSUSED */
7858 +static int pk11_DH_init(DH *dh)
7859 +       {
7860 +       return (1);
7861 +       }
7863 +/* ARGSUSED */
7864 +static int pk11_DH_finish(DH *dh)
7865 +       {
7866 +       return (1);
7867 +       }
7870 + * Generate DH key-pair.
7871 + *
7872 + * Warning: Unlike OpenSSL's DH_generate_key(3) we ignore dh->priv_key
7873 + * and override it even if it is set. OpenSSL does not touch dh->priv_key
7874 + * if set and just computes dh->pub_key. It looks like PKCS#11 standard
7875 + * is not capable of providing this functionality. This could be a problem
7876 + * for applications relying on OpenSSL's semantics.
7877 + */
7878 +static int pk11_DH_generate_key(DH *dh)
7879 +       {
7880 +       CK_ULONG i;
7881 +       CK_RV rv, rv1;
7882 +       int reuse_mem_len = 0, ret = 0;
7883 +       PK11_SESSION *sp = NULL;
7884 +       CK_BYTE_PTR reuse_mem;
7886 +       CK_MECHANISM mechanism = {CKM_DH_PKCS_KEY_PAIR_GEN, NULL_PTR, 0};
7887 +       CK_OBJECT_HANDLE h_pub_key = CK_INVALID_HANDLE;
7888 +       CK_OBJECT_HANDLE h_priv_key = CK_INVALID_HANDLE;
7890 +       CK_ULONG ul_pub_key_attr_count = 3;
7891 +       CK_ATTRIBUTE pub_key_template[] =
7892 +               {
7893 +               {CKA_PRIVATE, &false, sizeof (false)},
7894 +               {CKA_PRIME, (void *)NULL, 0},
7895 +               {CKA_BASE, (void *)NULL, 0}
7896 +               };
7898 +       CK_ULONG ul_priv_key_attr_count = 3;
7899 +       CK_ATTRIBUTE priv_key_template[] =
7900 +               {
7901 +               {CKA_PRIVATE, &false, sizeof (false)},
7902 +               {CKA_SENSITIVE, &false, sizeof (false)},
7903 +               {CKA_DERIVE, &true, sizeof (true)}
7904 +               };
7906 +       CK_ULONG pub_key_attr_result_count = 1;
7907 +       CK_ATTRIBUTE pub_key_result[] =
7908 +               {
7909 +               {CKA_VALUE, (void *)NULL, 0}
7910 +               };
7912 +       CK_ULONG priv_key_attr_result_count = 1;
7913 +       CK_ATTRIBUTE priv_key_result[] =
7914 +               {
7915 +               {CKA_VALUE, (void *)NULL, 0}
7916 +               };
7918 +       pub_key_template[1].ulValueLen = BN_num_bytes(dh->p);
7919 +       if (pub_key_template[1].ulValueLen > 0)
7920 +               {
7921 +               /*
7922 +                * We must not increase ulValueLen by DH_BUF_RESERVE since that
7923 +                * could cause the same rounding problem. See definition of
7924 +                * DH_BUF_RESERVE above.
7925 +                */
7926 +               pub_key_template[1].pValue =
7927 +                       OPENSSL_malloc(pub_key_template[1].ulValueLen +
7928 +                       DH_BUF_RESERVE);
7929 +               if (pub_key_template[1].pValue == NULL)
7930 +                       {
7931 +                       PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
7932 +                       goto err;
7933 +                       }
7935 +               i = BN_bn2bin(dh->p, pub_key_template[1].pValue);
7936 +               }
7937 +       else
7938 +               goto err;
7940 +       pub_key_template[2].ulValueLen = BN_num_bytes(dh->g);
7941 +       if (pub_key_template[2].ulValueLen > 0)
7942 +               {
7943 +               pub_key_template[2].pValue =
7944 +                       OPENSSL_malloc(pub_key_template[2].ulValueLen +
7945 +                       DH_BUF_RESERVE);
7946 +               if (pub_key_template[2].pValue == NULL)
7947 +                       {
7948 +                       PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
7949 +                       goto err;
7950 +                       }
7952 +               i = BN_bn2bin(dh->g, pub_key_template[2].pValue);
7953 +               }
7954 +       else
7955 +               goto err;
7957 +       /*
7958 +        * Note: we are only using PK11_SESSION structure for getting
7959 +        *       a session handle. The objects created in this function are
7960 +        *       destroyed before return and thus not cached.
7961 +        */
7962 +       if ((sp = pk11_get_session(OP_DH)) == NULL)
7963 +               goto err;
7965 +       rv = pFuncList->C_GenerateKeyPair(sp->session,
7966 +           &mechanism,
7967 +           pub_key_template,
7968 +           ul_pub_key_attr_count,
7969 +           priv_key_template,
7970 +           ul_priv_key_attr_count,
7971 +           &h_pub_key,
7972 +           &h_priv_key);
7973 +       if (rv != CKR_OK)
7974 +               {
7975 +               PK11err_add_data(PK11_F_DH_GEN_KEY, PK11_R_GEN_KEY, rv);
7976 +               goto err;
7977 +               }
7979 +       /*
7980 +        * Reuse the larger memory allocated. We know the larger memory
7981 +        * should be sufficient for reuse.
7982 +        */
7983 +       if (pub_key_template[1].ulValueLen > pub_key_template[2].ulValueLen)
7984 +               {
7985 +               reuse_mem = pub_key_template[1].pValue;
7986 +               reuse_mem_len = pub_key_template[1].ulValueLen + DH_BUF_RESERVE;
7987 +               }
7988 +       else
7989 +               {
7990 +               reuse_mem = pub_key_template[2].pValue;
7991 +               reuse_mem_len = pub_key_template[2].ulValueLen + DH_BUF_RESERVE;
7992 +               }
7994 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
7995 +               pub_key_result, pub_key_attr_result_count);
7996 +       rv1 = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
7997 +               priv_key_result, priv_key_attr_result_count);
7999 +       if (rv != CKR_OK || rv1 != CKR_OK)
8000 +               {
8001 +               rv = (rv != CKR_OK) ? rv : rv1;
8002 +               PK11err_add_data(PK11_F_DH_GEN_KEY,
8003 +                   PK11_R_GETATTRIBUTVALUE, rv);
8004 +               goto err;
8005 +               }
8007 +       if (((CK_LONG) pub_key_result[0].ulValueLen) <= 0 ||
8008 +               ((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
8009 +               {
8010 +               PK11err(PK11_F_DH_GEN_KEY, PK11_R_GETATTRIBUTVALUE);
8011 +               goto err;
8012 +               }
8014 +       /* Reuse the memory allocated */
8015 +       pub_key_result[0].pValue = reuse_mem;
8016 +       pub_key_result[0].ulValueLen = reuse_mem_len;
8018 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_pub_key,
8019 +               pub_key_result, pub_key_attr_result_count);
8021 +       if (rv != CKR_OK)
8022 +               {
8023 +               PK11err_add_data(PK11_F_DH_GEN_KEY,
8024 +                   PK11_R_GETATTRIBUTVALUE, rv);
8025 +               goto err;
8026 +               }
8028 +       if (pub_key_result[0].type == CKA_VALUE)
8029 +               {
8030 +               if (dh->pub_key == NULL)
8031 +                       if ((dh->pub_key = BN_new()) == NULL)
8032 +                               {
8033 +                               PK11err(PK11_F_DH_GEN_KEY,
8034 +                                       PK11_R_MALLOC_FAILURE);
8035 +                               goto err;
8036 +                               }
8037 +               dh->pub_key = BN_bin2bn(pub_key_result[0].pValue,
8038 +                       pub_key_result[0].ulValueLen, dh->pub_key);
8039 +               if (dh->pub_key == NULL)
8040 +                       {
8041 +                       PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
8042 +                       goto err;
8043 +                       }
8044 +               }
8046 +       /* Reuse the memory allocated */
8047 +       priv_key_result[0].pValue = reuse_mem;
8048 +       priv_key_result[0].ulValueLen = reuse_mem_len;
8050 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_priv_key,
8051 +               priv_key_result, priv_key_attr_result_count);
8053 +       if (rv != CKR_OK)
8054 +               {
8055 +               PK11err_add_data(PK11_F_DH_GEN_KEY,
8056 +                   PK11_R_GETATTRIBUTVALUE, rv);
8057 +               goto err;
8058 +               }
8060 +       if (priv_key_result[0].type == CKA_VALUE)
8061 +               {
8062 +               if (dh->priv_key == NULL)
8063 +                       if ((dh->priv_key = BN_new()) == NULL)
8064 +                               {
8065 +                               PK11err(PK11_F_DH_GEN_KEY,
8066 +                                       PK11_R_MALLOC_FAILURE);
8067 +                               goto err;
8068 +                               }
8069 +               dh->priv_key = BN_bin2bn(priv_key_result[0].pValue,
8070 +                       priv_key_result[0].ulValueLen, dh->priv_key);
8071 +               if (dh->priv_key == NULL)
8072 +                       {
8073 +                       PK11err(PK11_F_DH_GEN_KEY, PK11_R_MALLOC_FAILURE);
8074 +                       goto err;
8075 +                       }
8076 +               }
8078 +       ret = 1;
8080 +err:
8082 +       if (h_pub_key != CK_INVALID_HANDLE)
8083 +               {
8084 +               rv = pFuncList->C_DestroyObject(sp->session, h_pub_key);
8085 +               if (rv != CKR_OK)
8086 +                       {
8087 +                       PK11err_add_data(PK11_F_DH_GEN_KEY,
8088 +                           PK11_R_DESTROYOBJECT, rv);
8089 +                       }
8090 +               }
8092 +       if (h_priv_key != CK_INVALID_HANDLE)
8093 +               {
8094 +               rv = pFuncList->C_DestroyObject(sp->session, h_priv_key);
8095 +               if (rv != CKR_OK)
8096 +                       {
8097 +                       PK11err_add_data(PK11_F_DH_GEN_KEY,
8098 +                           PK11_R_DESTROYOBJECT, rv);
8099 +                       }
8100 +               }
8102 +       for (i = 1; i <= 2; i++)
8103 +               {
8104 +               if (pub_key_template[i].pValue != NULL)
8105 +                       {
8106 +                       OPENSSL_free(pub_key_template[i].pValue);
8107 +                       pub_key_template[i].pValue = NULL;
8108 +                       }
8109 +               }
8111 +       pk11_return_session(sp, OP_DH);
8112 +       return (ret);
8113 +       }
8115 +static int pk11_DH_compute_key(unsigned char *key, const BIGNUM *pub_key,
8116 +       DH *dh)
8117 +       {
8118 +       unsigned int i;
8119 +       CK_MECHANISM mechanism = {CKM_DH_PKCS_DERIVE, NULL_PTR, 0};
8120 +       CK_OBJECT_CLASS key_class = CKO_SECRET_KEY;
8121 +       CK_KEY_TYPE key_type = CKK_GENERIC_SECRET;
8122 +       CK_OBJECT_HANDLE h_derived_key = CK_INVALID_HANDLE;
8123 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
8125 +       CK_ULONG ul_priv_key_attr_count = 2;
8126 +       CK_ATTRIBUTE priv_key_template[] =
8127 +               {
8128 +               {CKA_CLASS, (void*) NULL, sizeof (key_class)},
8129 +               {CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
8130 +               };
8132 +       CK_ULONG priv_key_attr_result_count = 1;
8133 +       CK_ATTRIBUTE priv_key_result[] =
8134 +               {
8135 +               {CKA_VALUE, (void *)NULL, 0}
8136 +               };
8138 +       CK_RV rv;
8139 +       int ret = -1;
8140 +       PK11_SESSION *sp = NULL;
8142 +       if (dh->priv_key == NULL)
8143 +               goto err;
8145 +       priv_key_template[0].pValue = &key_class;
8146 +       priv_key_template[1].pValue = &key_type;
8148 +       if ((sp = pk11_get_session(OP_DH)) == NULL)
8149 +               goto err;
8151 +       mechanism.ulParameterLen = BN_num_bytes(pub_key);
8152 +       mechanism.pParameter = OPENSSL_malloc(mechanism.ulParameterLen);
8153 +       if (mechanism.pParameter == NULL)
8154 +               {
8155 +               PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
8156 +               goto err;
8157 +               }
8158 +       BN_bn2bin(pub_key, mechanism.pParameter);
8160 +       (void) check_new_dh_key(sp, dh);
8162 +       h_key = sp->opdata_dh_key;
8163 +       if (h_key == CK_INVALID_HANDLE)
8164 +               h_key = sp->opdata_dh_key =
8165 +                       pk11_get_dh_key((DH*) dh, &sp->opdata_dh,
8166 +                           &sp->opdata_dh_priv_num, sp->session);
8168 +       if (h_key == CK_INVALID_HANDLE)
8169 +               {
8170 +               PK11err(PK11_F_DH_COMP_KEY, PK11_R_CREATEOBJECT);
8171 +               goto err;
8172 +               }
8174 +       rv = pFuncList->C_DeriveKey(sp->session,
8175 +           &mechanism,
8176 +           h_key,
8177 +           priv_key_template,
8178 +           ul_priv_key_attr_count,
8179 +           &h_derived_key);
8180 +       if (rv != CKR_OK)
8181 +               {
8182 +               PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_DERIVEKEY, rv);
8183 +               goto err;
8184 +               }
8186 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
8187 +           priv_key_result, priv_key_attr_result_count);
8189 +       if (rv != CKR_OK)
8190 +               {
8191 +               PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
8192 +                   rv);
8193 +               goto err;
8194 +               }
8196 +       if (((CK_LONG) priv_key_result[0].ulValueLen) <= 0)
8197 +               {
8198 +               PK11err(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE);
8199 +               goto err;
8200 +               }
8201 +       priv_key_result[0].pValue =
8202 +               OPENSSL_malloc(priv_key_result[0].ulValueLen);
8203 +       if (!priv_key_result[0].pValue)
8204 +               {
8205 +               PK11err(PK11_F_DH_COMP_KEY, PK11_R_MALLOC_FAILURE);
8206 +               goto err;
8207 +               }
8209 +       rv = pFuncList->C_GetAttributeValue(sp->session, h_derived_key,
8210 +               priv_key_result, priv_key_attr_result_count);
8212 +       if (rv != CKR_OK)
8213 +               {
8214 +               PK11err_add_data(PK11_F_DH_COMP_KEY, PK11_R_GETATTRIBUTVALUE,
8215 +                   rv);
8216 +               goto err;
8217 +               }
8219 +       /*
8220 +        * OpenSSL allocates the output buffer 'key' which is the same
8221 +        * length of the public key. It is long enough for the derived key
8222 +        */
8223 +       if (priv_key_result[0].type == CKA_VALUE)
8224 +               {
8225 +               /*
8226 +                * CKM_DH_PKCS_DERIVE mechanism is not supposed to strip
8227 +                * leading zeros from a computed shared secret. However,
8228 +                * OpenSSL always did it so we must do the same here. The
8229 +                * vagueness of the spec regarding leading zero bytes was
8230 +                * finally cleared with TLS 1.1 (RFC 4346) saying that leading
8231 +                * zeros are stripped before the computed data is used as the
8232 +                * pre-master secret.
8233 +                */
8234 +               for (i = 0; i < priv_key_result[0].ulValueLen; ++i)
8235 +                       {
8236 +                       if (((char *)priv_key_result[0].pValue)[i] != 0)
8237 +                               break;
8238 +                       }
8240 +               (void) memcpy(key, ((char *)priv_key_result[0].pValue) + i,
8241 +                       priv_key_result[0].ulValueLen - i);
8242 +               ret = priv_key_result[0].ulValueLen - i;
8243 +               }
8245 +err:
8247 +       if (h_derived_key != CK_INVALID_HANDLE)
8248 +               {
8249 +               rv = pFuncList->C_DestroyObject(sp->session, h_derived_key);
8250 +               if (rv != CKR_OK)
8251 +                       {
8252 +                       PK11err_add_data(PK11_F_DH_COMP_KEY,
8253 +                           PK11_R_DESTROYOBJECT, rv);
8254 +                       }
8255 +               }
8256 +       if (priv_key_result[0].pValue)
8257 +               {
8258 +               OPENSSL_free(priv_key_result[0].pValue);
8259 +               priv_key_result[0].pValue = NULL;
8260 +               }
8262 +       if (mechanism.pParameter)
8263 +               {
8264 +               OPENSSL_free(mechanism.pParameter);
8265 +               mechanism.pParameter = NULL;
8266 +               }
8268 +       pk11_return_session(sp, OP_DH);
8269 +       return (ret);
8270 +       }
8273 +static CK_OBJECT_HANDLE pk11_get_dh_key(DH* dh,
8274 +       DH **key_ptr, BIGNUM **dh_priv_num, CK_SESSION_HANDLE session)
8275 +       {
8276 +       CK_RV rv;
8277 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
8278 +       CK_OBJECT_CLASS class = CKO_PRIVATE_KEY;
8279 +       CK_KEY_TYPE key_type = CKK_DH;
8280 +       CK_ULONG found;
8281 +       CK_BBOOL rollback = FALSE;
8282 +       int i;
8284 +       CK_ULONG ul_key_attr_count = 7;
8285 +       CK_ATTRIBUTE key_template[] =
8286 +               {
8287 +               {CKA_CLASS, (void*) NULL, sizeof (class)},
8288 +               {CKA_KEY_TYPE, (void*) NULL, sizeof (key_type)},
8289 +               {CKA_DERIVE, &true, sizeof (true)},
8290 +               {CKA_PRIVATE, &false, sizeof (false)},
8291 +               {CKA_PRIME, (void *) NULL, 0},
8292 +               {CKA_BASE, (void *) NULL, 0},
8293 +               {CKA_VALUE, (void *) NULL, 0},
8294 +               };
8296 +       key_template[0].pValue = &class;
8297 +       key_template[1].pValue = &key_type;
8299 +       key_template[4].ulValueLen = BN_num_bytes(dh->p);
8300 +       key_template[4].pValue = (CK_VOID_PTR)OPENSSL_malloc(
8301 +               (size_t)key_template[4].ulValueLen);
8302 +       if (key_template[4].pValue == NULL)
8303 +               {
8304 +               PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8305 +               goto malloc_err;
8306 +               }
8308 +       BN_bn2bin(dh->p, key_template[4].pValue);
8310 +       key_template[5].ulValueLen = BN_num_bytes(dh->g);
8311 +       key_template[5].pValue = (CK_VOID_PTR)OPENSSL_malloc(
8312 +               (size_t)key_template[5].ulValueLen);
8313 +       if (key_template[5].pValue == NULL)
8314 +               {
8315 +               PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8316 +               goto malloc_err;
8317 +               }
8319 +       BN_bn2bin(dh->g, key_template[5].pValue);
8321 +       key_template[6].ulValueLen = BN_num_bytes(dh->priv_key);
8322 +       key_template[6].pValue = (CK_VOID_PTR)OPENSSL_malloc(
8323 +               (size_t)key_template[6].ulValueLen);
8324 +       if (key_template[6].pValue == NULL)
8325 +               {
8326 +               PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8327 +               goto malloc_err;
8328 +               }
8330 +       BN_bn2bin(dh->priv_key, key_template[6].pValue);
8332 +       /* see find_lock array definition for more info on object locking */
8333 +       LOCK_OBJSTORE(OP_DH);
8334 +       rv = pFuncList->C_FindObjectsInit(session, key_template,
8335 +               ul_key_attr_count);
8337 +       if (rv != CKR_OK)
8338 +               {
8339 +               PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSINIT, rv);
8340 +               goto err;
8341 +               }
8343 +       rv = pFuncList->C_FindObjects(session, &h_key, 1, &found);
8345 +       if (rv != CKR_OK)
8346 +               {
8347 +               PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTS, rv);
8348 +               goto err;
8349 +               }
8351 +       rv = pFuncList->C_FindObjectsFinal(session);
8353 +       if (rv != CKR_OK)
8354 +               {
8355 +               PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_FINDOBJECTSFINAL,
8356 +                   rv);
8357 +               goto err;
8358 +               }
8360 +       if (found == 0)
8361 +               {
8362 +               rv = pFuncList->C_CreateObject(session,
8363 +                       key_template, ul_key_attr_count, &h_key);
8364 +               if (rv != CKR_OK)
8365 +                       {
8366 +                       PK11err_add_data(PK11_F_GET_DH_KEY, PK11_R_CREATEOBJECT,
8367 +                           rv);
8368 +                       goto err;
8369 +                       }
8370 +               }
8372 +       if (dh_priv_num != NULL)
8373 +               if ((*dh_priv_num = BN_dup(dh->priv_key)) == NULL)
8374 +                       {
8375 +                       PK11err(PK11_F_GET_DH_KEY, PK11_R_MALLOC_FAILURE);
8376 +                       rollback = TRUE;
8377 +                       goto err;
8378 +                       }
8380 +       /* LINTED: E_CONSTANT_CONDITION */
8381 +       KEY_HANDLE_REFHOLD(h_key, OP_DH, FALSE, rollback, err);
8382 +       if (key_ptr != NULL)
8383 +               *key_ptr = dh;
8385 +err:
8386 +       if (rollback)
8387 +               {
8388 +               /*
8389 +                * We do not care about the return value from C_DestroyObject()
8390 +                * since we are doing rollback.
8391 +                */
8392 +               if (found == 0)
8393 +                       (void) pFuncList->C_DestroyObject(session, h_key);
8394 +               h_key = CK_INVALID_HANDLE;
8395 +               }
8397 +       UNLOCK_OBJSTORE(OP_DH);
8399 +malloc_err:
8400 +       for (i = 4; i <= 6; i++)
8401 +               {
8402 +               if (key_template[i].pValue != NULL)
8403 +                       {
8404 +                       OPENSSL_free(key_template[i].pValue);
8405 +                       key_template[i].pValue = NULL;
8406 +                       }
8407 +               }
8409 +       return (h_key);
8410 +       }
8413 + * Check for cache miss and clean the object pointer and handle
8414 + * in such case. Return 1 for cache hit, 0 for cache miss.
8415 + *
8416 + * Note: we rely on pk11_destroy_dh_key_objects() to set sp->opdata_dh
8417 + *       to CK_INVALID_HANDLE even when it fails to destroy the object.
8418 + */
8419 +static int check_new_dh_key(PK11_SESSION *sp, DH *dh)
8420 +       {
8421 +       /*
8422 +        * Provide protection against DH structure reuse by making the
8423 +        * check for cache hit stronger. Private key component of DH key
8424 +        * is unique so it is sufficient to compare it with value cached
8425 +        * in PK11_SESSION structure.
8426 +        */
8427 +       if ((sp->opdata_dh != dh) ||
8428 +           (BN_cmp(sp->opdata_dh_priv_num, dh->priv_key) != 0))
8429 +               {
8430 +               /*
8431 +                * We do not check the return value because even in case of
8432 +                * failure the sp structure will have both key pointer
8433 +                * and object handle cleaned and pk11_destroy_object()
8434 +                * reports the failure to the OpenSSL error message buffer.
8435 +                */
8436 +               (void) pk11_destroy_dh_object(sp, TRUE);
8437 +               return (0);
8438 +               }
8439 +       return (1);
8440 +       }
8441 +#endif
8444 + * Local function to simplify key template population
8445 + * Return 0 -- error, 1 -- no error
8446 + */
8447 +static int init_template_value(BIGNUM *bn, CK_VOID_PTR *p_value,
8448 +       CK_ULONG *ul_value_len)
8449 +       {
8450 +       CK_ULONG len = BN_num_bytes(bn);
8451 +       if (len == 0)
8452 +               return (1);
8454 +       *ul_value_len = len;
8455 +       *p_value = (CK_VOID_PTR)OPENSSL_malloc((size_t)*ul_value_len);
8456 +       if (*p_value == NULL)
8457 +               return (0);
8459 +       BN_bn2bin(bn, *p_value);
8461 +       return (1);
8462 +       }
8464 +static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn)
8465 +       {
8466 +       if (attr->ulValueLen > 0)
8467 +               {
8468 +               *bn = BN_bin2bn(attr_data, attr->ulValueLen, NULL);
8469 +               }
8470 +       }
8471 +#ifdef OPENSSL_SYS_WIN32
8472 +char *getpassphrase(const char *prompt)
8473 +       {
8474 +       static char buf[128];
8475 +       HANDLE h;
8476 +       DWORD cc, mode;
8477 +       int cnt;
8479 +       h = GetStdHandle(STD_INPUT_HANDLE);
8480 +       fputs(prompt, stderr);
8481 +       fflush(stderr);
8482 +       fflush(stdout);
8483 +       FlushConsoleInputBuffer(h);
8484 +       GetConsoleMode(h, &mode);
8485 +       SetConsoleMode(h, ENABLE_PROCESSED_INPUT);
8487 +       for (cnt = 0; cnt < sizeof(buf) - 1; cnt++)
8488 +               {
8489 +               ReadFile(h, buf + cnt, 1, &cc, NULL);
8490 +               if (buf[cnt] == '\r')
8491 +                       break;
8492 +               fputc('*', stdout);
8493 +               fflush(stderr);
8494 +               fflush(stdout);
8495 +               }
8497 +       SetConsoleMode(h, mode);
8498 +       buf[cnt] = '\0';
8499 +       fputs("\n", stderr);
8500 +       return buf;
8501 +       }
8502 +#endif /* OPENSSL_SYS_WIN32 */
8503 +#endif /* OPENSSL_NO_HW_PK11CA */
8504 +#endif /* OPENSSL_NO_HW_PK11 */
8505 +#endif /* OPENSSL_NO_HW */
8506 Index: openssl/crypto/engine/hw_pk11ca.h
8507 diff -u /dev/null openssl/crypto/engine/hw_pk11ca.h:1.2
8508 --- /dev/null   Mon Oct  5 13:17:24 2009
8509 +++ openssl/crypto/engine/hw_pk11ca.h   Mon Oct  5 13:17:03 2009
8510 @@ -0,0 +1,28 @@
8511 +/* Redefine all pk11/PK11 external symbols to pk11ca/PK11CA */
8513 +#define find_lock                      pk11ca_find_lock
8514 +#define active_list                    pk11ca_active_list
8515 +#define ERR_pk11_error                 ERR_pk11ca_error
8516 +#define PK11err_add_data               PK11CAerr_add_data
8517 +#define pk11_get_session               pk11ca_get_session
8518 +#define pk11_return_session            pk11ca_return_session
8519 +#define pk11_active_add                        pk11ca_active_add
8520 +#define pk11_active_delete             pk11ca_active_delete
8521 +#define pk11_active_remove             pk11ca_active_remove
8522 +#define pk11_free_active_list          pk11ca_free_active_list
8523 +#define pk11_destroy_rsa_key_objects   pk11ca_destroy_rsa_key_objects
8524 +#define pk11_destroy_rsa_object_pub    pk11ca_destroy_rsa_object_pub
8525 +#define pk11_destroy_rsa_object_priv   pk11ca_destroy_rsa_object_priv
8526 +#define pk11_load_privkey              pk11ca_load_privkey
8527 +#define pk11_load_pubkey               pk11ca_load_pubkey
8528 +#define PK11_RSA                       PK11CA_RSA
8529 +#define pk11_destroy_dsa_key_objects   pk11ca_destroy_dsa_key_objects
8530 +#define pk11_destroy_dsa_object_pub    pk11ca_destroy_dsa_object_pub
8531 +#define pk11_destroy_dsa_object_priv   pk11ca_destroy_dsa_object_priv
8532 +#define PK11_DSA                       PK11CA_DSA
8533 +#define pk11_destroy_dh_key_objects    pk11ca_destroy_dh_key_objects
8534 +#define pk11_destroy_dh_object         pk11ca_destroy_dh_object
8535 +#define PK11_DH                                PK11CA_DH
8536 +#define pFuncList                      pk11ca_pFuncList
8537 +#define pk11_pin                       pk11ca_pin
8538 +#define ENGINE_load_pk11               ENGINE_load_pk11ca
8539 Index: openssl/crypto/engine/hw_pk11so.c
8540 diff -u /dev/null openssl/crypto/engine/hw_pk11so.c:1.2
8541 --- /dev/null   Mon Oct  5 13:17:24 2009
8542 +++ openssl/crypto/engine/hw_pk11so.c   Mon Oct  5 13:17:03 2009
8543 @@ -0,0 +1,1618 @@
8545 + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
8546 + * Use is subject to license terms.
8547 + */
8549 +/* crypto/engine/hw_pk11.c */
8551 + * This product includes software developed by the OpenSSL Project for
8552 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
8553 + *
8554 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
8555 + * Afchine Madjlessi.
8556 + */
8558 + * ====================================================================
8559 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
8560 + *
8561 + * Redistribution and use in source and binary forms, with or without
8562 + * modification, are permitted provided that the following conditions
8563 + * are met:
8564 + *
8565 + * 1. Redistributions of source code must retain the above copyright
8566 + *    notice, this list of conditions and the following disclaimer.
8567 + *
8568 + * 2. Redistributions in binary form must reproduce the above copyright
8569 + *    notice, this list of conditions and the following disclaimer in
8570 + *    the documentation and/or other materials provided with the
8571 + *    distribution.
8572 + *
8573 + * 3. All advertising materials mentioning features or use of this
8574 + *    software must display the following acknowledgment:
8575 + *    "This product includes software developed by the OpenSSL Project
8576 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
8577 + *
8578 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
8579 + *    endorse or promote products derived from this software without
8580 + *    prior written permission. For written permission, please contact
8581 + *    licensing@OpenSSL.org.
8582 + *
8583 + * 5. Products derived from this software may not be called "OpenSSL"
8584 + *    nor may "OpenSSL" appear in their names without prior written
8585 + *    permission of the OpenSSL Project.
8586 + *
8587 + * 6. Redistributions of any form whatsoever must retain the following
8588 + *    acknowledgment:
8589 + *    "This product includes software developed by the OpenSSL Project
8590 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
8591 + *
8592 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
8593 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
8594 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
8595 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
8596 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8597 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
8598 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
8599 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
8600 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
8601 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
8602 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
8603 + * OF THE POSSIBILITY OF SUCH DAMAGE.
8604 + * ====================================================================
8605 + *
8606 + * This product includes cryptographic software written by Eric Young
8607 + * (eay@cryptsoft.com).  This product includes software written by Tim
8608 + * Hudson (tjh@cryptsoft.com).
8609 + *
8610 + */
8612 +/* Modified to keep only RNG and RSA Sign */
8614 +#ifdef OPENSSL_NO_RSA
8615 +#error RSA is disabled
8616 +#endif
8618 +#include <stdio.h>
8619 +#include <stdlib.h>
8620 +#include <string.h>
8621 +#include <sys/types.h>
8623 +#include <openssl/e_os2.h>
8624 +#include <openssl/crypto.h>
8625 +#include <cryptlib.h>
8626 +#include <openssl/engine.h>
8627 +#include <openssl/dso.h>
8628 +#include <openssl/err.h>
8629 +#include <openssl/bn.h>
8630 +#include <openssl/md5.h>
8631 +#include <openssl/pem.h>
8632 +#include <openssl/rsa.h>
8633 +#include <openssl/rand.h>
8634 +#include <openssl/objects.h>
8635 +#include <openssl/x509.h>
8637 +#ifdef OPENSSL_SYS_WIN32
8638 +typedef int pid_t;
8639 +#define getpid() GetCurrentProcessId()
8640 +#define NOPTHREADS
8641 +#ifndef NULL_PTR
8642 +#define NULL_PTR NULL
8643 +#endif
8644 +#define CK_DEFINE_FUNCTION(returnType, name) \
8645 +       returnType __declspec(dllexport) name
8646 +#define CK_DECLARE_FUNCTION(returnType, name) \
8647 +       returnType __declspec(dllimport) name
8648 +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
8649 +       returnType __declspec(dllimport) (* name)
8650 +#else
8651 +#include <signal.h>
8652 +#include <unistd.h>
8653 +#include <dlfcn.h>
8654 +#endif
8656 +#ifndef NOPTHREADS
8657 +#include <pthread.h>
8658 +#endif
8660 +#ifndef OPENSSL_NO_HW
8661 +#ifndef OPENSSL_NO_HW_PK11
8662 +#ifndef OPENSSL_NO_HW_PK11SO
8664 +/* label for debug messages printed on stderr */
8665 +#define        PK11_DBG        "PKCS#11 ENGINE DEBUG"
8666 +/* prints a lot of debug messages on stderr about slot selection process */
8667 +/*#undef       DEBUG_SLOT_SELECTION */
8669 +#ifndef OPENSSL_NO_DSA
8670 +#define OPENSSL_NO_DSA
8671 +#endif
8672 +#ifndef OPENSSL_NO_DH
8673 +#define OPENSSL_NO_DH
8674 +#endif
8676 +#ifdef OPENSSL_SYS_WIN32
8677 +#pragma pack(push, cryptoki, 1)
8678 +#include "cryptoki.h"
8679 +#include "pkcs11.h"
8680 +#pragma pack(pop, cryptoki)
8681 +#else
8682 +#include "cryptoki.h"
8683 +#include "pkcs11.h"
8684 +#endif
8685 +#include "hw_pk11so.h"
8686 +#include "hw_pk11_err.c"
8688 +/* PKCS#11 session caches and their locks for all operation types */
8689 +static PK11_CACHE session_cache[OP_MAX];
8692 + * As stated in v2.20, 11.7 Object Management Function, in section for
8693 + * C_FindObjectsInit(), at most one search operation may be active at a given
8694 + * time in a given session. Therefore, C_Find{,Init,Final}Objects() should be
8695 + * grouped together to form one atomic search operation. This is already
8696 + * ensured by the property of unique PKCS#11 session handle used for each
8697 + * PK11_SESSION object.
8698 + *
8699 + * This is however not the biggest concern - maintaining consistency of the
8700 + * underlying object store is more important. The same section of the spec also
8701 + * says that one thread can be in the middle of a search operation while another
8702 + * thread destroys the object matching the search template which would result in
8703 + * invalid handle returned from the search operation.
8704 + *
8705 + * Hence, the following locks are used for both protection of the object stores.
8706 + * They are also used for active list protection.
8707 + */
8708 +#ifndef NOPTHREADS
8709 +pthread_mutex_t *find_lock[OP_MAX] = { NULL };
8710 +#endif
8713 + * lists of asymmetric key handles which are active (referenced by at least one
8714 + * PK11_SESSION structure, either held by a thread or present in free_session
8715 + * list) for given algorithm type
8716 + */
8717 +PK11_active *active_list[OP_MAX] = { NULL };
8720 + * Create all secret key objects in a global session so that they are available
8721 + * to use for other sessions. These other sessions may be opened or closed
8722 + * without losing the secret key objects.
8723 + */
8724 +static CK_SESSION_HANDLE       global_session = CK_INVALID_HANDLE;
8726 +/* ENGINE level stuff */
8727 +static int pk11_init(ENGINE *e);
8728 +static int pk11_library_init(ENGINE *e);
8729 +static int pk11_finish(ENGINE *e);
8730 +static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void));
8731 +static int pk11_destroy(ENGINE *e);
8733 +/* RAND stuff */
8734 +static void pk11_rand_seed(const void *buf, int num);
8735 +static void pk11_rand_add(const void *buf, int num, double add_entropy);
8736 +static void pk11_rand_cleanup(void);
8737 +static int pk11_rand_bytes(unsigned char *buf, int num);
8738 +static int pk11_rand_status(void);
8740 +/* These functions are also used in other files */
8741 +PK11_SESSION *pk11_get_session(PK11_OPTYPE optype);
8742 +void pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype);
8744 +/* active list manipulation functions used in this file */
8745 +extern int pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type);
8746 +extern void pk11_free_active_list(PK11_OPTYPE type);
8748 +int pk11_destroy_rsa_key_objects(PK11_SESSION *session);
8749 +int pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock);
8750 +int pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock);
8752 +/* Local helper functions */
8753 +static int pk11_free_all_sessions(void);
8754 +static int pk11_free_session_list(PK11_OPTYPE optype);
8755 +static int pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype);
8756 +static int pk11_destroy_object(CK_SESSION_HANDLE session,
8757 +       CK_OBJECT_HANDLE oh);
8758 +static const char *get_PK11_LIBNAME(void);
8759 +static void free_PK11_LIBNAME(void);
8760 +static long set_PK11_LIBNAME(const char *name);
8762 +static int pk11_choose_slots(int *any_slot_found);
8764 +static int pk11_init_all_locks(void);
8765 +static void pk11_free_all_locks(void);
8767 +#define        TRY_OBJ_DESTROY(sess_hdl, obj_hdl, retval, uselock, alg_type)   \
8768 +       {                                                               \
8769 +       if (uselock)                                                    \
8770 +               LOCK_OBJSTORE(alg_type);                                \
8771 +       if (pk11_active_delete(obj_hdl, alg_type) == 1)                 \
8772 +               {                                                       \
8773 +               retval = pk11_destroy_object(sess_hdl, obj_hdl);        \
8774 +               }                                                       \
8775 +       if (uselock)                                                    \
8776 +               UNLOCK_OBJSTORE(alg_type);                              \
8777 +       }
8779 +#define        TRY_OBJ_DELETE(sess_hdl, obj_hdl, retval, uselock, alg_type)    \
8780 +       {                                                               \
8781 +       if (uselock)                                                    \
8782 +               LOCK_OBJSTORE(alg_type);                                \
8783 +       (void) pk11_active_delete(obj_hdl, alg_type);                   \
8784 +       if (uselock)                                                    \
8785 +               UNLOCK_OBJSTORE(alg_type);                              \
8786 +       }
8788 +static CK_BBOOL pk11_have_rsa  = CK_FALSE;
8789 +static CK_BBOOL pk11_have_random = CK_FALSE;
8792 + * Initialization function. Sets up various PKCS#11 library components.
8793 + * The definitions for control commands specific to this engine
8794 + */
8795 +#define PK11_CMD_SO_PATH               ENGINE_CMD_BASE
8796 +#define PK11_CMD_PIN                   (ENGINE_CMD_BASE+1)
8797 +#define PK11_CMD_SLOT                  (ENGINE_CMD_BASE+2)
8798 +static const ENGINE_CMD_DEFN pk11_cmd_defns[] =
8799 +       {
8800 +               {
8801 +               PK11_CMD_SO_PATH,
8802 +               "SO_PATH",
8803 +               "Specifies the path to the 'pkcs#11' shared library",
8804 +               ENGINE_CMD_FLAG_STRING
8805 +               },
8806 +               {
8807 +               PK11_CMD_PIN,
8808 +               "PIN",
8809 +               "Specifies the pin code",
8810 +               ENGINE_CMD_FLAG_STRING
8811 +               },
8812 +               {
8813 +               PK11_CMD_SLOT,
8814 +               "SLOT",
8815 +               "Specifies the slot (default is auto select)",
8816 +               ENGINE_CMD_FLAG_NUMERIC,
8817 +               },
8818 +               {0, NULL, NULL, 0}
8819 +       };
8822 +static RAND_METHOD pk11_random =
8823 +       {
8824 +       pk11_rand_seed,
8825 +       pk11_rand_bytes,
8826 +       pk11_rand_cleanup,
8827 +       pk11_rand_add,
8828 +       pk11_rand_bytes,
8829 +       pk11_rand_status
8830 +       };
8833 +/* Constants used when creating the ENGINE */
8834 +#ifdef OPENSSL_NO_HW_PK11CA
8835 +#error "can't load both crypto-accelerator and sign-only PKCS#11 engines"
8836 +#endif
8837 +static const char *engine_pk11_id = "pkcs11";
8838 +static const char *engine_pk11_name = "PKCS #11 engine support (sign only)";
8840 +CK_FUNCTION_LIST_PTR pFuncList = NULL;
8841 +static const char PK11_GET_FUNCTION_LIST[] = "C_GetFunctionList";
8844 + * These is the static string constant for the DSO file name and the function
8845 + * symbol names to bind to.
8846 + */
8847 +static const char def_PK11_LIBNAME[] = PK11_LIB_LOCATION;
8849 +static CK_SLOT_ID pubkey_SLOTID = 0;
8850 +static CK_SLOT_ID rand_SLOTID = 0;
8851 +static CK_SLOT_ID SLOTID = 0;
8852 +char *pk11_pin = NULL;
8853 +static CK_BBOOL pk11_library_initialized = FALSE;
8854 +static CK_BBOOL pk11_atfork_initialized = FALSE;
8855 +static int pk11_pid = 0;
8857 +static DSO *pk11_dso = NULL;
8859 +/* allocate and initialize all locks used by the engine itself */
8860 +static int pk11_init_all_locks(void)
8861 +       {
8862 +#ifndef NOPTHREADS
8863 +       int type;
8865 +       find_lock[OP_RSA] = OPENSSL_malloc(sizeof (pthread_mutex_t));
8866 +       if (find_lock[OP_RSA] == NULL)
8867 +               goto malloc_err;
8868 +       (void) pthread_mutex_init(find_lock[OP_RSA], NULL);
8870 +       for (type = 0; type < OP_MAX; type++)
8871 +               {
8872 +               session_cache[type].lock =
8873 +                   OPENSSL_malloc(sizeof (pthread_mutex_t));
8874 +               if (session_cache[type].lock == NULL)
8875 +                       goto malloc_err;
8876 +               (void) pthread_mutex_init(session_cache[type].lock, NULL);
8877 +               }
8879 +       return (1);
8881 +malloc_err:
8882 +       pk11_free_all_locks();
8883 +       PK11err(PK11_F_INIT_ALL_LOCKS, PK11_R_MALLOC_FAILURE);
8884 +       return (0);
8885 +#else
8886 +       return (1);
8887 +#endif
8888 +       }
8890 +static void pk11_free_all_locks(void)
8891 +       {
8892 +#ifndef NOPTHREADS
8893 +       int type;
8895 +       if (find_lock[OP_RSA] != NULL)
8896 +               {
8897 +               (void) pthread_mutex_destroy(find_lock[OP_RSA]);
8898 +               OPENSSL_free(find_lock[OP_RSA]);
8899 +               find_lock[OP_RSA] = NULL;
8900 +               }
8902 +       for (type = 0; type < OP_MAX; type++)
8903 +               {
8904 +               if (session_cache[type].lock != NULL)
8905 +                       {
8906 +                       (void) pthread_mutex_destroy(session_cache[type].lock);
8907 +                       OPENSSL_free(session_cache[type].lock);
8908 +                       session_cache[type].lock = NULL;
8909 +                       }
8910 +               }
8911 +#endif
8912 +       }
8915 + * This internal function is used by ENGINE_pk11() and "dynamic" ENGINE support.
8916 + */
8917 +static int bind_pk11(ENGINE *e)
8918 +       {
8919 +       if (!pk11_library_initialized)
8920 +               if (!pk11_library_init(e))
8921 +                       return (0);
8923 +       if (!ENGINE_set_id(e, engine_pk11_id) ||
8924 +           !ENGINE_set_name(e, engine_pk11_name))
8925 +               return (0);
8927 +       if (pk11_have_rsa == CK_TRUE)
8928 +               {
8929 +               if (!ENGINE_set_RSA(e, PK11_RSA()) ||
8930 +                   !ENGINE_set_load_privkey_function(e, pk11_load_privkey) ||
8931 +                   !ENGINE_set_load_pubkey_function(e, pk11_load_pubkey))
8932 +                       return (0);
8933 +#ifdef DEBUG_SLOT_SELECTION
8934 +               fprintf(stderr, "%s: registered RSA\n", PK11_DBG);
8935 +#endif /* DEBUG_SLOT_SELECTION */
8936 +               }
8938 +       if (pk11_have_random)
8939 +               {
8940 +               if (!ENGINE_set_RAND(e, &pk11_random))
8941 +                       return (0);
8942 +#ifdef DEBUG_SLOT_SELECTION
8943 +               fprintf(stderr, "%s: registered random\n", PK11_DBG);
8944 +#endif /* DEBUG_SLOT_SELECTION */
8945 +               }
8946 +       if (!ENGINE_set_init_function(e, pk11_init) ||
8947 +           !ENGINE_set_destroy_function(e, pk11_destroy) ||
8948 +           !ENGINE_set_finish_function(e, pk11_finish) ||
8949 +           !ENGINE_set_ctrl_function(e, pk11_ctrl) ||
8950 +           !ENGINE_set_cmd_defns(e, pk11_cmd_defns))
8951 +               return (0);
8953 +       /* Ensure the pk11 error handling is set up */
8954 +       ERR_load_pk11_strings();
8956 +       return (1);
8957 +       }
8959 +/* Dynamic engine support is disabled at a higher level for Solaris */
8960 +#ifdef ENGINE_DYNAMIC_SUPPORT
8961 +#error "dynamic engine not supported"
8962 +static int bind_helper(ENGINE *e, const char *id)
8963 +       {
8964 +       if (id && (strcmp(id, engine_pk11_id) != 0))
8965 +               return (0);
8967 +       if (!bind_pk11(e))
8968 +               return (0);
8970 +       return (1);
8971 +       }
8973 +IMPLEMENT_DYNAMIC_CHECK_FN()
8974 +IMPLEMENT_DYNAMIC_BIND_FN(bind_helper)
8976 +#else
8977 +static ENGINE *engine_pk11(void)
8978 +       {
8979 +       ENGINE *ret = ENGINE_new();
8981 +       if (!ret)
8982 +               return (NULL);
8984 +       if (!bind_pk11(ret))
8985 +               {
8986 +               ENGINE_free(ret);
8987 +               return (NULL);
8988 +               }
8990 +       return (ret);
8991 +       }
8993 +void
8994 +ENGINE_load_pk11(void)
8995 +       {
8996 +       ENGINE *e_pk11 = NULL;
8998 +       /*
8999 +        * Do not use dynamic PKCS#11 library on Solaris due to
9000 +        * security reasons. We will link it in statically.
9001 +        */
9002 +       /* Attempt to load PKCS#11 library */
9003 +       if (!pk11_dso)
9004 +               pk11_dso = DSO_load(NULL, get_PK11_LIBNAME(), NULL, 0);
9006 +       if (pk11_dso == NULL)
9007 +               {
9008 +               PK11err(PK11_F_LOAD, PK11_R_DSO_FAILURE);
9009 +               return;
9010 +               }
9012 +       e_pk11 = engine_pk11();
9013 +       if (!e_pk11)
9014 +               {
9015 +               DSO_free(pk11_dso);
9016 +               pk11_dso = NULL;
9017 +               return;
9018 +               }
9020 +       /*
9021 +        * At this point, the pk11 shared library is either dynamically
9022 +        * loaded or statically linked in. So, initialize the pk11
9023 +        * library before calling ENGINE_set_default since the latter
9024 +        * needs cipher and digest algorithm information
9025 +        */
9026 +       if (!pk11_library_init(e_pk11))
9027 +               {
9028 +               DSO_free(pk11_dso);
9029 +               pk11_dso = NULL;
9030 +               ENGINE_free(e_pk11);
9031 +               return;
9032 +               }
9034 +       ENGINE_add(e_pk11);
9036 +       ENGINE_free(e_pk11);
9037 +       ERR_clear_error();
9038 +       }
9039 +#endif /* ENGINE_DYNAMIC_SUPPORT */
9042 + * These are the static string constants for the DSO file name and
9043 + * the function symbol names to bind to.
9044 + */
9045 +static const char *PK11_LIBNAME = NULL;
9047 +static const char *get_PK11_LIBNAME(void)
9048 +       {
9049 +       if (PK11_LIBNAME)
9050 +               return (PK11_LIBNAME);
9052 +       return (def_PK11_LIBNAME);
9053 +       }
9055 +static void free_PK11_LIBNAME(void)
9056 +       {
9057 +       if (PK11_LIBNAME)
9058 +               OPENSSL_free((void*)PK11_LIBNAME);
9060 +       PK11_LIBNAME = NULL;
9061 +       }
9063 +static long set_PK11_LIBNAME(const char *name)
9064 +       {
9065 +       free_PK11_LIBNAME();
9067 +       return ((PK11_LIBNAME = BUF_strdup(name)) != NULL ? 1 : 0);
9068 +       }
9070 +/* acquire all engine specific mutexes before fork */
9071 +static void pk11_fork_prepare(void)
9072 +       {
9073 +#ifndef NOPTHREADS
9074 +       int i;
9076 +       if (!pk11_library_initialized)
9077 +               return;
9079 +       LOCK_OBJSTORE(OP_RSA);
9080 +       for (i = 0; i < OP_MAX; i++)
9081 +               {
9082 +               (void) pthread_mutex_lock(session_cache[i].lock);
9083 +               }
9084 +#endif
9085 +       }
9087 +/* release all engine specific mutexes */
9088 +static void pk11_fork_parent(void)
9089 +       {
9090 +#ifndef NOPTHREADS
9091 +       int i;
9093 +       if (!pk11_library_initialized)
9094 +               return;
9096 +       for (i = OP_MAX - 1; i >= 0; i--)
9097 +               {
9098 +               (void) pthread_mutex_unlock(session_cache[i].lock);
9099 +               }
9100 +       UNLOCK_OBJSTORE(OP_RSA);
9101 +#endif
9102 +       }
9105 + * same situation as in parent - we need to unlock all locks to make them
9106 + * accessible to all threads.
9107 + */
9108 +static void pk11_fork_child(void)
9109 +       {
9110 +#ifndef NOPTHREADS
9111 +       int i;
9113 +       if (!pk11_library_initialized)
9114 +               return;
9116 +       for (i = OP_MAX - 1; i >= 0; i--)
9117 +               {
9118 +               (void) pthread_mutex_unlock(session_cache[i].lock);
9119 +               }
9120 +       UNLOCK_OBJSTORE(OP_RSA);
9121 +#endif
9122 +       }
9124 +/* Initialization function for the pk11 engine */
9125 +static int pk11_init(ENGINE *e)
9127 +       return (pk11_library_init(e));
9131 + * Initialization function. Sets up various PKCS#11 library components.
9132 + * It selects a slot based on predefined critiera. In the process, it also
9133 + * count how many ciphers and digests to support. Since the cipher and
9134 + * digest information is needed when setting default engine, this function
9135 + * needs to be called before calling ENGINE_set_default.
9136 + */
9137 +/* ARGSUSED */
9138 +static int pk11_library_init(ENGINE *e)
9139 +       {
9140 +       CK_C_GetFunctionList p;
9141 +       CK_RV rv = CKR_OK;
9142 +       CK_INFO info;
9143 +       int any_slot_found;
9144 +       int i;
9145 +#ifndef OPENSSL_SYS_WIN32
9146 +       struct sigaction sigint_act, sigterm_act, sighup_act;
9147 +#endif
9149 +       /*
9150 +        * pk11_library_initialized is set to 0 in pk11_finish() which is called
9151 +        * from ENGINE_finish(). However, if there is still at least one
9152 +        * existing functional reference to the engine (see engine(3) for more
9153 +        * information), pk11_finish() is skipped. For example, this can happen
9154 +        * if an application forgets to clear one cipher context. In case of a
9155 +        * fork() when the application is finishing the engine so that it can be
9156 +        * reinitialized in the child, forgotten functional reference causes
9157 +        * pk11_library_initialized to stay 1. In that case we need the PID
9158 +        * check so that we properly initialize the engine again.
9159 +        */
9160 +       if (pk11_library_initialized)
9161 +               {
9162 +               if (pk11_pid == getpid())
9163 +                       {
9164 +                       return (1);
9165 +                       }
9166 +               else
9167 +                       {
9168 +                       global_session = CK_INVALID_HANDLE;
9169 +                       /*
9170 +                        * free the locks first to prevent memory leak in case
9171 +                        * the application calls fork() without finishing the
9172 +                        * engine first.
9173 +                        */
9174 +                       pk11_free_all_locks();
9175 +                       }
9176 +               }
9178 +       if (pk11_dso == NULL)
9179 +               {
9180 +               PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
9181 +               goto err;
9182 +               }
9184 +       /* get the C_GetFunctionList function from the loaded library */
9185 +       p = (CK_C_GetFunctionList)DSO_bind_func(pk11_dso,
9186 +               PK11_GET_FUNCTION_LIST);
9187 +       if (!p)
9188 +               {
9189 +               PK11err(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE);
9190 +               goto err;
9191 +               }
9193 +       /* get the full function list from the loaded library */
9194 +       rv = p(&pFuncList);
9195 +       if (rv != CKR_OK)
9196 +               {
9197 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_DSO_FAILURE, rv);
9198 +               goto err;
9199 +               }
9201 +#ifndef OPENSSL_SYS_WIN32
9202 +       /* Not all PKCS#11 library are signal safe! */
9204 +       (void) memset(&sigint_act, 0, sizeof(sigint_act));
9205 +       (void) memset(&sigterm_act, 0, sizeof(sigterm_act));
9206 +       (void) memset(&sighup_act, 0, sizeof(sighup_act));
9207 +       (void) sigaction(SIGINT, NULL, &sigint_act);
9208 +       (void) sigaction(SIGTERM, NULL, &sigterm_act);
9209 +       (void) sigaction(SIGHUP, NULL, &sighup_act);
9210 +#endif
9211 +       rv = pFuncList->C_Initialize(NULL_PTR);
9212 +#ifndef OPENSSL_SYS_WIN32
9213 +       (void) sigaction(SIGINT, &sigint_act, NULL);
9214 +       (void) sigaction(SIGTERM, &sigterm_act, NULL);
9215 +       (void) sigaction(SIGHUP, &sighup_act, NULL);
9216 +#endif
9217 +       if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
9218 +               {
9219 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_INITIALIZE, rv);
9220 +               goto err;
9221 +               }
9223 +       rv = pFuncList->C_GetInfo(&info);
9224 +       if (rv != CKR_OK)
9225 +               {
9226 +               PK11err_add_data(PK11_F_LIBRARY_INIT, PK11_R_GETINFO, rv);
9227 +               goto err;
9228 +               }
9230 +       if (pk11_choose_slots(&any_slot_found) == 0)
9231 +               goto err;
9233 +       /*
9234 +        * The library we use, set in def_PK11_LIBNAME, may not offer any
9235 +        * slot(s). In that case, we must not proceed but we must not return an
9236 +        * error. The reason is that applications that try to set up the PKCS#11
9237 +        * engine don't exit on error during the engine initialization just
9238 +        * because no slot was present.
9239 +        */
9240 +       if (any_slot_found == 0)
9241 +               return (1);
9243 +       if (global_session == CK_INVALID_HANDLE)
9244 +               {
9245 +               /* Open the global_session for the new process */
9246 +               rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
9247 +                       NULL_PTR, NULL_PTR, &global_session);
9248 +               if (rv != CKR_OK)
9249 +                       {
9250 +                       PK11err_add_data(PK11_F_LIBRARY_INIT,
9251 +                           PK11_R_OPENSESSION, rv);
9252 +                       goto err;
9253 +                       }
9254 +               }
9256 +       pk11_library_initialized = TRUE;
9257 +       pk11_pid = getpid();
9258 +       /*
9259 +        * if initialization of the locks fails pk11_init_all_locks()
9260 +        * will do the cleanup.
9261 +        */
9262 +       if (!pk11_init_all_locks())
9263 +               goto err;
9264 +       for (i = 0; i < OP_MAX; i++)
9265 +               session_cache[i].head = NULL;
9266 +       /*
9267 +        * initialize active lists. We only use active lists
9268 +        * for asymmetric ciphers.
9269 +        */
9270 +       for (i = 0; i < OP_MAX; i++)
9271 +               active_list[i] = NULL;
9273 +#ifndef NOPTHREADS
9274 +       if (!pk11_atfork_initialized)
9275 +               {
9276 +               if (pthread_atfork(pk11_fork_prepare, pk11_fork_parent,
9277 +                   pk11_fork_child) != 0)
9278 +                       {
9279 +                       PK11err(PK11_F_LIBRARY_INIT, PK11_R_ATFORK_FAILED);
9280 +                       goto err;
9281 +                       }
9282 +               pk11_atfork_initialized = TRUE;
9283 +               }
9284 +#endif
9286 +       return (1);
9288 +err:
9289 +       return (0);
9290 +       }
9292 +/* Destructor (complements the "ENGINE_pk11()" constructor) */
9293 +/* ARGSUSED */
9294 +static int pk11_destroy(ENGINE *e)
9295 +       {
9296 +       free_PK11_LIBNAME();
9297 +       ERR_unload_pk11_strings();
9298 +       if (pk11_pin) {
9299 +               memset(pk11_pin, 0, strlen(pk11_pin));
9300 +               OPENSSL_free((void*)pk11_pin);
9301 +       }
9302 +       pk11_pin = NULL;
9303 +       return (1);
9304 +       }
9307 + * Termination function to clean up the session, the token, and the pk11
9308 + * library.
9309 + */
9310 +/* ARGSUSED */
9311 +static int pk11_finish(ENGINE *e)
9312 +       {
9313 +       int i;
9315 +       if (pk11_pin) {
9316 +               memset(pk11_pin, 0, strlen(pk11_pin));
9317 +               OPENSSL_free((void*)pk11_pin);
9318 +       }
9319 +       pk11_pin = NULL;
9321 +       if (pk11_dso == NULL)
9322 +               {
9323 +               PK11err(PK11_F_FINISH, PK11_R_NOT_LOADED);
9324 +               goto err;
9325 +               }
9327 +       OPENSSL_assert(pFuncList != NULL);
9329 +       if (pk11_free_all_sessions() == 0)
9330 +               goto err;
9332 +       /* free all active lists */
9333 +       for (i = 0; i < OP_MAX; i++)
9334 +               pk11_free_active_list(i);
9336 +       pFuncList->C_CloseSession(global_session);
9337 +       global_session = CK_INVALID_HANDLE;
9339 +       /*
9340 +        * Since we are part of a library (libcrypto.so), calling this function
9341 +        * may have side-effects.
9342 +        */
9343 +#if 0
9344 +       pFuncList->C_Finalize(NULL);
9345 +#endif
9347 +       if (!DSO_free(pk11_dso))
9348 +               {
9349 +               PK11err(PK11_F_FINISH, PK11_R_DSO_FAILURE);
9350 +               goto err;
9351 +               }
9352 +       pk11_dso = NULL;
9353 +       pFuncList = NULL;
9354 +       pk11_library_initialized = FALSE;
9355 +       pk11_pid = 0;
9356 +       /*
9357 +        * There is no way how to unregister atfork handlers (other than
9358 +        * unloading the library) so we just free the locks. For this reason
9359 +        * the atfork handlers check if the engine is initialized and bail out
9360 +        * immediately if not. This is necessary in case a process finishes
9361 +        * the engine before calling fork().
9362 +        */
9363 +       pk11_free_all_locks();
9365 +       return (1);
9367 +err:
9368 +       return (0);
9369 +       }
9371 +/* Standard engine interface function to set the dynamic library path */
9372 +/* ARGSUSED */
9373 +static int pk11_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f)(void))
9374 +       {
9375 +       int initialized = ((pk11_dso == NULL) ? 0 : 1);
9377 +       switch (cmd)
9378 +               {
9379 +       case PK11_CMD_SO_PATH:
9380 +               if (p == NULL)
9381 +                       {
9382 +                       PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
9383 +                       return (0);
9384 +                       }
9386 +               if (initialized)
9387 +                       {
9388 +                       PK11err(PK11_F_CTRL, PK11_R_ALREADY_LOADED);
9389 +                       return (0);
9390 +                       }
9392 +               return (set_PK11_LIBNAME((const char *)p));
9393 +       case PK11_CMD_PIN:
9394 +               if (pk11_pin) {
9395 +                       memset(pk11_pin, 0, strlen(pk11_pin));
9396 +                       OPENSSL_free((void*)pk11_pin);
9397 +               }
9398 +               pk11_pin = NULL;
9400 +               if (p == NULL)
9401 +                       {
9402 +                       PK11err(PK11_F_CTRL, ERR_R_PASSED_NULL_PARAMETER);
9403 +                       return (0);
9404 +                       }
9406 +               pk11_pin = BUF_strdup(p);
9407 +               if (pk11_pin == NULL)
9408 +                       {
9409 +                       PK11err(PK11_F_GET_SESSION, PK11_R_MALLOC_FAILURE);
9410 +                       return (0);
9411 +                       }
9412 +               return (1);
9413 +       case PK11_CMD_SLOT:
9414 +               SLOTID = (CK_SLOT_ID)i;
9415 +#ifdef DEBUG_SLOT_SELECTION
9416 +               fprintf(stderr, "%s: slot set\n", PK11_DBG);
9417 +#endif
9418 +               return (1);
9419 +       default:
9420 +               break;
9421 +               }
9423 +       PK11err(PK11_F_CTRL, PK11_R_CTRL_COMMAND_NOT_IMPLEMENTED);
9425 +       return (0);
9426 +       }
9429 +/* Required function by the engine random interface. It does nothing here */
9430 +static void pk11_rand_cleanup(void)
9431 +       {
9432 +       return;
9433 +       }
9435 +/* ARGSUSED */
9436 +static void pk11_rand_add(const void *buf, int num, double add)
9437 +       {
9438 +       PK11_SESSION *sp;
9440 +       if ((sp = pk11_get_session(OP_RAND)) == NULL)
9441 +               return;
9443 +       /*
9444 +        * Ignore any errors (e.g. CKR_RANDOM_SEED_NOT_SUPPORTED) since
9445 +        * the calling functions do not care anyway
9446 +        */
9447 +       pFuncList->C_SeedRandom(sp->session, (unsigned char *) buf, num);
9448 +       pk11_return_session(sp, OP_RAND);
9450 +       return;
9451 +       }
9453 +static void pk11_rand_seed(const void *buf, int num)
9454 +       {
9455 +       pk11_rand_add(buf, num, 0);
9456 +       }
9458 +static int pk11_rand_bytes(unsigned char *buf, int num)
9459 +       {
9460 +       CK_RV rv;
9461 +       PK11_SESSION *sp;
9463 +       if ((sp = pk11_get_session(OP_RAND)) == NULL)
9464 +               return (0);
9466 +       rv = pFuncList->C_GenerateRandom(sp->session, buf, num);
9467 +       if (rv != CKR_OK)
9468 +               {
9469 +               PK11err_add_data(PK11_F_RAND_BYTES, PK11_R_GENERATERANDOM, rv);
9470 +               pk11_return_session(sp, OP_RAND);
9471 +               return (0);
9472 +               }
9474 +       pk11_return_session(sp, OP_RAND);
9475 +       return (1);
9476 +       }
9478 +/* Required function by the engine random interface. It does nothing here */
9479 +static int pk11_rand_status(void)
9480 +       {
9481 +       return (1);
9482 +       }
9484 +/* Free all BIGNUM structures from PK11_SESSION. */
9485 +static void pk11_free_nums(PK11_SESSION *sp, PK11_OPTYPE optype)
9486 +       {
9487 +       switch (optype)
9488 +               {
9489 +               case OP_RSA:
9490 +                       if (sp->opdata_rsa_n_num != NULL)
9491 +                               {
9492 +                               BN_free(sp->opdata_rsa_n_num);
9493 +                               sp->opdata_rsa_n_num = NULL;
9494 +                               }
9495 +                       if (sp->opdata_rsa_e_num != NULL)
9496 +                               {
9497 +                               BN_free(sp->opdata_rsa_e_num);
9498 +                               sp->opdata_rsa_e_num = NULL;
9499 +                               }
9500 +                       if (sp->opdata_rsa_d_num != NULL)
9501 +                               {
9502 +                               BN_free(sp->opdata_rsa_d_num);
9503 +                               sp->opdata_rsa_d_num = NULL;
9504 +                               }
9505 +                       break;
9506 +               default:
9507 +                       break;
9508 +               }
9509 +       }
9512 + * Get new PK11_SESSION structure ready for use. Every process must have
9513 + * its own freelist of PK11_SESSION structures so handle fork() here
9514 + * by destroying the old and creating new freelist.
9515 + * The returned PK11_SESSION structure is disconnected from the freelist.
9516 + */
9517 +PK11_SESSION *
9518 +pk11_get_session(PK11_OPTYPE optype)
9519 +       {
9520 +       PK11_SESSION *sp = NULL, *sp1, *freelist;
9521 +#ifndef NOPTHREADS
9522 +       pthread_mutex_t *freelist_lock = NULL;
9523 +#endif
9524 +       CK_RV rv;
9526 +       switch (optype)
9527 +               {
9528 +               case OP_RSA:
9529 +               case OP_DSA:
9530 +               case OP_DH:
9531 +               case OP_RAND:
9532 +               case OP_DIGEST:
9533 +               case OP_CIPHER:
9534 +#ifndef NOPTHREADS
9535 +                       freelist_lock = session_cache[optype].lock;
9536 +#endif
9537 +                       break;
9538 +               default:
9539 +                       PK11err(PK11_F_GET_SESSION,
9540 +                               PK11_R_INVALID_OPERATION_TYPE);
9541 +                       return (NULL);
9542 +               }
9543 +#ifndef NOPTHREADS
9544 +       (void) pthread_mutex_lock(freelist_lock);
9545 +#else
9546 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
9547 +#endif
9548 +       freelist = session_cache[optype].head;
9549 +       sp = freelist;
9551 +       /*
9552 +        * If the free list is empty, allocate new unitialized (filled
9553 +        * with zeroes) PK11_SESSION structure otherwise return first
9554 +        * structure from the freelist.
9555 +        */
9556 +       if (sp == NULL)
9557 +               {
9558 +               if ((sp = OPENSSL_malloc(sizeof (PK11_SESSION))) == NULL)
9559 +                       {
9560 +                       PK11err(PK11_F_GET_SESSION,
9561 +                               PK11_R_MALLOC_FAILURE);
9562 +                       goto err;
9563 +                       }
9564 +               (void) memset(sp, 0, sizeof (PK11_SESSION));
9565 +               }
9566 +       else
9567 +               {
9568 +               freelist = sp->next;
9569 +               }
9571 +       if (sp->pid != 0 && sp->pid != getpid())
9572 +               {
9573 +               /*
9574 +                * We are a new process and thus need to free any inherited
9575 +                * PK11_SESSION objects.
9576 +                */
9577 +               while ((sp1 = freelist) != NULL)
9578 +                       {
9579 +                       freelist = sp1->next;
9580 +                       /*
9581 +                        * NOTE: we do not want to call pk11_free_all_sessions()
9582 +                        * here because it would close underlying PKCS#11
9583 +                        * sessions and destroy all objects.
9584 +                        */
9585 +                       pk11_free_nums(sp1, optype);
9586 +                       OPENSSL_free(sp1);
9587 +                       }
9589 +               /* we have to free the active list as well. */
9590 +               pk11_free_active_list(optype);
9592 +               /* Initialize the process */
9593 +               rv = pFuncList->C_Initialize(NULL_PTR);
9594 +               if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED))
9595 +                       {
9596 +                       PK11err_add_data(PK11_F_GET_SESSION, PK11_R_INITIALIZE,
9597 +                           rv);
9598 +                       OPENSSL_free(sp);
9599 +                       sp = NULL;
9600 +                       goto err;
9601 +                       }
9603 +               /*
9604 +                * Choose slot here since the slot table is different on this
9605 +                * process. If we are here then we must have found at least one
9606 +                * usable slot before so we don't need to check any_slot_found.
9607 +                * See pk11_library_init()'s usage of this function for more
9608 +                * information.
9609 +                */
9610 +               if (pk11_choose_slots(NULL) == 0)
9611 +                       goto err;
9613 +               /* Open the global_session for the new process */
9614 +               rv = pFuncList->C_OpenSession(SLOTID, CKF_SERIAL_SESSION,
9615 +                       NULL_PTR, NULL_PTR, &global_session);
9616 +               if (rv != CKR_OK)
9617 +                       {
9618 +                       PK11err_add_data(PK11_F_GET_SESSION, PK11_R_OPENSESSION,
9619 +                           rv);
9620 +                       OPENSSL_free(sp);
9621 +                       sp = NULL;
9622 +                       goto err;
9623 +                       }
9625 +               /* It is an inherited session and needs re-initialization. */
9626 +               if (pk11_setup_session(sp, optype) == 0)
9627 +                       {
9628 +                       OPENSSL_free(sp);
9629 +                       sp = NULL;
9630 +                       }
9631 +               }
9632 +       if (sp->pid == 0)
9633 +               {
9634 +               /* It is a new session and needs initialization. */
9635 +               if (pk11_setup_session(sp, optype) == 0)
9636 +                       {
9637 +                       OPENSSL_free(sp);
9638 +                       sp = NULL;
9639 +                       }
9640 +               }
9642 +       /* set new head for the list of PK11_SESSION objects */
9643 +       session_cache[optype].head = freelist;
9645 +err:
9646 +       if (sp != NULL)
9647 +               sp->next = NULL;
9649 +#ifndef NOPTHREADS
9650 +       (void) pthread_mutex_unlock(freelist_lock);
9651 +#else
9652 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
9653 +#endif
9655 +       return (sp);
9656 +       }
9659 +void
9660 +pk11_return_session(PK11_SESSION *sp, PK11_OPTYPE optype)
9661 +       {
9662 +#ifndef NOPTHREADS
9663 +       pthread_mutex_t *freelist_lock;
9664 +#endif
9665 +       PK11_SESSION *freelist;
9667 +       if (sp == NULL || sp->pid != getpid())
9668 +               return;
9670 +       switch (optype)
9671 +               {
9672 +               case OP_RSA:
9673 +               case OP_DSA:
9674 +               case OP_DH:
9675 +               case OP_RAND:
9676 +               case OP_DIGEST:
9677 +               case OP_CIPHER:
9678 +#ifndef NOPTHREADS
9679 +                       freelist_lock = session_cache[optype].lock;
9680 +#endif
9681 +                       break;
9682 +               default:
9683 +                       PK11err(PK11_F_RETURN_SESSION,
9684 +                               PK11_R_INVALID_OPERATION_TYPE);
9685 +                       return;
9686 +               }
9688 +#ifndef NOPTHREADS
9689 +       (void) pthread_mutex_lock(freelist_lock);
9690 +#else
9691 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
9692 +#endif
9693 +       freelist = session_cache[optype].head;
9694 +       sp->next = freelist;
9695 +       session_cache[optype].head = sp;
9696 +#ifndef NOPTHREADS
9697 +       (void) pthread_mutex_unlock(freelist_lock);
9698 +#else
9699 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
9700 +#endif
9701 +       }
9704 +/* Destroy all objects. This function is called when the engine is finished */
9705 +static int pk11_free_all_sessions()
9706 +       {
9707 +       int ret = 1;
9708 +       int type;
9710 +       (void) pk11_destroy_rsa_key_objects(NULL);
9712 +       /*
9713 +        * We try to release as much as we can but any error means that we will
9714 +        * return 0 on exit.
9715 +        */
9716 +       for (type = 0; type < OP_MAX; type++)
9717 +               {
9718 +               if (pk11_free_session_list(type) == 0)
9719 +                       ret = 0;
9720 +               }
9722 +       return (ret);
9723 +       }
9726 + * Destroy session structures from the linked list specified. Free as many
9727 + * sessions as possible but any failure in C_CloseSession() means that we
9728 + * return an error on return.
9729 + */
9730 +static int pk11_free_session_list(PK11_OPTYPE optype)
9731 +       {
9732 +       CK_RV rv;
9733 +       PK11_SESSION *sp = NULL;
9734 +       PK11_SESSION *freelist = NULL;
9735 +       pid_t mypid = getpid();
9736 +#ifndef NOPTHREADS
9737 +       pthread_mutex_t *freelist_lock;
9738 +#endif
9739 +       int ret = 1;
9741 +       switch (optype)
9742 +               {
9743 +               case OP_RSA:
9744 +               case OP_DSA:
9745 +               case OP_DH:
9746 +               case OP_RAND:
9747 +               case OP_DIGEST:
9748 +               case OP_CIPHER:
9749 +#ifndef NOPTHREADS
9750 +                       freelist_lock = session_cache[optype].lock;
9751 +#endif
9752 +                       break;
9753 +               default:
9754 +                       PK11err(PK11_F_FREE_ALL_SESSIONS,
9755 +                               PK11_R_INVALID_OPERATION_TYPE);
9756 +                       return (0);
9757 +               }
9759 +#ifndef NOPTHREADS
9760 +       (void) pthread_mutex_lock(freelist_lock);
9761 +#else
9762 +       CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
9763 +#endif
9764 +       freelist = session_cache[optype].head;
9765 +       while ((sp = freelist) != NULL)
9766 +               {
9767 +               if (sp->session != CK_INVALID_HANDLE && sp->pid == mypid)
9768 +                       {
9769 +                       rv = pFuncList->C_CloseSession(sp->session);
9770 +                       if (rv != CKR_OK)
9771 +                               {
9772 +                               PK11err_add_data(PK11_F_FREE_ALL_SESSIONS,
9773 +                                       PK11_R_CLOSESESSION, rv);
9774 +                               ret = 0;
9775 +                               }
9776 +                       }
9777 +               freelist = sp->next;
9778 +               pk11_free_nums(sp, optype);
9779 +               OPENSSL_free(sp);
9780 +               }
9782 +#ifndef NOPTHREADS
9783 +       (void) pthread_mutex_unlock(freelist_lock);
9784 +#else
9785 +       CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
9786 +#endif
9787 +       return (ret);
9788 +       }
9791 +static int pk11_setup_session(PK11_SESSION *sp, PK11_OPTYPE optype)
9792 +       {
9793 +       CK_RV rv;
9794 +       CK_SLOT_ID myslot;
9796 +       switch (optype)
9797 +               {
9798 +               case OP_RSA:
9799 +                       myslot = pubkey_SLOTID;
9800 +                       break;
9801 +               case OP_RAND:
9802 +                       myslot = rand_SLOTID;
9803 +                       break;
9804 +               default:
9805 +                       PK11err(PK11_F_SETUP_SESSION,
9806 +                           PK11_R_INVALID_OPERATION_TYPE);
9807 +                       return (0);
9808 +               }
9810 +       sp->session = CK_INVALID_HANDLE;
9811 +#ifdef DEBUG_SLOT_SELECTION
9812 +       fprintf(stderr, "%s: myslot=%d optype=%d\n", PK11_DBG, myslot, optype);
9813 +#endif /* DEBUG_SLOT_SELECTION */
9814 +       rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
9815 +               NULL_PTR, NULL_PTR, &sp->session);
9816 +       if (rv == CKR_CRYPTOKI_NOT_INITIALIZED)
9817 +               {
9818 +               /*
9819 +                * We are probably a child process so force the
9820 +                * reinitialize of the session
9821 +                */
9822 +               pk11_library_initialized = FALSE;
9823 +               if (!pk11_library_init(NULL))
9824 +                       return (0);
9825 +               rv = pFuncList->C_OpenSession(myslot, CKF_SERIAL_SESSION,
9826 +                       NULL_PTR, NULL_PTR, &sp->session);
9827 +               }
9828 +       if (rv != CKR_OK)
9829 +               {
9830 +               PK11err_add_data(PK11_F_SETUP_SESSION, PK11_R_OPENSESSION, rv);
9831 +               return (0);
9832 +               }
9834 +       sp->pid = getpid();
9836 +       if (optype == OP_RSA)
9837 +               {
9838 +               sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
9839 +               sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
9840 +               sp->opdata_rsa_pub = NULL;
9841 +               sp->opdata_rsa_n_num = NULL;
9842 +               sp->opdata_rsa_e_num = NULL;
9843 +               sp->opdata_rsa_priv = NULL;
9844 +               sp->opdata_rsa_d_num = NULL;
9845 +               }
9847 +       return (1);
9848 +       }
9850 +/* Destroy RSA public key from single session. */
9851 +int
9852 +pk11_destroy_rsa_object_pub(PK11_SESSION *sp, CK_BBOOL uselock)
9853 +       {
9854 +       int ret = 0;
9856 +       if (sp->opdata_rsa_pub_key != CK_INVALID_HANDLE)
9857 +               {
9858 +               TRY_OBJ_DESTROY(sp->session, sp->opdata_rsa_pub_key,
9859 +                   ret, uselock, OP_RSA);
9860 +               sp->opdata_rsa_pub_key = CK_INVALID_HANDLE;
9861 +               sp->opdata_rsa_pub = NULL;
9862 +               if (sp->opdata_rsa_n_num != NULL)
9863 +                       {
9864 +                       BN_free(sp->opdata_rsa_n_num);
9865 +                       sp->opdata_rsa_n_num = NULL;
9866 +                       }
9867 +               if (sp->opdata_rsa_e_num != NULL)
9868 +                       {
9869 +                       BN_free(sp->opdata_rsa_e_num);
9870 +                       sp->opdata_rsa_e_num = NULL;
9871 +                       }
9872 +               }
9874 +       return (ret);
9875 +       }
9877 +/* Destroy RSA private key from single session. */
9878 +int
9879 +pk11_destroy_rsa_object_priv(PK11_SESSION *sp, CK_BBOOL uselock)
9880 +       {
9881 +       int ret = 0;
9883 +       if (sp->opdata_rsa_priv_key != CK_INVALID_HANDLE)
9884 +               {
9885 +               TRY_OBJ_DELETE(sp->session,
9886 +                              sp->opdata_rsa_priv_key,
9887 +                              ret, uselock, OP_RSA);
9888 +               sp->opdata_rsa_priv_key = CK_INVALID_HANDLE;
9889 +               sp->opdata_rsa_priv = NULL;
9890 +               if (sp->opdata_rsa_d_num != NULL)
9891 +                       {
9892 +                       BN_free(sp->opdata_rsa_d_num);
9893 +                       sp->opdata_rsa_d_num = NULL;
9894 +                       }
9895 +               }
9897 +       return (ret);
9898 +       }
9901 + * Destroy RSA key object wrapper. If session is NULL, try to destroy all
9902 + * objects in the free list.
9903 + */
9904 +int
9905 +pk11_destroy_rsa_key_objects(PK11_SESSION *session)
9906 +       {
9907 +       int ret = 1;
9908 +       PK11_SESSION *sp = NULL;
9909 +       PK11_SESSION *local_free_session;
9910 +       CK_BBOOL uselock = TRUE;
9912 +       if (session != NULL)
9913 +               local_free_session = session;
9914 +       else
9915 +               {
9916 +#ifndef NOPTHREADS
9917 +               (void) pthread_mutex_lock(session_cache[OP_RSA].lock);
9918 +#else
9919 +               CRYPTO_w_lock(CRYPTO_LOCK_PK11_ENGINE);
9920 +#endif
9921 +               local_free_session = session_cache[OP_RSA].head;
9922 +               uselock = FALSE;
9923 +               }
9925 +       /*
9926 +        * go through the list of sessions and delete key objects
9927 +        */
9928 +       while ((sp = local_free_session) != NULL)
9929 +               {
9930 +               local_free_session = sp->next;
9932 +               /*
9933 +                * Do not terminate list traversal if one of the
9934 +                * destroy operations fails.
9935 +                */
9936 +               if (pk11_destroy_rsa_object_pub(sp, uselock) == 0)
9937 +                       {
9938 +                       ret = 0;
9939 +                       continue;
9940 +                       }
9941 +               if (pk11_destroy_rsa_object_priv(sp, uselock) == 0)
9942 +                       {
9943 +                       ret = 0;
9944 +                       continue;
9945 +                       }
9946 +               }
9948 +#ifndef NOPTHREADS
9949 +       if (session == NULL)
9950 +               (void) pthread_mutex_unlock(session_cache[OP_RSA].lock);
9951 +#else
9952 +       if (session == NULL)
9953 +               CRYPTO_w_unlock(CRYPTO_LOCK_PK11_ENGINE);
9954 +#endif
9956 +       return (ret);
9957 +       }
9959 +static int pk11_destroy_object(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE oh)
9960 +       {
9961 +       CK_RV rv;
9962 +       rv = pFuncList->C_DestroyObject(session, oh);
9963 +       if (rv != CKR_OK)
9964 +               {
9965 +               PK11err_add_data(PK11_F_DESTROY_OBJECT, PK11_R_DESTROYOBJECT,
9966 +                   rv);
9967 +               return (0);
9968 +               }
9970 +       return (1);
9971 +       }
9975 + * Public key mechanisms optionally supported
9976 + *
9977 + * CKM_RSA_X_509
9978 + * CKM_RSA_PKCS
9979 + *
9980 + * The first slot that supports at least one of those mechanisms is chosen as a
9981 + * public key slot.
9982 + *
9983 + * The output of this function is a set of global variables indicating which
9984 + * mechanisms from RSA, DSA, DH and RAND are present, and also two arrays of
9985 + * mechanisms, one for symmetric ciphers and one for digests. Also, 3 global
9986 + * variables carry information about which slot was chosen for (a) public key
9987 + * mechanisms, (b) random operations, and (c) symmetric ciphers and digests.
9988 + */
9989 +static int
9990 +pk11_choose_slots(int *any_slot_found)
9991 +       {
9992 +       CK_SLOT_ID_PTR pSlotList = NULL_PTR;
9993 +       CK_ULONG ulSlotCount = 0;
9994 +       CK_MECHANISM_INFO mech_info;
9995 +       CK_TOKEN_INFO token_info;
9996 +       unsigned int i;
9997 +       CK_RV rv;
9998 +       CK_SLOT_ID best_slot_sofar = 0;
9999 +       CK_BBOOL found_candidate_slot = CK_FALSE;
10000 +       CK_SLOT_ID current_slot = 0;
10002 +       /* let's initialize the output parameter */
10003 +       if (any_slot_found != NULL)
10004 +               *any_slot_found = 0;
10006 +       /* Get slot list for memory allocation */
10007 +       rv = pFuncList->C_GetSlotList(0, NULL_PTR, &ulSlotCount);
10009 +       if (rv != CKR_OK)
10010 +               {
10011 +               PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
10012 +               return (0);
10013 +               }
10015 +       /* it's not an error if we didn't find any providers */
10016 +       if (ulSlotCount == 0)
10017 +               {
10018 +#ifdef DEBUG_SLOT_SELECTION
10019 +               fprintf(stderr, "%s: no crypto providers found\n", PK11_DBG);
10020 +#endif /* DEBUG_SLOT_SELECTION */
10021 +               return (1);
10022 +               }
10024 +       pSlotList = OPENSSL_malloc(ulSlotCount * sizeof (CK_SLOT_ID));
10026 +       if (pSlotList == NULL)
10027 +               {
10028 +               PK11err(PK11_F_CHOOSE_SLOT, PK11_R_MALLOC_FAILURE);
10029 +               return (0);
10030 +               }
10032 +       /* Get the slot list for processing */
10033 +       rv = pFuncList->C_GetSlotList(0, pSlotList, &ulSlotCount);
10034 +       if (rv != CKR_OK)
10035 +               {
10036 +               PK11err_add_data(PK11_F_CHOOSE_SLOT, PK11_R_GETSLOTLIST, rv);
10037 +               OPENSSL_free(pSlotList);
10038 +               return (0);
10039 +               }
10041 +#ifdef DEBUG_SLOT_SELECTION
10042 +       fprintf(stderr, "%s: provider: %s\n", PK11_DBG, def_PK11_LIBNAME);
10043 +       fprintf(stderr, "%s: number of slots: %d\n", PK11_DBG, ulSlotCount);
10045 +       fprintf(stderr, "%s: == checking rand slots ==\n", PK11_DBG);
10046 +#endif /* DEBUG_SLOT_SELECTION */
10047 +       for (i = 0; i < ulSlotCount; i++)
10048 +               {
10049 +               current_slot = pSlotList[i];
10051 +#ifdef DEBUG_SLOT_SELECTION
10052 +       fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
10053 +#endif /* DEBUG_SLOT_SELECTION */
10054 +               /* Check if slot has random support. */
10055 +               rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
10056 +               if (rv != CKR_OK)
10057 +                       continue;
10059 +#ifdef DEBUG_SLOT_SELECTION
10060 +       fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
10061 +#endif /* DEBUG_SLOT_SELECTION */
10063 +               if (token_info.flags & CKF_RNG)
10064 +                       {
10065 +#ifdef DEBUG_SLOT_SELECTION
10066 +       fprintf(stderr, "%s: this token has CKF_RNG flag\n", PK11_DBG);
10067 +#endif /* DEBUG_SLOT_SELECTION */
10068 +                       pk11_have_random = CK_TRUE;
10069 +                       rand_SLOTID = current_slot;
10070 +                       break;
10071 +                       }
10072 +               }
10074 +#ifdef DEBUG_SLOT_SELECTION
10075 +       fprintf(stderr, "%s: == checking pubkey slots ==\n", PK11_DBG);
10076 +#endif /* DEBUG_SLOT_SELECTION */
10078 +       pubkey_SLOTID = pSlotList[0];
10079 +       for (i = 0; i < ulSlotCount; i++)
10080 +               {
10081 +               CK_BBOOL slot_has_rsa = CK_FALSE;
10082 +               current_slot = pSlotList[i];
10084 +#ifdef DEBUG_SLOT_SELECTION
10085 +       fprintf(stderr, "%s: checking slot: %d\n", PK11_DBG, i);
10086 +#endif /* DEBUG_SLOT_SELECTION */
10087 +               rv = pFuncList->C_GetTokenInfo(current_slot, &token_info);
10088 +               if (rv != CKR_OK)
10089 +                       continue;
10091 +#ifdef DEBUG_SLOT_SELECTION
10092 +       fprintf(stderr, "%s: token label: %.32s\n", PK11_DBG, token_info.label);
10093 +#endif /* DEBUG_SLOT_SELECTION */
10095 +               /*
10096 +                * Check if this slot is capable of signing with CKM_RSA_PKCS.
10097 +                */
10098 +               rv = pFuncList->C_GetMechanismInfo(current_slot, CKM_RSA_PKCS,
10099 +                       &mech_info);
10101 +               if (rv == CKR_OK && ((mech_info.flags & CKF_SIGN)))
10102 +                       {
10103 +                       slot_has_rsa = CK_TRUE;
10104 +                       }
10106 +               if (!found_candidate_slot && slot_has_rsa)
10107 +                       {
10108 +#ifdef DEBUG_SLOT_SELECTION
10109 +                       fprintf(stderr,
10110 +                           "%s: potential slot: %d\n", PK11_DBG, current_slot);
10111 +#endif /* DEBUG_SLOT_SELECTION */
10112 +                       best_slot_sofar = current_slot;
10113 +                       pk11_have_rsa = slot_has_rsa;
10114 +                       found_candidate_slot = CK_TRUE;
10115 +#ifdef DEBUG_SLOT_SELECTION
10116 +                       fprintf(stderr,
10117 +                           "%s: setting found_candidate_slot to CK_TRUE\n",
10118 +                           PK11_DBG);
10119 +                       fprintf(stderr,
10120 +                           "%s: best so far slot: %d\n", PK11_DBG,
10121 +                           best_slot_sofar);
10122 +                       }
10123 +               else
10124 +                       {
10125 +                       fprintf(stderr,
10126 +                           "%s: no rsa\n", PK11_DBG);
10127 +                       }
10128 +#else
10129 +                       } /* if */
10130 +#endif /* DEBUG_SLOT_SELECTION */
10131 +               } /* for */
10133 +       if (found_candidate_slot)
10134 +               {
10135 +               pubkey_SLOTID = best_slot_sofar;
10136 +               }
10138 +       /*SLOTID = pSlotList[0];*/
10140 +#ifdef DEBUG_SLOT_SELECTION
10141 +       fprintf(stderr,
10142 +           "%s: chosen pubkey slot: %d\n", PK11_DBG, pubkey_SLOTID);
10143 +       fprintf(stderr,
10144 +           "%s: chosen rand slot: %d\n", PK11_DBG, rand_SLOTID);
10145 +       fprintf(stderr,
10146 +           "%s: pk11_have_rsa %d\n", PK11_DBG, pk11_have_rsa);
10147 +       fprintf(stderr,
10148 +           "%s: pk11_have_random %d\n", PK11_DBG, pk11_have_random);
10149 +#endif /* DEBUG_SLOT_SELECTION */
10151 +       if (pSlotList != NULL)
10152 +               OPENSSL_free(pSlotList);
10154 +       if (any_slot_found != NULL)
10155 +               *any_slot_found = 1;
10156 +       return (1);
10157 +       }
10159 +#endif /* OPENSSL_NO_HW_PK11SO */
10160 +#endif /* OPENSSL_NO_HW_PK11 */
10161 +#endif /* OPENSSL_NO_HW */
10162 Index: openssl/crypto/engine/hw_pk11so.h
10163 diff -u /dev/null openssl/crypto/engine/hw_pk11so.h:1.2
10164 --- /dev/null   Mon Oct  5 13:17:24 2009
10165 +++ openssl/crypto/engine/hw_pk11so.h   Mon Oct  5 13:17:03 2009
10166 @@ -0,0 +1,28 @@
10167 +/* Redefine all pk11/PK11 external symbols to pk11so/PK11SO */
10169 +#define find_lock                      pk11so_find_lock
10170 +#define active_list                    pk11so_active_list
10171 +#define ERR_pk11_error                 ERR_pk11so_error
10172 +#define PK11err_add_data               PK11SOerr_add_data
10173 +#define pk11_get_session               pk11so_get_session
10174 +#define pk11_return_session            pk11so_return_session
10175 +#define pk11_active_add                        pk11so_active_add
10176 +#define pk11_active_delete             pk11so_active_delete
10177 +#define pk11_active_remove             pk11so_active_remove
10178 +#define pk11_free_active_list          pk11so_free_active_list
10179 +#define pk11_destroy_rsa_key_objects   pk11so_destroy_rsa_key_objects
10180 +#define pk11_destroy_rsa_object_pub    pk11so_destroy_rsa_object_pub
10181 +#define pk11_destroy_rsa_object_priv   pk11so_destroy_rsa_object_priv
10182 +#define pk11_load_privkey              pk11so_load_privkey
10183 +#define pk11_load_pubkey               pk11so_load_pubkey
10184 +#define PK11_RSA                       PK11SO_RSA
10185 +#define pk11_destroy_dsa_key_objects   pk11so_destroy_dsa_key_objects
10186 +#define pk11_destroy_dsa_object_pub    pk11so_destroy_dsa_object_pub
10187 +#define pk11_destroy_dsa_object_priv   pk11so_destroy_dsa_object_priv
10188 +#define PK11_DSA                       PK11SO_DSA
10189 +#define pk11_destroy_dh_key_objects    pk11so_destroy_dh_key_objects
10190 +#define pk11_destroy_dh_object         pk11so_destroy_dh_object
10191 +#define PK11_DH                                PK11SO_DH
10192 +#define pFuncList                      pk11so_pFuncList
10193 +#define pk11_pin                       pk11so_pin
10194 +#define ENGINE_load_pk11               ENGINE_load_pk11so
10195 Index: openssl/crypto/engine/hw_pk11so_pub.c
10196 diff -u /dev/null openssl/crypto/engine/hw_pk11so_pub.c:1.2
10197 --- /dev/null   Mon Oct  5 13:17:24 2009
10198 +++ openssl/crypto/engine/hw_pk11so_pub.c       Mon Oct  5 13:17:03 2009
10199 @@ -0,0 +1,899 @@
10201 + * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
10202 + * Use is subject to license terms.
10203 + */
10205 +/* crypto/engine/hw_pk11_pub.c */
10207 + * This product includes software developed by the OpenSSL Project for
10208 + * use in the OpenSSL Toolkit (http://www.openssl.org/).
10209 + *
10210 + * This project also referenced hw_pkcs11-0.9.7b.patch written by
10211 + * Afchine Madjlessi.
10212 + */
10214 + * ====================================================================
10215 + * Copyright (c) 2000-2001 The OpenSSL Project.  All rights reserved.
10216 + *
10217 + * Redistribution and use in source and binary forms, with or without
10218 + * modification, are permitted provided that the following conditions
10219 + * are met:
10220 + *
10221 + * 1. Redistributions of source code must retain the above copyright
10222 + *    notice, this list of conditions and the following disclaimer.
10223 + *
10224 + * 2. Redistributions in binary form must reproduce the above copyright
10225 + *    notice, this list of conditions and the following disclaimer in
10226 + *    the documentation and/or other materials provided with the
10227 + *    distribution.
10228 + *
10229 + * 3. All advertising materials mentioning features or use of this
10230 + *    software must display the following acknowledgment:
10231 + *    "This product includes software developed by the OpenSSL Project
10232 + *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
10233 + *
10234 + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
10235 + *    endorse or promote products derived from this software without
10236 + *    prior written permission. For written permission, please contact
10237 + *    licensing@OpenSSL.org.
10238 + *
10239 + * 5. Products derived from this software may not be called "OpenSSL"
10240 + *    nor may "OpenSSL" appear in their names without prior written
10241 + *    permission of the OpenSSL Project.
10242 + *
10243 + * 6. Redistributions of any form whatsoever must retain the following
10244 + *    acknowledgment:
10245 + *    "This product includes software developed by the OpenSSL Project
10246 + *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
10247 + *
10248 + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
10249 + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
10250 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
10251 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
10252 + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
10253 + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
10254 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
10255 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
10256 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
10257 + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
10258 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
10259 + * OF THE POSSIBILITY OF SUCH DAMAGE.
10260 + * ====================================================================
10261 + *
10262 + * This product includes cryptographic software written by Eric Young
10263 + * (eay@cryptsoft.com).  This product includes software written by Tim
10264 + * Hudson (tjh@cryptsoft.com).
10265 + *
10266 + */
10268 +/* Modified to keep only RNG and RSA Sign */
10270 +#ifdef OPENSSL_NO_RSA
10271 +#error RSA is disabled
10272 +#endif
10274 +#include <stdio.h>
10275 +#include <stdlib.h>
10276 +#include <string.h>
10277 +#include <sys/types.h>
10279 +#include <openssl/e_os2.h>
10280 +#include <openssl/crypto.h>
10281 +#include <cryptlib.h>
10282 +#include <openssl/engine.h>
10283 +#include <openssl/dso.h>
10284 +#include <openssl/err.h>
10285 +#include <openssl/bn.h>
10286 +#include <openssl/pem.h>
10287 +#include <openssl/rsa.h>
10288 +#include <openssl/rand.h>
10289 +#include <openssl/objects.h>
10290 +#include <openssl/x509.h>
10292 +#ifdef OPENSSL_SYS_WIN32
10293 +#define NOPTHREADS
10294 +typedef int pid_t;
10295 +#define HAVE_GETPASSPHRASE
10296 +static char *getpassphrase(const char *prompt);
10297 +#ifndef NULL_PTR
10298 +#define NULL_PTR NULL
10299 +#endif
10300 +#define CK_DEFINE_FUNCTION(returnType, name) \
10301 +       returnType __declspec(dllexport) name
10302 +#define CK_DECLARE_FUNCTION(returnType, name) \
10303 +       returnType __declspec(dllimport) name
10304 +#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
10305 +       returnType __declspec(dllimport) (* name)
10306 +#else
10307 +#include <unistd.h>
10308 +#endif
10310 +#ifndef NOPTHREADS
10311 +#include <pthread.h>
10312 +#endif
10314 +#ifndef OPENSSL_NO_HW
10315 +#ifndef OPENSSL_NO_HW_PK11
10316 +#ifndef OPENSSL_NO_HW_PK11SO
10318 +#ifndef OPENSSL_NO_DSA
10319 +#define OPENSSL_NO_DSA
10320 +#endif
10321 +#ifndef OPENSSL_NO_DH
10322 +#define OPENSSL_NO_DH
10323 +#endif
10325 +#ifdef OPENSSL_SYS_WIN32
10326 +#pragma pack(push, cryptoki, 1)
10327 +#include "cryptoki.h"
10328 +#include "pkcs11.h"
10329 +#pragma pack(pop, cryptoki)
10330 +#else
10331 +#include "cryptoki.h"
10332 +#include "pkcs11.h"
10333 +#endif
10334 +#include "hw_pk11so.h"
10335 +#include "hw_pk11_err.h"
10337 +#if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun)))
10338 +#define getpassphrase(x)       getpass(x)
10339 +#endif
10341 +/* RSA stuff */
10342 +static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
10343 +       unsigned char *sigret, unsigned int *siglen, const RSA *rsa);
10344 +EVP_PKEY *pk11_load_privkey(ENGINE*, const char *pubkey_file,
10345 +       UI_METHOD *ui_method, void *callback_data);
10346 +EVP_PKEY *pk11_load_pubkey(ENGINE*, const char *pubkey_file,
10347 +       UI_METHOD *ui_method, void *callback_data);
10349 +static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA* rsa, RSA** key_ptr,
10350 +       BIGNUM **rsa_d_num, CK_SESSION_HANDLE session);
10352 +static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa);
10353 +static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa);
10355 +static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn);
10357 +/* Read mode string to be used for fopen() */
10358 +#if SOLARIS_OPENSSL
10359 +static char *read_mode_flags = "rF";
10360 +#else
10361 +static char *read_mode_flags = "r";
10362 +#endif
10365 + * increment/create reference for an asymmetric key handle via active list
10366 + * manipulation. If active list operation fails, unlock (if locked), set error
10367 + * variable and jump to the specified label.
10368 + */
10369 +#define        KEY_HANDLE_REFHOLD(key_handle, alg_type, unlock, var, label)    \
10370 +       {                                                               \
10371 +       if (pk11_active_add(key_handle, alg_type) < 0)                  \
10372 +               {                                                       \
10373 +               var = TRUE;                                             \
10374 +               if (unlock)                                             \
10375 +                       UNLOCK_OBJSTORE(alg_type);                      \
10376 +               goto label;                                             \
10377 +               }                                                       \
10378 +       }
10381 + * Find active list entry according to object handle and return pointer to the
10382 + * entry otherwise return NULL.
10383 + *
10384 + * This function presumes it is called with lock protecting the active list
10385 + * held.
10386 + */
10387 +static PK11_active *pk11_active_find(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
10388 +       {
10389 +       PK11_active *entry;
10391 +       for (entry = active_list[type]; entry != NULL; entry = entry->next)
10392 +               if (entry->h == h)
10393 +                       return (entry);
10395 +       return (NULL);
10396 +       }
10399 + * Search for an entry in the active list using PKCS#11 object handle as a
10400 + * search key and return refcnt of the found/created entry or -1 in case of
10401 + * failure.
10402 + *
10403 + * This function presumes it is called with lock protecting the active list
10404 + * held.
10405 + */
10406 +int
10407 +pk11_active_add(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
10408 +       {
10409 +       PK11_active *entry = NULL;
10411 +       if (h == CK_INVALID_HANDLE)
10412 +               {
10413 +               PK11err(PK11_F_ACTIVE_ADD, PK11_R_INVALID_HANDLE);
10414 +               return (-1);
10415 +               }
10417 +       /* search for entry in the active list */
10418 +       if ((entry = pk11_active_find(h, type)) != NULL)
10419 +               entry->refcnt++;
10420 +       else
10421 +               {
10422 +               /* not found, create new entry and add it to the list */
10423 +               entry = OPENSSL_malloc(sizeof (PK11_active));
10424 +               if (entry == NULL)
10425 +                       {
10426 +                       PK11err(PK11_F_ACTIVE_ADD, PK11_R_MALLOC_FAILURE);
10427 +                       return (-1);
10428 +                       }
10429 +               entry->h = h;
10430 +               entry->refcnt = 1;
10431 +               entry->prev = NULL;
10432 +               entry->next = NULL;
10433 +               /* connect the newly created entry to the list */
10434 +               if (active_list[type] == NULL)
10435 +                       active_list[type] = entry;
10436 +               else /* make the entry first in the list */
10437 +                       {
10438 +                       entry->next = active_list[type];
10439 +                       active_list[type]->prev = entry;
10440 +                       active_list[type] = entry;
10441 +                       }
10442 +               }
10444 +       return (entry->refcnt);
10445 +       }
10448 + * Remove active list entry from the list and free it.
10449 + *
10450 + * This function presumes it is called with lock protecting the active list
10451 + * held.
10452 + */
10453 +void
10454 +pk11_active_remove(PK11_active *entry, PK11_OPTYPE type)
10455 +       {
10456 +       PK11_active *prev_entry;
10458 +       /* remove the entry from the list and free it */
10459 +       if ((prev_entry = entry->prev) != NULL)
10460 +               {
10461 +               prev_entry->next = entry->next;
10462 +               if (entry->next != NULL)
10463 +                       entry->next->prev = prev_entry;
10464 +               }
10465 +       else
10466 +               {
10467 +               active_list[type] = entry->next;
10468 +               /* we were the first but not the only one */
10469 +               if (entry->next != NULL)
10470 +                       entry->next->prev = NULL;
10471 +               }
10473 +       /* sanitization */
10474 +       entry->h = CK_INVALID_HANDLE;
10475 +       entry->prev = NULL;
10476 +       entry->next = NULL;
10477 +       OPENSSL_free(entry);
10478 +       }
10480 +/* Free all entries from the active list. */
10481 +void
10482 +pk11_free_active_list(PK11_OPTYPE type)
10483 +       {
10484 +       PK11_active *entry;
10486 +       /* only for asymmetric types since only they have C_Find* locks. */
10487 +       switch (type)
10488 +               {
10489 +               case OP_RSA:
10490 +                       break;
10491 +               default:
10492 +                       return;
10493 +               }
10495 +       /* see find_lock array definition for more info on object locking */
10496 +       LOCK_OBJSTORE(type);
10497 +       while ((entry = active_list[type]) != NULL)
10498 +               pk11_active_remove(entry, type);
10499 +       UNLOCK_OBJSTORE(type);
10500 +       }
10503 + * Search for active list entry associated with given PKCS#11 object handle,
10504 + * decrement its refcnt and if it drops to 0, disconnect the entry and free it.
10505 + *
10506 + * Return 1 if the PKCS#11 object associated with the entry has no references,
10507 + * return 0 if there is at least one reference, -1 on error.
10508 + *
10509 + * This function presumes it is called with lock protecting the active list
10510 + * held.
10511 + */
10512 +int
10513 +pk11_active_delete(CK_OBJECT_HANDLE h, PK11_OPTYPE type)
10514 +       {
10515 +       PK11_active *entry = NULL;
10517 +       if ((entry = pk11_active_find(h, type)) == NULL)
10518 +               {
10519 +               PK11err(PK11_F_ACTIVE_DELETE, PK11_R_INVALID_HANDLE);
10520 +               return (-1);
10521 +               }
10523 +       OPENSSL_assert(entry->refcnt > 0);
10524 +       entry->refcnt--;
10525 +       if (entry->refcnt == 0)
10526 +               {
10527 +               pk11_active_remove(entry, type);
10528 +               return (1);
10529 +               }
10531 +       return (0);
10532 +       }
10534 +/* Our internal RSA_METHOD that we provide pointers to */
10535 +static RSA_METHOD pk11_rsa;
10537 +RSA_METHOD *
10538 +PK11_RSA(void)
10539 +       {
10540 +       const RSA_METHOD *rsa;
10542 +       if (pk11_rsa.name == NULL)
10543 +               {
10544 +               rsa = RSA_PKCS1_SSLeay();
10545 +               memcpy(&pk11_rsa, rsa, sizeof(*rsa));
10546 +               pk11_rsa.name = "PKCS#11 RSA method";
10547 +               pk11_rsa.rsa_sign = pk11_RSA_sign;
10548 +               }
10549 +       return (&pk11_rsa);
10550 +       }
10552 +/* Size of an SSL signature: MD5+SHA1 */
10553 +#define        SSL_SIG_LENGTH          36
10556 + * Standard engine interface function. Majority codes here are from
10557 + * rsa/rsa_sign.c. We replaced the decrypt function call by C_Sign of PKCS#11.
10558 + * See more details in rsa/rsa_sign.c
10559 + */
10560 +static int pk11_RSA_sign(int type, const unsigned char *m, unsigned int m_len,
10561 +       unsigned char *sigret, unsigned int *siglen, const RSA *rsa)
10562 +       {
10563 +       X509_SIG sig;
10564 +       ASN1_TYPE parameter;
10565 +       int i, j = 0;
10566 +       unsigned char *p, *s = NULL;
10567 +       X509_ALGOR algor;
10568 +       ASN1_OCTET_STRING digest;
10569 +       CK_RV rv;
10570 +       CK_MECHANISM mech_rsa = {CKM_RSA_PKCS, NULL, 0};
10571 +       CK_MECHANISM *p_mech = &mech_rsa;
10572 +       CK_OBJECT_HANDLE h_priv_key;
10573 +       PK11_SESSION *sp = NULL;
10574 +       int ret = 0;
10575 +       unsigned long ulsiglen;
10577 +       /* Encode the digest */
10578 +       /* Special case: SSL signature, just check the length */
10579 +       if (type == NID_md5_sha1)
10580 +               {
10581 +               if (m_len != SSL_SIG_LENGTH)
10582 +                       {
10583 +                       PK11err(PK11_F_RSA_SIGN,
10584 +                               PK11_R_INVALID_MESSAGE_LENGTH);
10585 +                       goto err;
10586 +                       }
10587 +               i = SSL_SIG_LENGTH;
10588 +               s = (unsigned char *)m;
10589 +               }
10590 +       else
10591 +               {
10592 +               sig.algor = &algor;
10593 +               sig.algor->algorithm = OBJ_nid2obj(type);
10594 +               if (sig.algor->algorithm == NULL)
10595 +                       {
10596 +                       PK11err(PK11_F_RSA_SIGN,
10597 +                               PK11_R_UNKNOWN_ALGORITHM_TYPE);
10598 +                       goto err;
10599 +                       }
10600 +               if (sig.algor->algorithm->length == 0)
10601 +                       {
10602 +                       PK11err(PK11_F_RSA_SIGN,
10603 +                               PK11_R_UNKNOWN_ASN1_OBJECT_ID);
10604 +                       goto err;
10605 +                       }
10606 +               parameter.type = V_ASN1_NULL;
10607 +               parameter.value.ptr = NULL;
10608 +               sig.algor->parameter = &parameter;
10610 +               sig.digest = &digest;
10611 +               sig.digest->data = (unsigned char *)m;
10612 +               sig.digest->length = m_len;
10614 +               i = i2d_X509_SIG(&sig, NULL);
10615 +               }
10617 +       j = RSA_size(rsa);
10618 +       if ((i - RSA_PKCS1_PADDING) > j)
10619 +               {
10620 +               PK11err(PK11_F_RSA_SIGN, PK11_R_DIGEST_TOO_BIG);
10621 +               goto err;
10622 +               }
10624 +       if (type != NID_md5_sha1)
10625 +               {
10626 +               s = (unsigned char *)OPENSSL_malloc((unsigned int)(j + 1));
10627 +               if (s == NULL)
10628 +                       {
10629 +                       PK11err(PK11_F_RSA_SIGN, PK11_R_MALLOC_FAILURE);
10630 +                       goto err;
10631 +                       }
10632 +               p = s;
10633 +               (void) i2d_X509_SIG(&sig, &p);
10634 +               }
10636 +       if ((sp = pk11_get_session(OP_RSA)) == NULL)
10637 +               goto err;
10639 +       (void) check_new_rsa_key_priv(sp, rsa);
10641 +       h_priv_key = sp->opdata_rsa_priv_key;
10642 +       if (h_priv_key == CK_INVALID_HANDLE)
10643 +               h_priv_key = sp->opdata_rsa_priv_key =
10644 +                       pk11_get_private_rsa_key((RSA *)rsa,
10645 +                           &sp->opdata_rsa_priv,
10646 +                           &sp->opdata_rsa_d_num, sp->session);
10648 +       if (h_priv_key != CK_INVALID_HANDLE)
10649 +               {
10650 +               rv = pFuncList->C_SignInit(sp->session, p_mech, h_priv_key);
10652 +               if (rv != CKR_OK)
10653 +                       {
10654 +                       PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGNINIT, rv);
10655 +                       goto err;
10656 +                       }
10658 +               ulsiglen = j;
10659 +               rv = pFuncList->C_Sign(sp->session, s, i, sigret,
10660 +                       (CK_ULONG_PTR) &ulsiglen);
10661 +               *siglen = ulsiglen;
10663 +               if (rv != CKR_OK)
10664 +                       {
10665 +                       PK11err_add_data(PK11_F_RSA_SIGN, PK11_R_SIGN, rv);
10666 +                       goto err;
10667 +                       }
10668 +               ret = 1;
10669 +               }
10671 +err:
10672 +       if ((type != NID_md5_sha1) && (s != NULL))
10673 +               {
10674 +               (void) memset(s, 0, (unsigned int)(j + 1));
10675 +               OPENSSL_free(s);
10676 +               }
10678 +       pk11_return_session(sp, OP_RSA);
10679 +       return (ret);
10680 +       }
10682 +static int hndidx_rsa = -1;
10684 +/* load RSA private key from a file */
10685 +/* ARGSUSED */
10686 +EVP_PKEY *pk11_load_privkey(ENGINE *e, const char *privkey_file,
10687 +       UI_METHOD *ui_method, void *callback_data)
10688 +       {
10689 +       EVP_PKEY *pkey = NULL;
10690 +       FILE *privkey;
10691 +       RSA *rsa;
10692 +       PK11_SESSION *sp = NULL;
10693 +       /* everything else below needed for key by reference extension */
10694 +       CK_RV rv;
10695 +       CK_ULONG objcnt = 0;
10696 +       CK_BBOOL is_token = TRUE;
10697 +       CK_BYTE attr_data[2][1024];
10698 +       CK_OBJECT_CLASS key_class = CKO_PRIVATE_KEY;
10699 +       CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;    /* key in keystore */
10700 +       extern char *pk11_pin;
10702 +       /* we look for private keys only */
10703 +       CK_ATTRIBUTE search_templ[] =
10704 +               {
10705 +               {CKA_TOKEN, &is_token, sizeof(is_token)},
10706 +               {CKA_CLASS, &key_class, sizeof(key_class)},
10707 +               {CKA_LABEL, NULL, 0}
10708 +               };
10710 +       /* these attributes are needed to initialize OpenSSL RSA structure */
10711 +       CK_ATTRIBUTE get_templ[] =
10712 +               {
10713 +               {CKA_MODULUS, (void *)attr_data[0], 1024},          /* n */
10714 +               {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], 1024},  /* e */
10715 +               };
10717 +       /*
10718 +        * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
10719 +        */
10720 +       if (strstr(privkey_file, "pkcs11:") == privkey_file)
10721 +               {
10722 +               if ((sp = pk11_get_session(OP_RSA)) == NULL)
10723 +                       return (NULL);
10725 +               search_templ[2].pValue = strstr(privkey_file, ":") + 1;
10726 +               search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
10728 +               if (pk11_pin == NULL)
10729 +                       {
10730 +                       pk11_pin = BUF_strdup(getpassphrase("Enter PIN: "));
10732 +                       if (pk11_pin == NULL)
10733 +                               {
10734 +                               PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_MALLOC_FAILURE);
10735 +                               goto err;
10736 +                               }
10737 +                       }
10738 +               if ((rv = pFuncList->C_Login(sp->session, CKU_USER, (CK_UTF8CHAR*)pk11_pin,
10739 +                   strlen(pk11_pin))) != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN)
10740 +                       {
10741 +                       PK11err_add_data(PK11_F_LOAD_PRIVKEY,
10742 +                                        PK11_R_INVALID_PIN, rv);
10743 +                       goto err;
10744 +                       }
10746 +               LOCK_OBJSTORE(OP_RSA);
10747 +               if ((rv = pFuncList->C_FindObjectsInit(sp->session,
10748 +                   search_templ, 3)) != CKR_OK)
10749 +                       {
10750 +                       UNLOCK_OBJSTORE(OP_RSA);
10751 +                       PK11err_add_data(PK11_F_LOAD_PRIVKEY,
10752 +                                        PK11_R_FINDOBJECTSINIT, rv);
10753 +                       goto err;
10754 +                       }
10756 +               rv = pFuncList->C_FindObjects(sp->session, &ks_key, 1, &objcnt);
10757 +               if (rv != CKR_OK)
10758 +                       {
10759 +                       UNLOCK_OBJSTORE(OP_RSA);
10760 +                       PK11err_add_data(PK11_F_LOAD_PRIVKEY,
10761 +                                        PK11_R_FINDOBJECTS, rv);
10762 +                       goto err;
10763 +                       }
10765 +               if (objcnt > 1)
10766 +                       {
10767 +                       UNLOCK_OBJSTORE(OP_RSA);
10768 +                       PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_TOO_MANY_OBJECTS);
10769 +                       goto err;
10770 +                       }
10772 +               if (objcnt != 1)
10773 +                       {
10774 +                       UNLOCK_OBJSTORE(OP_RSA);
10775 +                       PK11err(PK11_F_LOAD_PRIVKEY, PK11_R_OBJECT_NOT_FOUND);
10776 +                       goto err;
10777 +                       }
10779 +               (void) pFuncList->C_FindObjectsFinal(sp->session);
10780 +               UNLOCK_OBJSTORE(OP_RSA);
10782 +               if (hndidx_rsa == -1)
10783 +                       hndidx_rsa = RSA_get_ex_new_index(0,
10784 +                                       "pkcs11 RSA HSM key handle",
10785 +                                       NULL, NULL, NULL);
10787 +               pkey = EVP_PKEY_new();
10788 +               if (pkey == NULL)
10789 +                       goto err;
10791 +               rsa = RSA_new_method(e);
10792 +               if (rsa == NULL) {
10793 +                       EVP_PKEY_free(pkey);
10794 +                       pkey = NULL;
10795 +                       goto err;
10796 +               }
10797 +               EVP_PKEY_assign_RSA(pkey, rsa);
10799 +               if ((rv = pFuncList->C_GetAttributeValue(sp->session, ks_key,
10800 +                   get_templ, 2)) != CKR_OK)
10801 +                       {
10802 +                       PK11err_add_data(PK11_F_LOAD_PRIVKEY,
10803 +                                        PK11_R_GETATTRIBUTVALUE, rv);
10804 +                       EVP_PKEY_free(pkey);
10805 +                       pkey = NULL;
10806 +                       goto err;
10807 +                       }
10809 +               /* Note: these flags are critical! */
10810 +               rsa->flags = RSA_FLAG_SIGN_VER | RSA_FLAG_EXT_PKEY;
10811 +               RSA_set_ex_data(rsa, hndidx_rsa, (void *) ks_key);
10812 +               (void) check_new_rsa_key_priv(sp, rsa);
10813 +               sp->opdata_rsa_priv = rsa;
10814 +               sp->opdata_rsa_priv_key = ks_key;
10816 +               attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
10817 +               attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
10818 +               }
10819 +       else if ((privkey = fopen(privkey_file, read_mode_flags)) != NULL)
10820 +               {
10821 +               pkey = PEM_read_PrivateKey(privkey, NULL, NULL, NULL);
10822 +               (void) fclose(privkey);
10823 +               }
10825 +err:
10826 +       if (sp != NULL)
10827 +               pk11_return_session(sp, OP_RSA);
10828 +       return (pkey);
10829 +       }
10831 +/* load RSA public key from a file */
10832 +/* ARGSUSED */
10833 +EVP_PKEY *pk11_load_pubkey(ENGINE *e, const char *pubkey_file,
10834 +       UI_METHOD *ui_method, void *callback_data)
10835 +       {
10836 +       EVP_PKEY *pkey = NULL;
10837 +       FILE *pubkey;
10838 +       RSA *rsa;
10839 +       PK11_SESSION *sp = NULL;
10840 +       /* everything else below needed for key by reference extension */
10841 +       CK_RV rv;
10842 +       CK_ULONG objcnt = 0;
10843 +       CK_BBOOL is_token = TRUE;
10844 +       CK_BYTE attr_data[2][1024];
10845 +       CK_OBJECT_CLASS key_class = CKO_PUBLIC_KEY;
10846 +       CK_OBJECT_HANDLE ks_key = CK_INVALID_HANDLE;    /* key in keystore */
10847 +       extern char *pk11_pin;
10849 +       /* we look for public keys only */
10850 +       CK_ATTRIBUTE search_templ[] =
10851 +               {
10852 +               {CKA_TOKEN, &is_token, sizeof(is_token)},
10853 +               {CKA_CLASS, &key_class, sizeof(key_class)},
10854 +               {CKA_LABEL, NULL, 0}
10855 +               };
10857 +       /* these attributes are needed to initialize OpenSSL RSA structure */
10858 +       CK_ATTRIBUTE get_templ[] =
10859 +               {
10860 +               {CKA_MODULUS, (void *)attr_data[0], 1024},          /* n */
10861 +               {CKA_PUBLIC_EXPONENT, (void *)attr_data[1], 1024},  /* e */
10862 +               };
10864 +       /*
10865 +        * Use simple scheme "pkcs11:<KEY_LABEL>" for now.
10866 +        */
10867 +       if (strstr(pubkey_file, "pkcs11:") == pubkey_file)
10868 +               {
10869 +               if ((sp = pk11_get_session(OP_RSA)) == NULL)
10870 +                       return (NULL);
10872 +               search_templ[2].pValue = strstr(pubkey_file, ":") + 1;
10873 +               search_templ[2].ulValueLen = strlen(search_templ[2].pValue);
10875 +#define ALLWAYS_LOGIN
10876 +#ifdef ALLWAYS_LOGIN
10877 +               if (pk11_pin == NULL)
10878 +                       {
10879 +                       pk11_pin = BUF_strdup(getpassphrase("Enter PIN: "));
10881 +                       if (pk11_pin == NULL)
10882 +                               {
10883 +                               PK11err(PK11_F_LOAD_PUBKEY, PK11_R_MALLOC_FAILURE);
10884 +                               goto err;
10885 +                               }
10886 +                       }
10887 +               if ((rv = pFuncList->C_Login(sp->session, CKU_USER, (CK_UTF8CHAR*)pk11_pin,
10888 +                   strlen(pk11_pin))) != CKR_OK && rv != CKR_USER_ALREADY_LOGGED_IN)
10889 +                       {
10890 +                       PK11err_add_data(PK11_F_LOAD_PUBKEY,
10891 +                                        PK11_R_INVALID_PIN, rv);
10892 +                       goto err;
10893 +                       }
10894 +#endif
10896 +               LOCK_OBJSTORE(OP_RSA);
10897 +               if (pFuncList->C_FindObjectsInit(sp->session, search_templ, 3) != CKR_OK)
10898 +                       {
10899 +                       UNLOCK_OBJSTORE(OP_RSA);
10900 +                       PK11err_add_data(PK11_F_LOAD_PUBKEY,
10901 +                                        PK11_R_FINDOBJECTSINIT, rv);
10902 +                       goto err;
10903 +                       }
10904 +               rv = pFuncList->C_FindObjects(sp->session, &ks_key, 1, &objcnt);
10905 +               if (rv != CKR_OK)
10906 +                       {
10907 +                       UNLOCK_OBJSTORE(OP_RSA);
10908 +                       PK11err_add_data(PK11_F_LOAD_PUBKEY,
10909 +                                        PK11_R_FINDOBJECTS, rv);
10910 +                       goto err;
10911 +                       }
10913 +               if (objcnt > 1)
10914 +                       {
10915 +                       UNLOCK_OBJSTORE(OP_RSA);
10916 +                       PK11err(PK11_F_LOAD_PUBKEY, PK11_R_TOO_MANY_OBJECTS);
10917 +                       goto err;
10918 +                       }
10920 +               if (objcnt != 1)
10921 +                       {
10922 +                       UNLOCK_OBJSTORE(OP_RSA);
10923 +                       PK11err(PK11_F_LOAD_PUBKEY, PK11_R_OBJECT_NOT_FOUND);
10924 +                       goto err;
10925 +                       }
10927 +               (void) pFuncList->C_FindObjectsFinal(sp->session);
10928 +               UNLOCK_OBJSTORE(OP_RSA);
10930 +               sp->opdata_rsa_pub_key = ks_key;
10931 +               pkey = EVP_PKEY_new();
10932 +               if (pkey == NULL)
10933 +                       goto err;
10935 +               rsa = RSA_new_method(e);
10936 +               if (rsa == NULL) {
10937 +                       EVP_PKEY_free(pkey);
10938 +                       pkey = NULL;
10939 +                       goto err;
10940 +               }
10941 +               EVP_PKEY_assign_RSA(pkey, rsa);
10943 +               if (pFuncList->C_GetAttributeValue(sp->session, ks_key,
10944 +                   get_templ, 2) != CKR_OK)
10945 +                       {
10946 +                       PK11err_add_data(PK11_F_LOAD_PUBKEY,
10947 +                                        PK11_R_GETATTRIBUTVALUE, rv);
10948 +                       goto err;
10949 +                       }
10951 +               (void) check_new_rsa_key_pub(sp, rsa);
10952 +               sp->opdata_rsa_pub = rsa;
10954 +               attr_to_BN(&get_templ[0], attr_data[0], &rsa->n);
10955 +               attr_to_BN(&get_templ[1], attr_data[1], &rsa->e);
10956 +               }
10957 +       else if ((pubkey = fopen(pubkey_file, read_mode_flags)) != NULL)
10958 +               {
10959 +               pkey = PEM_read_PUBKEY(pubkey, NULL, NULL, NULL);
10960 +               (void) fclose(pubkey);
10961 +               }
10963 +err:
10964 +       if (sp != NULL)
10965 +               pk11_return_session(sp, OP_RSA);
10966 +       return (pkey);
10967 +       }
10970 + * Create a private key object in the session from a given rsa structure.
10971 + * The *rsa_d_num pointer is non-NULL for RSA private keys.
10972 + */
10973 +static CK_OBJECT_HANDLE pk11_get_private_rsa_key(RSA *rsa,
10974 +    RSA **key_ptr, BIGNUM **rsa_d_num, CK_SESSION_HANDLE session)
10975 +       {
10976 +       CK_OBJECT_HANDLE h_key = CK_INVALID_HANDLE;
10978 +       if ((rsa->flags & RSA_FLAG_EXT_PKEY) == 0) {
10979 +               PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_INCONSISTENT_KEY);
10980 +               return (h_key);
10981 +       }
10982 +       
10983 +       h_key = (CK_OBJECT_HANDLE)RSA_get_ex_data(rsa, hndidx_rsa);
10984 +       (void) pk11_active_add(h_key, OP_RSA);
10985 +       if (key_ptr != NULL)
10986 +               *key_ptr = rsa;
10987 +       if (rsa_d_num != NULL)
10988 +               {
10989 +               if (rsa->d == NULL)
10990 +                       *rsa_d_num = NULL;
10991 +               else if ((*rsa_d_num = BN_dup(rsa->d)) == NULL)
10992 +                       {
10993 +                       PK11err(PK11_F_GET_PRIV_RSA_KEY, PK11_R_MALLOC_FAILURE);
10994 +                       return (h_key);
10995 +                       }
10996 +               }
10997 +       return (h_key);
10998 +       }
11001 + * Check for cache miss and clean the object pointer and handle
11002 + * in such case. Return 1 for cache hit, 0 for cache miss.
11003 + */
11004 +static int check_new_rsa_key_pub(PK11_SESSION *sp, const RSA *rsa)
11005 +       {
11006 +       /*
11007 +        * Provide protection against RSA structure reuse by making the
11008 +        * check for cache hit stronger. Only public components of RSA
11009 +        * key matter here so it is sufficient to compare them with values
11010 +        * cached in PK11_SESSION structure.
11011 +        */
11012 +       if ((sp->opdata_rsa_pub != rsa) ||
11013 +           (BN_cmp(sp->opdata_rsa_n_num, rsa->n) != 0) ||
11014 +           (BN_cmp(sp->opdata_rsa_e_num, rsa->e) != 0))
11015 +               {
11016 +               /*
11017 +                * We do not check the return value because even in case of
11018 +                * failure the sp structure will have both key pointer
11019 +                * and object handle cleaned and pk11_destroy_object()
11020 +                * reports the failure to the OpenSSL error message buffer.
11021 +                */
11022 +               (void) pk11_destroy_rsa_object_pub(sp, TRUE);
11023 +               return (0);
11024 +               }
11025 +       return (1);
11026 +       }
11029 + * Check for cache miss and clean the object pointer and handle
11030 + * in such case. Return 1 for cache hit, 0 for cache miss.
11031 + */
11032 +static int check_new_rsa_key_priv(PK11_SESSION *sp, const RSA *rsa)
11033 +       {
11034 +       /*
11035 +        * Provide protection against RSA structure reuse by making the
11036 +        * check for cache hit stronger. Comparing private exponent of RSA
11037 +        * key with value cached in PK11_SESSION structure should
11038 +        * be sufficient.
11039 +        */
11040 +       if ((sp->opdata_rsa_priv != rsa) ||
11041 +           (BN_cmp(sp->opdata_rsa_d_num, rsa->d) != 0) ||
11042 +           ((rsa->flags & RSA_FLAG_EXT_PKEY) != 0))
11043 +               {
11044 +               /*
11045 +                * We do not check the return value because even in case of
11046 +                * failure the sp structure will have both key pointer
11047 +                * and object handle cleaned and pk11_destroy_object()
11048 +                * reports the failure to the OpenSSL error message buffer.
11049 +                */
11050 +               (void) pk11_destroy_rsa_object_priv(sp, TRUE);
11051 +               return (0);
11052 +               }
11053 +       return (1);
11054 +       }
11056 +static void attr_to_BN(CK_ATTRIBUTE_PTR attr, CK_BYTE attr_data[], BIGNUM **bn)
11057 +       {
11058 +       if (attr->ulValueLen > 0)
11059 +               {
11060 +               *bn = BN_bin2bn(attr_data, attr->ulValueLen, NULL);
11061 +               }
11062 +       }
11064 +#ifdef OPENSSL_SYS_WIN32
11065 +char *getpassphrase(const char *prompt)
11066 +       {
11067 +       static char buf[128];
11068 +       HANDLE h;
11069 +       DWORD cc, mode;
11070 +       int cnt;
11072 +       h = GetStdHandle(STD_INPUT_HANDLE);
11073 +       fputs(prompt, stderr);
11074 +       fflush(stderr);
11075 +       fflush(stdout);
11076 +       FlushConsoleInputBuffer(h);
11077 +       GetConsoleMode(h, &mode);
11078 +       SetConsoleMode(h, ENABLE_PROCESSED_INPUT);
11080 +       for (cnt = 0; cnt < sizeof(buf) - 1; cnt++)
11081 +               {
11082 +               ReadFile(h, buf + cnt, 1, &cc, NULL);
11083 +               if (buf[cnt] == '\r')
11084 +                       break;
11085 +               fputc('*', stdout);
11086 +               fflush(stderr);
11087 +               fflush(stdout);
11088 +               }
11090 +       SetConsoleMode(h, mode);
11091 +       buf[cnt] = '\0';
11092 +       fputs("\n", stderr);
11093 +       return buf;
11094 +       }
11095 +#endif /* OPENSSL_SYS_WIN32 */
11096 +#endif /* OPENSSL_NO_HW_PK11SO */
11097 +#endif /* OPENSSL_NO_HW_PK11 */
11098 +#endif /* OPENSSL_NO_HW */
11099 Index: openssl/crypto/engine/pkcs11.h
11100 diff -u /dev/null openssl/crypto/engine/pkcs11.h:1.1.1.1
11101 --- /dev/null   Mon Oct  5 13:17:24 2009
11102 +++ openssl/crypto/engine/pkcs11.h      Wed Oct 24 23:27:09 2007
11103 @@ -0,0 +1,299 @@
11104 +/* pkcs11.h include file for PKCS #11. */
11105 +/* Revision: 1.1 */
11107 +/* License to copy and use this software is granted provided that it is
11108 + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
11109 + * (Cryptoki)" in all material mentioning or referencing this software.
11111 + * License is also granted to make and use derivative works provided that
11112 + * such works are identified as "derived from the RSA Security Inc. PKCS #11
11113 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
11114 + * referencing the derived work.
11116 + * RSA Security Inc. makes no representations concerning either the 
11117 + * merchantability of this software or the suitability of this software for
11118 + * any particular purpose. It is provided "as is" without express or implied
11119 + * warranty of any kind.
11120 + */
11122 +#ifndef _PKCS11_H_
11123 +#define _PKCS11_H_ 1
11125 +#ifdef __cplusplus
11126 +extern "C" {
11127 +#endif
11129 +/* Before including this file (pkcs11.h) (or pkcs11t.h by
11130 + * itself), 6 platform-specific macros must be defined.  These
11131 + * macros are described below, and typical definitions for them
11132 + * are also given.  Be advised that these definitions can depend
11133 + * on both the platform and the compiler used (and possibly also
11134 + * on whether a Cryptoki library is linked statically or
11135 + * dynamically).
11136 + *
11137 + * In addition to defining these 6 macros, the packing convention
11138 + * for Cryptoki structures should be set.  The Cryptoki
11139 + * convention on packing is that structures should be 1-byte
11140 + * aligned.
11141 + *
11142 + * If you're using Microsoft Developer Studio 5.0 to produce
11143 + * Win32 stuff, this might be done by using the following
11144 + * preprocessor directive before including pkcs11.h or pkcs11t.h:
11145 + *
11146 + * #pragma pack(push, cryptoki, 1)
11147 + *
11148 + * and using the following preprocessor directive after including
11149 + * pkcs11.h or pkcs11t.h:
11150 + *
11151 + * #pragma pack(pop, cryptoki)
11152 + *
11153 + * If you're using an earlier version of Microsoft Developer
11154 + * Studio to produce Win16 stuff, this might be done by using
11155 + * the following preprocessor directive before including
11156 + * pkcs11.h or pkcs11t.h:
11157 + *
11158 + * #pragma pack(1)
11159 + *
11160 + * In a UNIX environment, you're on your own for this.  You might
11161 + * not need to do (or be able to do!) anything.
11162 + *
11163 + *
11164 + * Now for the macros:
11165 + *
11166 + *
11167 + * 1. CK_PTR: The indirection string for making a pointer to an
11168 + * object.  It can be used like this:
11169 + *
11170 + * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
11171 + *
11172 + * If you're using Microsoft Developer Studio 5.0 to produce
11173 + * Win32 stuff, it might be defined by:
11174 + *
11175 + * #define CK_PTR *
11176 + *
11177 + * If you're using an earlier version of Microsoft Developer
11178 + * Studio to produce Win16 stuff, it might be defined by:
11179 + *
11180 + * #define CK_PTR far *
11181 + *
11182 + * In a typical UNIX environment, it might be defined by:
11183 + *
11184 + * #define CK_PTR *
11185 + *
11186 + *
11187 + * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
11188 + * an exportable Cryptoki library function definition out of a
11189 + * return type and a function name.  It should be used in the
11190 + * following fashion to define the exposed Cryptoki functions in
11191 + * a Cryptoki library:
11192 + *
11193 + * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
11194 + *   CK_VOID_PTR pReserved
11195 + * )
11196 + * {
11197 + *   ...
11198 + * }
11199 + *
11200 + * If you're using Microsoft Developer Studio 5.0 to define a
11201 + * function in a Win32 Cryptoki .dll, it might be defined by:
11202 + *
11203 + * #define CK_DEFINE_FUNCTION(returnType, name) \
11204 + *   returnType __declspec(dllexport) name
11205 + *
11206 + * If you're using an earlier version of Microsoft Developer
11207 + * Studio to define a function in a Win16 Cryptoki .dll, it
11208 + * might be defined by:
11209 + *
11210 + * #define CK_DEFINE_FUNCTION(returnType, name) \
11211 + *   returnType __export _far _pascal name
11212 + *
11213 + * In a UNIX environment, it might be defined by:
11214 + *
11215 + * #define CK_DEFINE_FUNCTION(returnType, name) \
11216 + *   returnType name
11217 + *
11218 + *
11219 + * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
11220 + * an importable Cryptoki library function declaration out of a
11221 + * return type and a function name.  It should be used in the
11222 + * following fashion:
11223 + *
11224 + * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
11225 + *   CK_VOID_PTR pReserved
11226 + * );
11227 + *
11228 + * If you're using Microsoft Developer Studio 5.0 to declare a
11229 + * function in a Win32 Cryptoki .dll, it might be defined by:
11230 + *
11231 + * #define CK_DECLARE_FUNCTION(returnType, name) \
11232 + *   returnType __declspec(dllimport) name
11233 + *
11234 + * If you're using an earlier version of Microsoft Developer
11235 + * Studio to declare a function in a Win16 Cryptoki .dll, it
11236 + * might be defined by:
11237 + *
11238 + * #define CK_DECLARE_FUNCTION(returnType, name) \
11239 + *   returnType __export _far _pascal name
11240 + *
11241 + * In a UNIX environment, it might be defined by:
11242 + *
11243 + * #define CK_DECLARE_FUNCTION(returnType, name) \
11244 + *   returnType name
11245 + *
11246 + *
11247 + * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
11248 + * which makes a Cryptoki API function pointer declaration or
11249 + * function pointer type declaration out of a return type and a
11250 + * function name.  It should be used in the following fashion:
11251 + *
11252 + * // Define funcPtr to be a pointer to a Cryptoki API function
11253 + * // taking arguments args and returning CK_RV.
11254 + * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
11255 + *
11256 + * or
11257 + *
11258 + * // Define funcPtrType to be the type of a pointer to a
11259 + * // Cryptoki API function taking arguments args and returning
11260 + * // CK_RV, and then define funcPtr to be a variable of type
11261 + * // funcPtrType.
11262 + * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
11263 + * funcPtrType funcPtr;
11264 + *
11265 + * If you're using Microsoft Developer Studio 5.0 to access
11266 + * functions in a Win32 Cryptoki .dll, in might be defined by:
11267 + *
11268 + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
11269 + *   returnType __declspec(dllimport) (* name)
11270 + *
11271 + * If you're using an earlier version of Microsoft Developer
11272 + * Studio to access functions in a Win16 Cryptoki .dll, it might
11273 + * be defined by:
11274 + *
11275 + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
11276 + *   returnType __export _far _pascal (* name)
11277 + *
11278 + * In a UNIX environment, it might be defined by:
11279 + *
11280 + * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
11281 + *   returnType (* name)
11282 + *
11283 + *
11284 + * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
11285 + * a function pointer type for an application callback out of
11286 + * a return type for the callback and a name for the callback.
11287 + * It should be used in the following fashion:
11288 + *
11289 + * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
11290 + *
11291 + * to declare a function pointer, myCallback, to a callback
11292 + * which takes arguments args and returns a CK_RV.  It can also
11293 + * be used like this:
11294 + *
11295 + * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
11296 + * myCallbackType myCallback;
11297 + *
11298 + * If you're using Microsoft Developer Studio 5.0 to do Win32
11299 + * Cryptoki development, it might be defined by:
11300 + *
11301 + * #define CK_CALLBACK_FUNCTION(returnType, name) \
11302 + *   returnType (* name)
11303 + *
11304 + * If you're using an earlier version of Microsoft Developer
11305 + * Studio to do Win16 development, it might be defined by:
11306 + *
11307 + * #define CK_CALLBACK_FUNCTION(returnType, name) \
11308 + *   returnType _far _pascal (* name)
11309 + *
11310 + * In a UNIX environment, it might be defined by:
11311 + *
11312 + * #define CK_CALLBACK_FUNCTION(returnType, name) \
11313 + *   returnType (* name)
11314 + *
11315 + *
11316 + * 6. NULL_PTR: This macro is the value of a NULL pointer.
11317 + *
11318 + * In any ANSI/ISO C environment (and in many others as well),
11319 + * this should best be defined by
11320 + *
11321 + * #ifndef NULL_PTR
11322 + * #define NULL_PTR 0
11323 + * #endif
11324 + */
11327 +/* All the various Cryptoki types and #define'd values are in the
11328 + * file pkcs11t.h. */
11329 +#include "pkcs11t.h"
11331 +#define __PASTE(x,y)      x##y
11334 +/* ==============================================================
11335 + * Define the "extern" form of all the entry points.
11336 + * ==============================================================
11337 + */
11339 +#define CK_NEED_ARG_LIST  1
11340 +#define CK_PKCS11_FUNCTION_INFO(name) \
11341 +  extern CK_DECLARE_FUNCTION(CK_RV, name)
11343 +/* pkcs11f.h has all the information about the Cryptoki
11344 + * function prototypes. */
11345 +#include "pkcs11f.h"
11347 +#undef CK_NEED_ARG_LIST
11348 +#undef CK_PKCS11_FUNCTION_INFO
11351 +/* ==============================================================
11352 + * Define the typedef form of all the entry points.  That is, for
11353 + * each Cryptoki function C_XXX, define a type CK_C_XXX which is
11354 + * a pointer to that kind of function.
11355 + * ==============================================================
11356 + */
11358 +#define CK_NEED_ARG_LIST  1
11359 +#define CK_PKCS11_FUNCTION_INFO(name) \
11360 +  typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
11362 +/* pkcs11f.h has all the information about the Cryptoki
11363 + * function prototypes. */
11364 +#include "pkcs11f.h"
11366 +#undef CK_NEED_ARG_LIST
11367 +#undef CK_PKCS11_FUNCTION_INFO
11370 +/* ==============================================================
11371 + * Define structed vector of entry points.  A CK_FUNCTION_LIST
11372 + * contains a CK_VERSION indicating a library's Cryptoki version
11373 + * and then a whole slew of function pointers to the routines in
11374 + * the library.  This type was declared, but not defined, in
11375 + * pkcs11t.h.
11376 + * ==============================================================
11377 + */
11379 +#define CK_PKCS11_FUNCTION_INFO(name) \
11380 +  __PASTE(CK_,name) name;
11381 +  
11382 +struct CK_FUNCTION_LIST {
11384 +  CK_VERSION    version;  /* Cryptoki version */
11386 +/* Pile all the function pointers into the CK_FUNCTION_LIST. */
11387 +/* pkcs11f.h has all the information about the Cryptoki
11388 + * function prototypes. */
11389 +#include "pkcs11f.h"
11393 +#undef CK_PKCS11_FUNCTION_INFO
11396 +#undef __PASTE
11398 +#ifdef __cplusplus
11400 +#endif
11402 +#endif
11403 Index: openssl/crypto/engine/pkcs11f.h
11404 diff -u /dev/null openssl/crypto/engine/pkcs11f.h:1.1.1.1
11405 --- /dev/null   Mon Oct  5 13:17:24 2009
11406 +++ openssl/crypto/engine/pkcs11f.h     Wed Oct 24 23:27:09 2007
11407 @@ -0,0 +1,912 @@
11408 +/* pkcs11f.h include file for PKCS #11. */
11409 +/* Revision: 1.1 */
11411 +/* License to copy and use this software is granted provided that it is
11412 + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
11413 + * (Cryptoki)" in all material mentioning or referencing this software.
11415 + * License is also granted to make and use derivative works provided that
11416 + * such works are identified as "derived from the RSA Security Inc. PKCS #11
11417 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
11418 + * referencing the derived work.
11420 + * RSA Security Inc. makes no representations concerning either the 
11421 + * merchantability of this software or the suitability of this software for
11422 + * any particular purpose. It is provided "as is" without express or implied
11423 + * warranty of any kind.
11424 + */
11426 +/* This header file contains pretty much everything about all the */
11427 +/* Cryptoki function prototypes.  Because this information is */
11428 +/* used for more than just declaring function prototypes, the */
11429 +/* order of the functions appearing herein is important, and */
11430 +/* should not be altered. */
11432 +/* General-purpose */
11434 +/* C_Initialize initializes the Cryptoki library. */
11435 +CK_PKCS11_FUNCTION_INFO(C_Initialize)
11436 +#ifdef CK_NEED_ARG_LIST
11438 +  CK_VOID_PTR   pInitArgs  /* if this is not NULL_PTR, it gets
11439 +                            * cast to CK_C_INITIALIZE_ARGS_PTR
11440 +                            * and dereferenced */
11442 +#endif
11445 +/* C_Finalize indicates that an application is done with the
11446 + * Cryptoki library. */
11447 +CK_PKCS11_FUNCTION_INFO(C_Finalize)
11448 +#ifdef CK_NEED_ARG_LIST
11450 +  CK_VOID_PTR   pReserved  /* reserved.  Should be NULL_PTR */
11452 +#endif
11455 +/* C_GetInfo returns general information about Cryptoki. */
11456 +CK_PKCS11_FUNCTION_INFO(C_GetInfo)
11457 +#ifdef CK_NEED_ARG_LIST
11459 +  CK_INFO_PTR   pInfo  /* location that receives information */
11461 +#endif
11464 +/* C_GetFunctionList returns the function list. */
11465 +CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
11466 +#ifdef CK_NEED_ARG_LIST
11468 +  CK_FUNCTION_LIST_PTR_PTR ppFunctionList  /* receives pointer to
11469 +                                            * function list */
11471 +#endif
11475 +/* Slot and token management */
11477 +/* C_GetSlotList obtains a list of slots in the system. */
11478 +CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
11479 +#ifdef CK_NEED_ARG_LIST
11481 +  CK_BBOOL       tokenPresent,  /* only slots with tokens? */
11482 +  CK_SLOT_ID_PTR pSlotList,     /* receives array of slot IDs */
11483 +  CK_ULONG_PTR   pulCount       /* receives number of slots */
11485 +#endif
11488 +/* C_GetSlotInfo obtains information about a particular slot in
11489 + * the system. */
11490 +CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
11491 +#ifdef CK_NEED_ARG_LIST
11493 +  CK_SLOT_ID       slotID,  /* the ID of the slot */
11494 +  CK_SLOT_INFO_PTR pInfo    /* receives the slot information */
11496 +#endif
11499 +/* C_GetTokenInfo obtains information about a particular token
11500 + * in the system. */
11501 +CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
11502 +#ifdef CK_NEED_ARG_LIST
11504 +  CK_SLOT_ID        slotID,  /* ID of the token's slot */
11505 +  CK_TOKEN_INFO_PTR pInfo    /* receives the token information */
11507 +#endif
11510 +/* C_GetMechanismList obtains a list of mechanism types
11511 + * supported by a token. */
11512 +CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
11513 +#ifdef CK_NEED_ARG_LIST
11515 +  CK_SLOT_ID            slotID,          /* ID of token's slot */
11516 +  CK_MECHANISM_TYPE_PTR pMechanismList,  /* gets mech. array */
11517 +  CK_ULONG_PTR          pulCount         /* gets # of mechs. */
11519 +#endif
11522 +/* C_GetMechanismInfo obtains information about a particular
11523 + * mechanism possibly supported by a token. */
11524 +CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
11525 +#ifdef CK_NEED_ARG_LIST
11527 +  CK_SLOT_ID            slotID,  /* ID of the token's slot */
11528 +  CK_MECHANISM_TYPE     type,    /* type of mechanism */
11529 +  CK_MECHANISM_INFO_PTR pInfo    /* receives mechanism info */
11531 +#endif
11534 +/* C_InitToken initializes a token. */
11535 +CK_PKCS11_FUNCTION_INFO(C_InitToken)
11536 +#ifdef CK_NEED_ARG_LIST
11537 +/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
11539 +  CK_SLOT_ID      slotID,    /* ID of the token's slot */
11540 +  CK_UTF8CHAR_PTR pPin,      /* the SO's initial PIN */
11541 +  CK_ULONG        ulPinLen,  /* length in bytes of the PIN */
11542 +  CK_UTF8CHAR_PTR pLabel     /* 32-byte token label (blank padded) */
11544 +#endif
11547 +/* C_InitPIN initializes the normal user's PIN. */
11548 +CK_PKCS11_FUNCTION_INFO(C_InitPIN)
11549 +#ifdef CK_NEED_ARG_LIST
11551 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
11552 +  CK_UTF8CHAR_PTR   pPin,      /* the normal user's PIN */
11553 +  CK_ULONG          ulPinLen   /* length in bytes of the PIN */
11555 +#endif
11558 +/* C_SetPIN modifies the PIN of the user who is logged in. */
11559 +CK_PKCS11_FUNCTION_INFO(C_SetPIN)
11560 +#ifdef CK_NEED_ARG_LIST
11562 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
11563 +  CK_UTF8CHAR_PTR   pOldPin,   /* the old PIN */
11564 +  CK_ULONG          ulOldLen,  /* length of the old PIN */
11565 +  CK_UTF8CHAR_PTR   pNewPin,   /* the new PIN */
11566 +  CK_ULONG          ulNewLen   /* length of the new PIN */
11568 +#endif
11572 +/* Session management */
11574 +/* C_OpenSession opens a session between an application and a
11575 + * token. */
11576 +CK_PKCS11_FUNCTION_INFO(C_OpenSession)
11577 +#ifdef CK_NEED_ARG_LIST
11579 +  CK_SLOT_ID            slotID,        /* the slot's ID */
11580 +  CK_FLAGS              flags,         /* from CK_SESSION_INFO */
11581 +  CK_VOID_PTR           pApplication,  /* passed to callback */
11582 +  CK_NOTIFY             Notify,        /* callback function */
11583 +  CK_SESSION_HANDLE_PTR phSession      /* gets session handle */
11585 +#endif
11588 +/* C_CloseSession closes a session between an application and a
11589 + * token. */
11590 +CK_PKCS11_FUNCTION_INFO(C_CloseSession)
11591 +#ifdef CK_NEED_ARG_LIST
11593 +  CK_SESSION_HANDLE hSession  /* the session's handle */
11595 +#endif
11598 +/* C_CloseAllSessions closes all sessions with a token. */
11599 +CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
11600 +#ifdef CK_NEED_ARG_LIST
11602 +  CK_SLOT_ID     slotID  /* the token's slot */
11604 +#endif
11607 +/* C_GetSessionInfo obtains information about the session. */
11608 +CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
11609 +#ifdef CK_NEED_ARG_LIST
11611 +  CK_SESSION_HANDLE   hSession,  /* the session's handle */
11612 +  CK_SESSION_INFO_PTR pInfo      /* receives session info */
11614 +#endif
11617 +/* C_GetOperationState obtains the state of the cryptographic operation
11618 + * in a session. */
11619 +CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
11620 +#ifdef CK_NEED_ARG_LIST
11622 +  CK_SESSION_HANDLE hSession,             /* session's handle */
11623 +  CK_BYTE_PTR       pOperationState,      /* gets state */
11624 +  CK_ULONG_PTR      pulOperationStateLen  /* gets state length */
11626 +#endif
11629 +/* C_SetOperationState restores the state of the cryptographic
11630 + * operation in a session. */
11631 +CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
11632 +#ifdef CK_NEED_ARG_LIST
11634 +  CK_SESSION_HANDLE hSession,            /* session's handle */
11635 +  CK_BYTE_PTR      pOperationState,      /* holds state */
11636 +  CK_ULONG         ulOperationStateLen,  /* holds state length */
11637 +  CK_OBJECT_HANDLE hEncryptionKey,       /* en/decryption key */
11638 +  CK_OBJECT_HANDLE hAuthenticationKey    /* sign/verify key */
11640 +#endif
11643 +/* C_Login logs a user into a token. */
11644 +CK_PKCS11_FUNCTION_INFO(C_Login)
11645 +#ifdef CK_NEED_ARG_LIST
11647 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
11648 +  CK_USER_TYPE      userType,  /* the user type */
11649 +  CK_UTF8CHAR_PTR   pPin,      /* the user's PIN */
11650 +  CK_ULONG          ulPinLen   /* the length of the PIN */
11652 +#endif
11655 +/* C_Logout logs a user out from a token. */
11656 +CK_PKCS11_FUNCTION_INFO(C_Logout)
11657 +#ifdef CK_NEED_ARG_LIST
11659 +  CK_SESSION_HANDLE hSession  /* the session's handle */
11661 +#endif
11665 +/* Object management */
11667 +/* C_CreateObject creates a new object. */
11668 +CK_PKCS11_FUNCTION_INFO(C_CreateObject)
11669 +#ifdef CK_NEED_ARG_LIST
11671 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
11672 +  CK_ATTRIBUTE_PTR  pTemplate,   /* the object's template */
11673 +  CK_ULONG          ulCount,     /* attributes in template */
11674 +  CK_OBJECT_HANDLE_PTR phObject  /* gets new object's handle. */
11676 +#endif
11679 +/* C_CopyObject copies an object, creating a new object for the
11680 + * copy. */
11681 +CK_PKCS11_FUNCTION_INFO(C_CopyObject)
11682 +#ifdef CK_NEED_ARG_LIST
11684 +  CK_SESSION_HANDLE    hSession,    /* the session's handle */
11685 +  CK_OBJECT_HANDLE     hObject,     /* the object's handle */
11686 +  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new object */
11687 +  CK_ULONG             ulCount,     /* attributes in template */
11688 +  CK_OBJECT_HANDLE_PTR phNewObject  /* receives handle of copy */
11690 +#endif
11693 +/* C_DestroyObject destroys an object. */
11694 +CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
11695 +#ifdef CK_NEED_ARG_LIST
11697 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
11698 +  CK_OBJECT_HANDLE  hObject    /* the object's handle */
11700 +#endif
11703 +/* C_GetObjectSize gets the size of an object in bytes. */
11704 +CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
11705 +#ifdef CK_NEED_ARG_LIST
11707 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
11708 +  CK_OBJECT_HANDLE  hObject,   /* the object's handle */
11709 +  CK_ULONG_PTR      pulSize    /* receives size of object */
11711 +#endif
11714 +/* C_GetAttributeValue obtains the value of one or more object
11715 + * attributes. */
11716 +CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
11717 +#ifdef CK_NEED_ARG_LIST
11719 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
11720 +  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
11721 +  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs; gets vals */
11722 +  CK_ULONG          ulCount     /* attributes in template */
11724 +#endif
11727 +/* C_SetAttributeValue modifies the value of one or more object
11728 + * attributes */
11729 +CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
11730 +#ifdef CK_NEED_ARG_LIST
11732 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
11733 +  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
11734 +  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs and values */
11735 +  CK_ULONG          ulCount     /* attributes in template */
11737 +#endif
11740 +/* C_FindObjectsInit initializes a search for token and session
11741 + * objects that match a template. */
11742 +CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
11743 +#ifdef CK_NEED_ARG_LIST
11745 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
11746 +  CK_ATTRIBUTE_PTR  pTemplate,  /* attribute values to match */
11747 +  CK_ULONG          ulCount     /* attrs in search template */
11749 +#endif
11752 +/* C_FindObjects continues a search for token and session
11753 + * objects that match a template, obtaining additional object
11754 + * handles. */
11755 +CK_PKCS11_FUNCTION_INFO(C_FindObjects)
11756 +#ifdef CK_NEED_ARG_LIST
11758 + CK_SESSION_HANDLE    hSession,          /* session's handle */
11759 + CK_OBJECT_HANDLE_PTR phObject,          /* gets obj. handles */
11760 + CK_ULONG             ulMaxObjectCount,  /* max handles to get */
11761 + CK_ULONG_PTR         pulObjectCount     /* actual # returned */
11763 +#endif
11766 +/* C_FindObjectsFinal finishes a search for token and session
11767 + * objects. */
11768 +CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
11769 +#ifdef CK_NEED_ARG_LIST
11771 +  CK_SESSION_HANDLE hSession  /* the session's handle */
11773 +#endif
11777 +/* Encryption and decryption */
11779 +/* C_EncryptInit initializes an encryption operation. */
11780 +CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
11781 +#ifdef CK_NEED_ARG_LIST
11783 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
11784 +  CK_MECHANISM_PTR  pMechanism,  /* the encryption mechanism */
11785 +  CK_OBJECT_HANDLE  hKey         /* handle of encryption key */
11787 +#endif
11790 +/* C_Encrypt encrypts single-part data. */
11791 +CK_PKCS11_FUNCTION_INFO(C_Encrypt)
11792 +#ifdef CK_NEED_ARG_LIST
11794 +  CK_SESSION_HANDLE hSession,            /* session's handle */
11795 +  CK_BYTE_PTR       pData,               /* the plaintext data */
11796 +  CK_ULONG          ulDataLen,           /* bytes of plaintext */
11797 +  CK_BYTE_PTR       pEncryptedData,      /* gets ciphertext */
11798 +  CK_ULONG_PTR      pulEncryptedDataLen  /* gets c-text size */
11800 +#endif
11803 +/* C_EncryptUpdate continues a multiple-part encryption
11804 + * operation. */
11805 +CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
11806 +#ifdef CK_NEED_ARG_LIST
11808 +  CK_SESSION_HANDLE hSession,           /* session's handle */
11809 +  CK_BYTE_PTR       pPart,              /* the plaintext data */
11810 +  CK_ULONG          ulPartLen,          /* plaintext data len */
11811 +  CK_BYTE_PTR       pEncryptedPart,     /* gets ciphertext */
11812 +  CK_ULONG_PTR      pulEncryptedPartLen /* gets c-text size */
11814 +#endif
11817 +/* C_EncryptFinal finishes a multiple-part encryption
11818 + * operation. */
11819 +CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
11820 +#ifdef CK_NEED_ARG_LIST
11822 +  CK_SESSION_HANDLE hSession,                /* session handle */
11823 +  CK_BYTE_PTR       pLastEncryptedPart,      /* last c-text */
11824 +  CK_ULONG_PTR      pulLastEncryptedPartLen  /* gets last size */
11826 +#endif
11829 +/* C_DecryptInit initializes a decryption operation. */
11830 +CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
11831 +#ifdef CK_NEED_ARG_LIST
11833 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
11834 +  CK_MECHANISM_PTR  pMechanism,  /* the decryption mechanism */
11835 +  CK_OBJECT_HANDLE  hKey         /* handle of decryption key */
11837 +#endif
11840 +/* C_Decrypt decrypts encrypted data in a single part. */
11841 +CK_PKCS11_FUNCTION_INFO(C_Decrypt)
11842 +#ifdef CK_NEED_ARG_LIST
11844 +  CK_SESSION_HANDLE hSession,           /* session's handle */
11845 +  CK_BYTE_PTR       pEncryptedData,     /* ciphertext */
11846 +  CK_ULONG          ulEncryptedDataLen, /* ciphertext length */
11847 +  CK_BYTE_PTR       pData,              /* gets plaintext */
11848 +  CK_ULONG_PTR      pulDataLen          /* gets p-text size */
11850 +#endif
11853 +/* C_DecryptUpdate continues a multiple-part decryption
11854 + * operation. */
11855 +CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
11856 +#ifdef CK_NEED_ARG_LIST
11858 +  CK_SESSION_HANDLE hSession,            /* session's handle */
11859 +  CK_BYTE_PTR       pEncryptedPart,      /* encrypted data */
11860 +  CK_ULONG          ulEncryptedPartLen,  /* input length */
11861 +  CK_BYTE_PTR       pPart,               /* gets plaintext */
11862 +  CK_ULONG_PTR      pulPartLen           /* p-text size */
11864 +#endif
11867 +/* C_DecryptFinal finishes a multiple-part decryption
11868 + * operation. */
11869 +CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
11870 +#ifdef CK_NEED_ARG_LIST
11872 +  CK_SESSION_HANDLE hSession,       /* the session's handle */
11873 +  CK_BYTE_PTR       pLastPart,      /* gets plaintext */
11874 +  CK_ULONG_PTR      pulLastPartLen  /* p-text size */
11876 +#endif
11880 +/* Message digesting */
11882 +/* C_DigestInit initializes a message-digesting operation. */
11883 +CK_PKCS11_FUNCTION_INFO(C_DigestInit)
11884 +#ifdef CK_NEED_ARG_LIST
11886 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
11887 +  CK_MECHANISM_PTR  pMechanism  /* the digesting mechanism */
11889 +#endif
11892 +/* C_Digest digests data in a single part. */
11893 +CK_PKCS11_FUNCTION_INFO(C_Digest)
11894 +#ifdef CK_NEED_ARG_LIST
11896 +  CK_SESSION_HANDLE hSession,     /* the session's handle */
11897 +  CK_BYTE_PTR       pData,        /* data to be digested */
11898 +  CK_ULONG          ulDataLen,    /* bytes of data to digest */
11899 +  CK_BYTE_PTR       pDigest,      /* gets the message digest */
11900 +  CK_ULONG_PTR      pulDigestLen  /* gets digest length */
11902 +#endif
11905 +/* C_DigestUpdate continues a multiple-part message-digesting
11906 + * operation. */
11907 +CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
11908 +#ifdef CK_NEED_ARG_LIST
11910 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
11911 +  CK_BYTE_PTR       pPart,     /* data to be digested */
11912 +  CK_ULONG          ulPartLen  /* bytes of data to be digested */
11914 +#endif
11917 +/* C_DigestKey continues a multi-part message-digesting
11918 + * operation, by digesting the value of a secret key as part of
11919 + * the data already digested. */
11920 +CK_PKCS11_FUNCTION_INFO(C_DigestKey)
11921 +#ifdef CK_NEED_ARG_LIST
11923 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
11924 +  CK_OBJECT_HANDLE  hKey       /* secret key to digest */
11926 +#endif
11929 +/* C_DigestFinal finishes a multiple-part message-digesting
11930 + * operation. */
11931 +CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
11932 +#ifdef CK_NEED_ARG_LIST
11934 +  CK_SESSION_HANDLE hSession,     /* the session's handle */
11935 +  CK_BYTE_PTR       pDigest,      /* gets the message digest */
11936 +  CK_ULONG_PTR      pulDigestLen  /* gets byte count of digest */
11938 +#endif
11942 +/* Signing and MACing */
11944 +/* C_SignInit initializes a signature (private key encryption)
11945 + * operation, where the signature is (will be) an appendix to
11946 + * the data, and plaintext cannot be recovered from the
11947 + *signature. */
11948 +CK_PKCS11_FUNCTION_INFO(C_SignInit)
11949 +#ifdef CK_NEED_ARG_LIST
11951 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
11952 +  CK_MECHANISM_PTR  pMechanism,  /* the signature mechanism */
11953 +  CK_OBJECT_HANDLE  hKey         /* handle of signature key */
11955 +#endif
11958 +/* C_Sign signs (encrypts with private key) data in a single
11959 + * part, where the signature is (will be) an appendix to the
11960 + * data, and plaintext cannot be recovered from the signature. */
11961 +CK_PKCS11_FUNCTION_INFO(C_Sign)
11962 +#ifdef CK_NEED_ARG_LIST
11964 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
11965 +  CK_BYTE_PTR       pData,           /* the data to sign */
11966 +  CK_ULONG          ulDataLen,       /* count of bytes to sign */
11967 +  CK_BYTE_PTR       pSignature,      /* gets the signature */
11968 +  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
11970 +#endif
11973 +/* C_SignUpdate continues a multiple-part signature operation,
11974 + * where the signature is (will be) an appendix to the data, 
11975 + * and plaintext cannot be recovered from the signature. */
11976 +CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
11977 +#ifdef CK_NEED_ARG_LIST
11979 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
11980 +  CK_BYTE_PTR       pPart,     /* the data to sign */
11981 +  CK_ULONG          ulPartLen  /* count of bytes to sign */
11983 +#endif
11986 +/* C_SignFinal finishes a multiple-part signature operation, 
11987 + * returning the signature. */
11988 +CK_PKCS11_FUNCTION_INFO(C_SignFinal)
11989 +#ifdef CK_NEED_ARG_LIST
11991 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
11992 +  CK_BYTE_PTR       pSignature,      /* gets the signature */
11993 +  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
11995 +#endif
11998 +/* C_SignRecoverInit initializes a signature operation, where
11999 + * the data can be recovered from the signature. */
12000 +CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
12001 +#ifdef CK_NEED_ARG_LIST
12003 +  CK_SESSION_HANDLE hSession,   /* the session's handle */
12004 +  CK_MECHANISM_PTR  pMechanism, /* the signature mechanism */
12005 +  CK_OBJECT_HANDLE  hKey        /* handle of the signature key */
12007 +#endif
12010 +/* C_SignRecover signs data in a single operation, where the
12011 + * data can be recovered from the signature. */
12012 +CK_PKCS11_FUNCTION_INFO(C_SignRecover)
12013 +#ifdef CK_NEED_ARG_LIST
12015 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
12016 +  CK_BYTE_PTR       pData,           /* the data to sign */
12017 +  CK_ULONG          ulDataLen,       /* count of bytes to sign */
12018 +  CK_BYTE_PTR       pSignature,      /* gets the signature */
12019 +  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
12021 +#endif
12025 +/* Verifying signatures and MACs */
12027 +/* C_VerifyInit initializes a verification operation, where the
12028 + * signature is an appendix to the data, and plaintext cannot
12029 + *  cannot be recovered from the signature (e.g. DSA). */
12030 +CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
12031 +#ifdef CK_NEED_ARG_LIST
12033 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
12034 +  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
12035 +  CK_OBJECT_HANDLE  hKey         /* verification key */ 
12037 +#endif
12040 +/* C_Verify verifies a signature in a single-part operation, 
12041 + * where the signature is an appendix to the data, and plaintext
12042 + * cannot be recovered from the signature. */
12043 +CK_PKCS11_FUNCTION_INFO(C_Verify)
12044 +#ifdef CK_NEED_ARG_LIST
12046 +  CK_SESSION_HANDLE hSession,       /* the session's handle */
12047 +  CK_BYTE_PTR       pData,          /* signed data */
12048 +  CK_ULONG          ulDataLen,      /* length of signed data */
12049 +  CK_BYTE_PTR       pSignature,     /* signature */
12050 +  CK_ULONG          ulSignatureLen  /* signature length*/
12052 +#endif
12055 +/* C_VerifyUpdate continues a multiple-part verification
12056 + * operation, where the signature is an appendix to the data, 
12057 + * and plaintext cannot be recovered from the signature. */
12058 +CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
12059 +#ifdef CK_NEED_ARG_LIST
12061 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
12062 +  CK_BYTE_PTR       pPart,     /* signed data */
12063 +  CK_ULONG          ulPartLen  /* length of signed data */
12065 +#endif
12068 +/* C_VerifyFinal finishes a multiple-part verification
12069 + * operation, checking the signature. */
12070 +CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
12071 +#ifdef CK_NEED_ARG_LIST
12073 +  CK_SESSION_HANDLE hSession,       /* the session's handle */
12074 +  CK_BYTE_PTR       pSignature,     /* signature to verify */
12075 +  CK_ULONG          ulSignatureLen  /* signature length */
12077 +#endif
12080 +/* C_VerifyRecoverInit initializes a signature verification
12081 + * operation, where the data is recovered from the signature. */
12082 +CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
12083 +#ifdef CK_NEED_ARG_LIST
12085 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
12086 +  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
12087 +  CK_OBJECT_HANDLE  hKey         /* verification key */
12089 +#endif
12092 +/* C_VerifyRecover verifies a signature in a single-part
12093 + * operation, where the data is recovered from the signature. */
12094 +CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
12095 +#ifdef CK_NEED_ARG_LIST
12097 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
12098 +  CK_BYTE_PTR       pSignature,      /* signature to verify */
12099 +  CK_ULONG          ulSignatureLen,  /* signature length */
12100 +  CK_BYTE_PTR       pData,           /* gets signed data */
12101 +  CK_ULONG_PTR      pulDataLen       /* gets signed data len */
12103 +#endif
12107 +/* Dual-function cryptographic operations */
12109 +/* C_DigestEncryptUpdate continues a multiple-part digesting
12110 + * and encryption operation. */
12111 +CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
12112 +#ifdef CK_NEED_ARG_LIST
12114 +  CK_SESSION_HANDLE hSession,            /* session's handle */
12115 +  CK_BYTE_PTR       pPart,               /* the plaintext data */
12116 +  CK_ULONG          ulPartLen,           /* plaintext length */
12117 +  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
12118 +  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
12120 +#endif
12123 +/* C_DecryptDigestUpdate continues a multiple-part decryption and
12124 + * digesting operation. */
12125 +CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
12126 +#ifdef CK_NEED_ARG_LIST
12128 +  CK_SESSION_HANDLE hSession,            /* session's handle */
12129 +  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
12130 +  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
12131 +  CK_BYTE_PTR       pPart,               /* gets plaintext */
12132 +  CK_ULONG_PTR      pulPartLen           /* gets plaintext len */
12134 +#endif
12137 +/* C_SignEncryptUpdate continues a multiple-part signing and
12138 + * encryption operation. */
12139 +CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
12140 +#ifdef CK_NEED_ARG_LIST
12142 +  CK_SESSION_HANDLE hSession,            /* session's handle */
12143 +  CK_BYTE_PTR       pPart,               /* the plaintext data */
12144 +  CK_ULONG          ulPartLen,           /* plaintext length */
12145 +  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
12146 +  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
12148 +#endif
12151 +/* C_DecryptVerifyUpdate continues a multiple-part decryption and
12152 + * verify operation. */
12153 +CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
12154 +#ifdef CK_NEED_ARG_LIST
12156 +  CK_SESSION_HANDLE hSession,            /* session's handle */
12157 +  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
12158 +  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
12159 +  CK_BYTE_PTR       pPart,               /* gets plaintext */
12160 +  CK_ULONG_PTR      pulPartLen           /* gets p-text length */
12162 +#endif
12166 +/* Key management */
12168 +/* C_GenerateKey generates a secret key, creating a new key
12169 + * object. */
12170 +CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
12171 +#ifdef CK_NEED_ARG_LIST
12173 +  CK_SESSION_HANDLE    hSession,    /* the session's handle */
12174 +  CK_MECHANISM_PTR     pMechanism,  /* key generation mech. */
12175 +  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new key */
12176 +  CK_ULONG             ulCount,     /* # of attrs in template */
12177 +  CK_OBJECT_HANDLE_PTR phKey        /* gets handle of new key */
12179 +#endif
12182 +/* C_GenerateKeyPair generates a public-key/private-key pair, 
12183 + * creating new key objects. */
12184 +CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
12185 +#ifdef CK_NEED_ARG_LIST
12187 +  CK_SESSION_HANDLE    hSession,                    /* session
12188 +                                                     * handle */
12189 +  CK_MECHANISM_PTR     pMechanism,                  /* key-gen
12190 +                                                     * mech. */
12191 +  CK_ATTRIBUTE_PTR     pPublicKeyTemplate,          /* template
12192 +                                                     * for pub.
12193 +                                                     * key */
12194 +  CK_ULONG             ulPublicKeyAttributeCount,   /* # pub.
12195 +                                                     * attrs. */
12196 +  CK_ATTRIBUTE_PTR     pPrivateKeyTemplate,         /* template
12197 +                                                     * for priv.
12198 +                                                     * key */
12199 +  CK_ULONG             ulPrivateKeyAttributeCount,  /* # priv.
12200 +                                                     * attrs. */
12201 +  CK_OBJECT_HANDLE_PTR phPublicKey,                 /* gets pub.
12202 +                                                     * key
12203 +                                                     * handle */
12204 +  CK_OBJECT_HANDLE_PTR phPrivateKey                 /* gets
12205 +                                                     * priv. key
12206 +                                                     * handle */
12208 +#endif
12211 +/* C_WrapKey wraps (i.e., encrypts) a key. */
12212 +CK_PKCS11_FUNCTION_INFO(C_WrapKey)
12213 +#ifdef CK_NEED_ARG_LIST
12215 +  CK_SESSION_HANDLE hSession,        /* the session's handle */
12216 +  CK_MECHANISM_PTR  pMechanism,      /* the wrapping mechanism */
12217 +  CK_OBJECT_HANDLE  hWrappingKey,    /* wrapping key */
12218 +  CK_OBJECT_HANDLE  hKey,            /* key to be wrapped */
12219 +  CK_BYTE_PTR       pWrappedKey,     /* gets wrapped key */
12220 +  CK_ULONG_PTR      pulWrappedKeyLen /* gets wrapped key size */
12222 +#endif
12225 +/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
12226 + * key object. */
12227 +CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
12228 +#ifdef CK_NEED_ARG_LIST
12230 +  CK_SESSION_HANDLE    hSession,          /* session's handle */
12231 +  CK_MECHANISM_PTR     pMechanism,        /* unwrapping mech. */
12232 +  CK_OBJECT_HANDLE     hUnwrappingKey,    /* unwrapping key */
12233 +  CK_BYTE_PTR          pWrappedKey,       /* the wrapped key */
12234 +  CK_ULONG             ulWrappedKeyLen,   /* wrapped key len */
12235 +  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
12236 +  CK_ULONG             ulAttributeCount,  /* template length */
12237 +  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
12239 +#endif
12242 +/* C_DeriveKey derives a key from a base key, creating a new key
12243 + * object. */
12244 +CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
12245 +#ifdef CK_NEED_ARG_LIST
12247 +  CK_SESSION_HANDLE    hSession,          /* session's handle */
12248 +  CK_MECHANISM_PTR     pMechanism,        /* key deriv. mech. */
12249 +  CK_OBJECT_HANDLE     hBaseKey,          /* base key */
12250 +  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
12251 +  CK_ULONG             ulAttributeCount,  /* template length */
12252 +  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
12254 +#endif
12258 +/* Random number generation */
12260 +/* C_SeedRandom mixes additional seed material into the token's
12261 + * random number generator. */
12262 +CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
12263 +#ifdef CK_NEED_ARG_LIST
12265 +  CK_SESSION_HANDLE hSession,  /* the session's handle */
12266 +  CK_BYTE_PTR       pSeed,     /* the seed material */
12267 +  CK_ULONG          ulSeedLen  /* length of seed material */
12269 +#endif
12272 +/* C_GenerateRandom generates random data. */
12273 +CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
12274 +#ifdef CK_NEED_ARG_LIST
12276 +  CK_SESSION_HANDLE hSession,    /* the session's handle */
12277 +  CK_BYTE_PTR       RandomData,  /* receives the random data */
12278 +  CK_ULONG          ulRandomLen  /* # of bytes to generate */
12280 +#endif
12284 +/* Parallel function management */
12286 +/* C_GetFunctionStatus is a legacy function; it obtains an
12287 + * updated status of a function running in parallel with an
12288 + * application. */
12289 +CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
12290 +#ifdef CK_NEED_ARG_LIST
12292 +  CK_SESSION_HANDLE hSession  /* the session's handle */
12294 +#endif
12297 +/* C_CancelFunction is a legacy function; it cancels a function
12298 + * running in parallel. */
12299 +CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
12300 +#ifdef CK_NEED_ARG_LIST
12302 +  CK_SESSION_HANDLE hSession  /* the session's handle */
12304 +#endif
12308 +/* Functions added in for Cryptoki Version 2.01 or later */
12310 +/* C_WaitForSlotEvent waits for a slot event (token insertion,
12311 + * removal, etc.) to occur. */
12312 +CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
12313 +#ifdef CK_NEED_ARG_LIST
12315 +  CK_FLAGS flags,        /* blocking/nonblocking flag */
12316 +  CK_SLOT_ID_PTR pSlot,  /* location that receives the slot ID */
12317 +  CK_VOID_PTR pRserved   /* reserved.  Should be NULL_PTR */
12319 +#endif
12320 Index: openssl/crypto/engine/pkcs11t.h
12321 diff -u /dev/null openssl/crypto/engine/pkcs11t.h:1.2
12322 --- /dev/null   Mon Oct  5 13:17:24 2009
12323 +++ openssl/crypto/engine/pkcs11t.h     Sat Aug 30 11:58:07 2008
12324 @@ -0,0 +1,1885 @@
12325 +/* pkcs11t.h include file for PKCS #11. */
12326 +/* Revision: 1.1 */
12328 +/* License to copy and use this software is granted provided that it is
12329 + * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
12330 + * (Cryptoki)" in all material mentioning or referencing this software.
12332 + * License is also granted to make and use derivative works provided that
12333 + * such works are identified as "derived from the RSA Security Inc. PKCS #11
12334 + * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
12335 + * referencing the derived work.
12337 + * RSA Security Inc. makes no representations concerning either the
12338 + * merchantability of this software or the suitability of this software for
12339 + * any particular purpose. It is provided "as is" without express or implied
12340 + * warranty of any kind.
12341 + */
12343 +/* See top of pkcs11.h for information about the macros that
12344 + * must be defined and the structure-packing conventions that
12345 + * must be set before including this file. */
12347 +#ifndef _PKCS11T_H_
12348 +#define _PKCS11T_H_ 1
12350 +#define CRYPTOKI_VERSION_MAJOR 2
12351 +#define CRYPTOKI_VERSION_MINOR 20
12352 +#define CRYPTOKI_VERSION_AMENDMENT 3
12354 +#define CK_TRUE 1
12355 +#define CK_FALSE 0
12357 +#ifndef CK_DISABLE_TRUE_FALSE
12358 +#ifndef FALSE
12359 +#define FALSE CK_FALSE
12360 +#endif
12362 +#ifndef TRUE
12363 +#define TRUE CK_TRUE
12364 +#endif
12365 +#endif
12367 +/* an unsigned 8-bit value */
12368 +typedef unsigned char     CK_BYTE;
12370 +/* an unsigned 8-bit character */
12371 +typedef CK_BYTE           CK_CHAR;
12373 +/* an 8-bit UTF-8 character */
12374 +typedef CK_BYTE           CK_UTF8CHAR;
12376 +/* a BYTE-sized Boolean flag */
12377 +typedef CK_BYTE           CK_BBOOL;
12379 +/* an unsigned value, at least 32 bits long */
12380 +typedef unsigned long int CK_ULONG;
12382 +/* a signed value, the same size as a CK_ULONG */
12383 +/* CK_LONG is new for v2.0 */
12384 +typedef long int          CK_LONG;
12386 +/* at least 32 bits; each bit is a Boolean flag */
12387 +typedef CK_ULONG          CK_FLAGS;
12390 +/* some special values for certain CK_ULONG variables */
12391 +#define CK_UNAVAILABLE_INFORMATION (~0UL)
12392 +#define CK_EFFECTIVELY_INFINITE    0
12395 +typedef CK_BYTE     CK_PTR   CK_BYTE_PTR;
12396 +typedef CK_CHAR     CK_PTR   CK_CHAR_PTR;
12397 +typedef CK_UTF8CHAR CK_PTR   CK_UTF8CHAR_PTR;
12398 +typedef CK_ULONG    CK_PTR   CK_ULONG_PTR;
12399 +typedef void        CK_PTR   CK_VOID_PTR;
12401 +/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
12402 +typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
12405 +/* The following value is always invalid if used as a session */
12406 +/* handle or object handle */
12407 +#define CK_INVALID_HANDLE 0
12410 +typedef struct CK_VERSION {
12411 +  CK_BYTE       major;  /* integer portion of version number */
12412 +  CK_BYTE       minor;  /* 1/100ths portion of version number */
12413 +} CK_VERSION;
12415 +typedef CK_VERSION CK_PTR CK_VERSION_PTR;
12418 +typedef struct CK_INFO {
12419 +  /* manufacturerID and libraryDecription have been changed from
12420 +   * CK_CHAR to CK_UTF8CHAR for v2.10 */
12421 +  CK_VERSION    cryptokiVersion;     /* Cryptoki interface ver */
12422 +  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
12423 +  CK_FLAGS      flags;               /* must be zero */
12425 +  /* libraryDescription and libraryVersion are new for v2.0 */
12426 +  CK_UTF8CHAR   libraryDescription[32];  /* blank padded */
12427 +  CK_VERSION    libraryVersion;          /* version of library */
12428 +} CK_INFO;
12430 +typedef CK_INFO CK_PTR    CK_INFO_PTR;
12433 +/* CK_NOTIFICATION enumerates the types of notifications that
12434 + * Cryptoki provides to an application */
12435 +/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
12436 + * for v2.0 */
12437 +typedef CK_ULONG CK_NOTIFICATION;
12438 +#define CKN_SURRENDER       0
12440 +/* The following notification is new for PKCS #11 v2.20 amendment 3 */
12441 +#define CKN_OTP_CHANGED     1
12444 +typedef CK_ULONG          CK_SLOT_ID;
12446 +typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
12449 +/* CK_SLOT_INFO provides information about a slot */
12450 +typedef struct CK_SLOT_INFO {
12451 +  /* slotDescription and manufacturerID have been changed from
12452 +   * CK_CHAR to CK_UTF8CHAR for v2.10 */
12453 +  CK_UTF8CHAR   slotDescription[64];  /* blank padded */
12454 +  CK_UTF8CHAR   manufacturerID[32];   /* blank padded */
12455 +  CK_FLAGS      flags;
12457 +  /* hardwareVersion and firmwareVersion are new for v2.0 */
12458 +  CK_VERSION    hardwareVersion;  /* version of hardware */
12459 +  CK_VERSION    firmwareVersion;  /* version of firmware */
12460 +} CK_SLOT_INFO;
12462 +/* flags: bit flags that provide capabilities of the slot
12463 + *      Bit Flag              Mask        Meaning
12464 + */
12465 +#define CKF_TOKEN_PRESENT     0x00000001  /* a token is there */
12466 +#define CKF_REMOVABLE_DEVICE  0x00000002  /* removable devices*/
12467 +#define CKF_HW_SLOT           0x00000004  /* hardware slot */
12469 +typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
12472 +/* CK_TOKEN_INFO provides information about a token */
12473 +typedef struct CK_TOKEN_INFO {
12474 +  /* label, manufacturerID, and model have been changed from
12475 +   * CK_CHAR to CK_UTF8CHAR for v2.10 */
12476 +  CK_UTF8CHAR   label[32];           /* blank padded */
12477 +  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
12478 +  CK_UTF8CHAR   model[16];           /* blank padded */
12479 +  CK_CHAR       serialNumber[16];    /* blank padded */
12480 +  CK_FLAGS      flags;               /* see below */
12482 +  /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
12483 +   * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
12484 +   * changed from CK_USHORT to CK_ULONG for v2.0 */
12485 +  CK_ULONG      ulMaxSessionCount;     /* max open sessions */
12486 +  CK_ULONG      ulSessionCount;        /* sess. now open */
12487 +  CK_ULONG      ulMaxRwSessionCount;   /* max R/W sessions */
12488 +  CK_ULONG      ulRwSessionCount;      /* R/W sess. now open */
12489 +  CK_ULONG      ulMaxPinLen;           /* in bytes */
12490 +  CK_ULONG      ulMinPinLen;           /* in bytes */
12491 +  CK_ULONG      ulTotalPublicMemory;   /* in bytes */
12492 +  CK_ULONG      ulFreePublicMemory;    /* in bytes */
12493 +  CK_ULONG      ulTotalPrivateMemory;  /* in bytes */
12494 +  CK_ULONG      ulFreePrivateMemory;   /* in bytes */
12496 +  /* hardwareVersion, firmwareVersion, and time are new for
12497 +   * v2.0 */
12498 +  CK_VERSION    hardwareVersion;       /* version of hardware */
12499 +  CK_VERSION    firmwareVersion;       /* version of firmware */
12500 +  CK_CHAR       utcTime[16];           /* time */
12501 +} CK_TOKEN_INFO;
12503 +/* The flags parameter is defined as follows:
12504 + *      Bit Flag                    Mask        Meaning
12505 + */
12506 +#define CKF_RNG                     0x00000001  /* has random #
12507 +                                                 * generator */
12508 +#define CKF_WRITE_PROTECTED         0x00000002  /* token is
12509 +                                                 * write-
12510 +                                                 * protected */
12511 +#define CKF_LOGIN_REQUIRED          0x00000004  /* user must
12512 +                                                 * login */
12513 +#define CKF_USER_PIN_INITIALIZED    0x00000008  /* normal user's
12514 +                                                 * PIN is set */
12516 +/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0.  If it is set,
12517 + * that means that *every* time the state of cryptographic
12518 + * operations of a session is successfully saved, all keys
12519 + * needed to continue those operations are stored in the state */
12520 +#define CKF_RESTORE_KEY_NOT_NEEDED  0x00000020
12522 +/* CKF_CLOCK_ON_TOKEN is new for v2.0.  If it is set, that means
12523 + * that the token has some sort of clock.  The time on that
12524 + * clock is returned in the token info structure */
12525 +#define CKF_CLOCK_ON_TOKEN          0x00000040
12527 +/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0.  If it is
12528 + * set, that means that there is some way for the user to login
12529 + * without sending a PIN through the Cryptoki library itself */
12530 +#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
12532 +/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0.  If it is true,
12533 + * that means that a single session with the token can perform
12534 + * dual simultaneous cryptographic operations (digest and
12535 + * encrypt; decrypt and digest; sign and encrypt; and decrypt
12536 + * and sign) */
12537 +#define CKF_DUAL_CRYPTO_OPERATIONS  0x00000200
12539 +/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
12540 + * token has been initialized using C_InitializeToken or an
12541 + * equivalent mechanism outside the scope of PKCS #11.
12542 + * Calling C_InitializeToken when this flag is set will cause
12543 + * the token to be reinitialized. */
12544 +#define CKF_TOKEN_INITIALIZED       0x00000400
12546 +/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
12547 + * true, the token supports secondary authentication for
12548 + * private key objects. This flag is deprecated in v2.11 and
12549 +   onwards. */
12550 +#define CKF_SECONDARY_AUTHENTICATION  0x00000800
12552 +/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
12553 + * incorrect user login PIN has been entered at least once
12554 + * since the last successful authentication. */
12555 +#define CKF_USER_PIN_COUNT_LOW       0x00010000
12557 +/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
12558 + * supplying an incorrect user PIN will it to become locked. */
12559 +#define CKF_USER_PIN_FINAL_TRY       0x00020000
12561 +/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
12562 + * user PIN has been locked. User login to the token is not
12563 + * possible. */
12564 +#define CKF_USER_PIN_LOCKED          0x00040000
12566 +/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
12567 + * the user PIN value is the default value set by token
12568 + * initialization or manufacturing, or the PIN has been
12569 + * expired by the card. */
12570 +#define CKF_USER_PIN_TO_BE_CHANGED   0x00080000
12572 +/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
12573 + * incorrect SO login PIN has been entered at least once since
12574 + * the last successful authentication. */
12575 +#define CKF_SO_PIN_COUNT_LOW         0x00100000
12577 +/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
12578 + * supplying an incorrect SO PIN will it to become locked. */
12579 +#define CKF_SO_PIN_FINAL_TRY         0x00200000
12581 +/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
12582 + * PIN has been locked. SO login to the token is not possible.
12583 + */
12584 +#define CKF_SO_PIN_LOCKED            0x00400000
12586 +/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
12587 + * the SO PIN value is the default value set by token
12588 + * initialization or manufacturing, or the PIN has been
12589 + * expired by the card. */
12590 +#define CKF_SO_PIN_TO_BE_CHANGED     0x00800000
12592 +typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
12595 +/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
12596 + * identifies a session */
12597 +typedef CK_ULONG          CK_SESSION_HANDLE;
12599 +typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
12602 +/* CK_USER_TYPE enumerates the types of Cryptoki users */
12603 +/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
12604 + * v2.0 */
12605 +typedef CK_ULONG          CK_USER_TYPE;
12606 +/* Security Officer */
12607 +#define CKU_SO    0
12608 +/* Normal user */
12609 +#define CKU_USER  1
12610 +/* Context specific (added in v2.20) */
12611 +#define CKU_CONTEXT_SPECIFIC   2
12613 +/* CK_STATE enumerates the session states */
12614 +/* CK_STATE has been changed from an enum to a CK_ULONG for
12615 + * v2.0 */
12616 +typedef CK_ULONG          CK_STATE;
12617 +#define CKS_RO_PUBLIC_SESSION  0
12618 +#define CKS_RO_USER_FUNCTIONS  1
12619 +#define CKS_RW_PUBLIC_SESSION  2
12620 +#define CKS_RW_USER_FUNCTIONS  3
12621 +#define CKS_RW_SO_FUNCTIONS    4
12624 +/* CK_SESSION_INFO provides information about a session */
12625 +typedef struct CK_SESSION_INFO {
12626 +  CK_SLOT_ID    slotID;
12627 +  CK_STATE      state;
12628 +  CK_FLAGS      flags;          /* see below */
12630 +  /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
12631 +   * v2.0 */
12632 +  CK_ULONG      ulDeviceError;  /* device-dependent error code */
12633 +} CK_SESSION_INFO;
12635 +/* The flags are defined in the following table:
12636 + *      Bit Flag                Mask        Meaning
12637 + */
12638 +#define CKF_RW_SESSION          0x00000002  /* session is r/w */
12639 +#define CKF_SERIAL_SESSION      0x00000004  /* no parallel */
12641 +typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
12644 +/* CK_OBJECT_HANDLE is a token-specific identifier for an
12645 + * object  */
12646 +typedef CK_ULONG          CK_OBJECT_HANDLE;
12648 +typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
12651 +/* CK_OBJECT_CLASS is a value that identifies the classes (or
12652 + * types) of objects that Cryptoki recognizes.  It is defined
12653 + * as follows: */
12654 +/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
12655 + * v2.0 */
12656 +typedef CK_ULONG          CK_OBJECT_CLASS;
12658 +/* The following classes of objects are defined: */
12659 +/* CKO_HW_FEATURE is new for v2.10 */
12660 +/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
12661 +/* CKO_MECHANISM is new for v2.20 */
12662 +#define CKO_DATA              0x00000000
12663 +#define CKO_CERTIFICATE       0x00000001
12664 +#define CKO_PUBLIC_KEY        0x00000002
12665 +#define CKO_PRIVATE_KEY       0x00000003
12666 +#define CKO_SECRET_KEY        0x00000004
12667 +#define CKO_HW_FEATURE        0x00000005
12668 +#define CKO_DOMAIN_PARAMETERS 0x00000006
12669 +#define CKO_MECHANISM         0x00000007
12671 +/* CKO_OTP_KEY is new for PKCS #11 v2.20 amendment 1 */
12672 +#define CKO_OTP_KEY           0x00000008
12674 +#define CKO_VENDOR_DEFINED    0x80000000
12676 +typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
12678 +/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
12679 + * value that identifies the hardware feature type of an object
12680 + * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
12681 +typedef CK_ULONG          CK_HW_FEATURE_TYPE;
12683 +/* The following hardware feature types are defined */
12684 +/* CKH_USER_INTERFACE is new for v2.20 */
12685 +#define CKH_MONOTONIC_COUNTER  0x00000001
12686 +#define CKH_CLOCK           0x00000002
12687 +#define CKH_USER_INTERFACE  0x00000003
12688 +#define CKH_VENDOR_DEFINED  0x80000000
12690 +/* CK_KEY_TYPE is a value that identifies a key type */
12691 +/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
12692 +typedef CK_ULONG          CK_KEY_TYPE;
12694 +/* the following key types are defined: */
12695 +#define CKK_RSA             0x00000000
12696 +#define CKK_DSA             0x00000001
12697 +#define CKK_DH              0x00000002
12699 +/* CKK_ECDSA and CKK_KEA are new for v2.0 */
12700 +/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
12701 +#define CKK_ECDSA           0x00000003
12702 +#define CKK_EC              0x00000003
12703 +#define CKK_X9_42_DH        0x00000004
12704 +#define CKK_KEA             0x00000005
12706 +#define CKK_GENERIC_SECRET  0x00000010
12707 +#define CKK_RC2             0x00000011
12708 +#define CKK_RC4             0x00000012
12709 +#define CKK_DES             0x00000013
12710 +#define CKK_DES2            0x00000014
12711 +#define CKK_DES3            0x00000015
12713 +/* all these key types are new for v2.0 */
12714 +#define CKK_CAST            0x00000016
12715 +#define CKK_CAST3           0x00000017
12716 +/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
12717 +#define CKK_CAST5           0x00000018
12718 +#define CKK_CAST128         0x00000018
12719 +#define CKK_RC5             0x00000019
12720 +#define CKK_IDEA            0x0000001A
12721 +#define CKK_SKIPJACK        0x0000001B
12722 +#define CKK_BATON           0x0000001C
12723 +#define CKK_JUNIPER         0x0000001D
12724 +#define CKK_CDMF            0x0000001E
12725 +#define CKK_AES             0x0000001F
12727 +/* BlowFish and TwoFish are new for v2.20 */
12728 +#define CKK_BLOWFISH        0x00000020
12729 +#define CKK_TWOFISH         0x00000021
12731 +/* SecurID, HOTP, and ACTI are new for PKCS #11 v2.20 amendment 1 */
12732 +#define CKK_SECURID         0x00000022
12733 +#define CKK_HOTP            0x00000023
12734 +#define CKK_ACTI            0x00000024
12736 +/* Camellia is new for PKCS #11 v2.20 amendment 3 */
12737 +#define CKK_CAMELLIA                   0x00000025
12738 +/* ARIA is new for PKCS #11 v2.20 amendment 3 */
12739 +#define CKK_ARIA                       0x00000026
12742 +#define CKK_VENDOR_DEFINED  0x80000000
12745 +/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
12746 + * type */
12747 +/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
12748 + * for v2.0 */
12749 +typedef CK_ULONG          CK_CERTIFICATE_TYPE;
12751 +/* The following certificate types are defined: */
12752 +/* CKC_X_509_ATTR_CERT is new for v2.10 */
12753 +/* CKC_WTLS is new for v2.20 */
12754 +#define CKC_X_509           0x00000000
12755 +#define CKC_X_509_ATTR_CERT 0x00000001
12756 +#define CKC_WTLS            0x00000002
12757 +#define CKC_VENDOR_DEFINED  0x80000000
12760 +/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
12761 + * type */
12762 +/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
12763 + * v2.0 */
12764 +typedef CK_ULONG          CK_ATTRIBUTE_TYPE;
12766 +/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
12767 +   consists of an array of values. */
12768 +#define CKF_ARRAY_ATTRIBUTE    0x40000000
12770 +/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1
12771 +   and relates to the CKA_OTP_FORMAT attribute */
12772 +#define CK_OTP_FORMAT_DECIMAL      0
12773 +#define CK_OTP_FORMAT_HEXADECIMAL  1
12774 +#define CK_OTP_FORMAT_ALPHANUMERIC 2
12775 +#define CK_OTP_FORMAT_BINARY       3
12777 +/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1
12778 +   and relates to the CKA_OTP_..._REQUIREMENT attributes */
12779 +#define CK_OTP_PARAM_IGNORED       0
12780 +#define CK_OTP_PARAM_OPTIONAL      1
12781 +#define CK_OTP_PARAM_MANDATORY     2
12783 +/* The following attribute types are defined: */
12784 +#define CKA_CLASS              0x00000000
12785 +#define CKA_TOKEN              0x00000001
12786 +#define CKA_PRIVATE            0x00000002
12787 +#define CKA_LABEL              0x00000003
12788 +#define CKA_APPLICATION        0x00000010
12789 +#define CKA_VALUE              0x00000011
12791 +/* CKA_OBJECT_ID is new for v2.10 */
12792 +#define CKA_OBJECT_ID          0x00000012
12794 +#define CKA_CERTIFICATE_TYPE   0x00000080
12795 +#define CKA_ISSUER             0x00000081
12796 +#define CKA_SERIAL_NUMBER      0x00000082
12798 +/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
12799 + * for v2.10 */
12800 +#define CKA_AC_ISSUER          0x00000083
12801 +#define CKA_OWNER              0x00000084
12802 +#define CKA_ATTR_TYPES         0x00000085
12804 +/* CKA_TRUSTED is new for v2.11 */
12805 +#define CKA_TRUSTED            0x00000086
12807 +/* CKA_CERTIFICATE_CATEGORY ...
12808 + * CKA_CHECK_VALUE are new for v2.20 */
12809 +#define CKA_CERTIFICATE_CATEGORY        0x00000087
12810 +#define CKA_JAVA_MIDP_SECURITY_DOMAIN   0x00000088
12811 +#define CKA_URL                         0x00000089
12812 +#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY  0x0000008A
12813 +#define CKA_HASH_OF_ISSUER_PUBLIC_KEY   0x0000008B
12814 +#define CKA_CHECK_VALUE                 0x00000090
12816 +#define CKA_KEY_TYPE           0x00000100
12817 +#define CKA_SUBJECT            0x00000101
12818 +#define CKA_ID                 0x00000102
12819 +#define CKA_SENSITIVE          0x00000103
12820 +#define CKA_ENCRYPT            0x00000104
12821 +#define CKA_DECRYPT            0x00000105
12822 +#define CKA_WRAP               0x00000106
12823 +#define CKA_UNWRAP             0x00000107
12824 +#define CKA_SIGN               0x00000108
12825 +#define CKA_SIGN_RECOVER       0x00000109
12826 +#define CKA_VERIFY             0x0000010A
12827 +#define CKA_VERIFY_RECOVER     0x0000010B
12828 +#define CKA_DERIVE             0x0000010C
12829 +#define CKA_START_DATE         0x00000110
12830 +#define CKA_END_DATE           0x00000111
12831 +#define CKA_MODULUS            0x00000120
12832 +#define CKA_MODULUS_BITS       0x00000121
12833 +#define CKA_PUBLIC_EXPONENT    0x00000122
12834 +#define CKA_PRIVATE_EXPONENT   0x00000123
12835 +#define CKA_PRIME_1            0x00000124
12836 +#define CKA_PRIME_2            0x00000125
12837 +#define CKA_EXPONENT_1         0x00000126
12838 +#define CKA_EXPONENT_2         0x00000127
12839 +#define CKA_COEFFICIENT        0x00000128
12840 +#define CKA_PRIME              0x00000130
12841 +#define CKA_SUBPRIME           0x00000131
12842 +#define CKA_BASE               0x00000132
12844 +/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
12845 +#define CKA_PRIME_BITS         0x00000133
12846 +#define CKA_SUBPRIME_BITS      0x00000134
12847 +#define CKA_SUB_PRIME_BITS     CKA_SUBPRIME_BITS
12848 +/* (To retain backwards-compatibility) */
12850 +#define CKA_VALUE_BITS         0x00000160
12851 +#define CKA_VALUE_LEN          0x00000161
12853 +/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
12854 + * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
12855 + * and CKA_EC_POINT are new for v2.0 */
12856 +#define CKA_EXTRACTABLE        0x00000162
12857 +#define CKA_LOCAL              0x00000163
12858 +#define CKA_NEVER_EXTRACTABLE  0x00000164
12859 +#define CKA_ALWAYS_SENSITIVE   0x00000165
12861 +/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
12862 +#define CKA_KEY_GEN_MECHANISM  0x00000166
12864 +#define CKA_MODIFIABLE         0x00000170
12866 +/* CKA_ECDSA_PARAMS is deprecated in v2.11,
12867 + * CKA_EC_PARAMS is preferred. */
12868 +#define CKA_ECDSA_PARAMS       0x00000180
12869 +#define CKA_EC_PARAMS          0x00000180
12871 +#define CKA_EC_POINT           0x00000181
12873 +/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
12874 + * are new for v2.10. Deprecated in v2.11 and onwards. */
12875 +#define CKA_SECONDARY_AUTH     0x00000200
12876 +#define CKA_AUTH_PIN_FLAGS     0x00000201
12878 +/* CKA_ALWAYS_AUTHENTICATE ...
12879 + * CKA_UNWRAP_TEMPLATE are new for v2.20 */
12880 +#define CKA_ALWAYS_AUTHENTICATE  0x00000202
12882 +#define CKA_WRAP_WITH_TRUSTED    0x00000210
12883 +#define CKA_WRAP_TEMPLATE        (CKF_ARRAY_ATTRIBUTE|0x00000211)
12884 +#define CKA_UNWRAP_TEMPLATE      (CKF_ARRAY_ATTRIBUTE|0x00000212)
12886 +/* CKA_OTP... atttributes are new for PKCS #11 v2.20 amendment 3. */
12887 +#define CKA_OTP_FORMAT                0x00000220
12888 +#define CKA_OTP_LENGTH                0x00000221
12889 +#define CKA_OTP_TIME_INTERVAL         0x00000222
12890 +#define CKA_OTP_USER_FRIENDLY_MODE    0x00000223
12891 +#define CKA_OTP_CHALLENGE_REQUIREMENT 0x00000224
12892 +#define CKA_OTP_TIME_REQUIREMENT      0x00000225
12893 +#define CKA_OTP_COUNTER_REQUIREMENT   0x00000226
12894 +#define CKA_OTP_PIN_REQUIREMENT       0x00000227
12895 +#define CKA_OTP_COUNTER               0x0000022E
12896 +#define CKA_OTP_TIME                  0x0000022F
12897 +#define CKA_OTP_USER_IDENTIFIER       0x0000022A
12898 +#define CKA_OTP_SERVICE_IDENTIFIER    0x0000022B
12899 +#define CKA_OTP_SERVICE_LOGO          0x0000022C
12900 +#define CKA_OTP_SERVICE_LOGO_TYPE     0x0000022D
12903 +/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
12904 + * are new for v2.10 */
12905 +#define CKA_HW_FEATURE_TYPE    0x00000300
12906 +#define CKA_RESET_ON_INIT      0x00000301
12907 +#define CKA_HAS_RESET          0x00000302
12909 +/* The following attributes are new for v2.20 */
12910 +#define CKA_PIXEL_X                     0x00000400
12911 +#define CKA_PIXEL_Y                     0x00000401
12912 +#define CKA_RESOLUTION                  0x00000402
12913 +#define CKA_CHAR_ROWS                   0x00000403
12914 +#define CKA_CHAR_COLUMNS                0x00000404
12915 +#define CKA_COLOR                       0x00000405
12916 +#define CKA_BITS_PER_PIXEL              0x00000406
12917 +#define CKA_CHAR_SETS                   0x00000480
12918 +#define CKA_ENCODING_METHODS            0x00000481
12919 +#define CKA_MIME_TYPES                  0x00000482
12920 +#define CKA_MECHANISM_TYPE              0x00000500
12921 +#define CKA_REQUIRED_CMS_ATTRIBUTES     0x00000501
12922 +#define CKA_DEFAULT_CMS_ATTRIBUTES      0x00000502
12923 +#define CKA_SUPPORTED_CMS_ATTRIBUTES    0x00000503
12924 +#define CKA_ALLOWED_MECHANISMS          (CKF_ARRAY_ATTRIBUTE|0x00000600)
12926 +#define CKA_VENDOR_DEFINED     0x80000000
12928 +/* CK_ATTRIBUTE is a structure that includes the type, length
12929 + * and value of an attribute */
12930 +typedef struct CK_ATTRIBUTE {
12931 +  CK_ATTRIBUTE_TYPE type;
12932 +  CK_VOID_PTR       pValue;
12934 +  /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
12935 +  CK_ULONG          ulValueLen;  /* in bytes */
12936 +} CK_ATTRIBUTE;
12938 +typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
12941 +/* CK_DATE is a structure that defines a date */
12942 +typedef struct CK_DATE{
12943 +  CK_CHAR       year[4];   /* the year ("1900" - "9999") */
12944 +  CK_CHAR       month[2];  /* the month ("01" - "12") */
12945 +  CK_CHAR       day[2];    /* the day   ("01" - "31") */
12946 +} CK_DATE;
12949 +/* CK_MECHANISM_TYPE is a value that identifies a mechanism
12950 + * type */
12951 +/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
12952 + * v2.0 */
12953 +typedef CK_ULONG          CK_MECHANISM_TYPE;
12955 +/* the following mechanism types are defined: */
12956 +#define CKM_RSA_PKCS_KEY_PAIR_GEN      0x00000000
12957 +#define CKM_RSA_PKCS                   0x00000001
12958 +#define CKM_RSA_9796                   0x00000002
12959 +#define CKM_RSA_X_509                  0x00000003
12961 +/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
12962 + * are new for v2.0.  They are mechanisms which hash and sign */
12963 +#define CKM_MD2_RSA_PKCS               0x00000004
12964 +#define CKM_MD5_RSA_PKCS               0x00000005
12965 +#define CKM_SHA1_RSA_PKCS              0x00000006
12967 +/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
12968 + * CKM_RSA_PKCS_OAEP are new for v2.10 */
12969 +#define CKM_RIPEMD128_RSA_PKCS         0x00000007
12970 +#define CKM_RIPEMD160_RSA_PKCS         0x00000008
12971 +#define CKM_RSA_PKCS_OAEP              0x00000009
12973 +/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
12974 + * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
12975 +#define CKM_RSA_X9_31_KEY_PAIR_GEN     0x0000000A
12976 +#define CKM_RSA_X9_31                  0x0000000B
12977 +#define CKM_SHA1_RSA_X9_31             0x0000000C
12978 +#define CKM_RSA_PKCS_PSS               0x0000000D
12979 +#define CKM_SHA1_RSA_PKCS_PSS          0x0000000E
12981 +#define CKM_DSA_KEY_PAIR_GEN           0x00000010
12982 +#define CKM_DSA                        0x00000011
12983 +#define CKM_DSA_SHA1                   0x00000012
12984 +#define CKM_DH_PKCS_KEY_PAIR_GEN       0x00000020
12985 +#define CKM_DH_PKCS_DERIVE             0x00000021
12987 +/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
12988 + * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
12989 + * v2.11 */
12990 +#define CKM_X9_42_DH_KEY_PAIR_GEN      0x00000030
12991 +#define CKM_X9_42_DH_DERIVE            0x00000031
12992 +#define CKM_X9_42_DH_HYBRID_DERIVE     0x00000032
12993 +#define CKM_X9_42_MQV_DERIVE           0x00000033
12995 +/* CKM_SHA256/384/512 are new for v2.20 */
12996 +#define CKM_SHA256_RSA_PKCS            0x00000040
12997 +#define CKM_SHA384_RSA_PKCS            0x00000041
12998 +#define CKM_SHA512_RSA_PKCS            0x00000042
12999 +#define CKM_SHA256_RSA_PKCS_PSS        0x00000043
13000 +#define CKM_SHA384_RSA_PKCS_PSS        0x00000044
13001 +#define CKM_SHA512_RSA_PKCS_PSS        0x00000045
13003 +/* SHA-224 RSA mechanisms are new for PKCS #11 v2.20 amendment 3 */
13004 +#define CKM_SHA224_RSA_PKCS            0x00000046
13005 +#define CKM_SHA224_RSA_PKCS_PSS        0x00000047
13007 +#define CKM_RC2_KEY_GEN                0x00000100
13008 +#define CKM_RC2_ECB                    0x00000101
13009 +#define CKM_RC2_CBC                    0x00000102
13010 +#define CKM_RC2_MAC                    0x00000103
13012 +/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
13013 +#define CKM_RC2_MAC_GENERAL            0x00000104
13014 +#define CKM_RC2_CBC_PAD                0x00000105
13016 +#define CKM_RC4_KEY_GEN                0x00000110
13017 +#define CKM_RC4                        0x00000111
13018 +#define CKM_DES_KEY_GEN                0x00000120
13019 +#define CKM_DES_ECB                    0x00000121
13020 +#define CKM_DES_CBC                    0x00000122
13021 +#define CKM_DES_MAC                    0x00000123
13023 +/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
13024 +#define CKM_DES_MAC_GENERAL            0x00000124
13025 +#define CKM_DES_CBC_PAD                0x00000125
13027 +#define CKM_DES2_KEY_GEN               0x00000130
13028 +#define CKM_DES3_KEY_GEN               0x00000131
13029 +#define CKM_DES3_ECB                   0x00000132
13030 +#define CKM_DES3_CBC                   0x00000133
13031 +#define CKM_DES3_MAC                   0x00000134
13033 +/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
13034 + * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
13035 + * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
13036 +#define CKM_DES3_MAC_GENERAL           0x00000135
13037 +#define CKM_DES3_CBC_PAD               0x00000136
13038 +#define CKM_CDMF_KEY_GEN               0x00000140
13039 +#define CKM_CDMF_ECB                   0x00000141
13040 +#define CKM_CDMF_CBC                   0x00000142
13041 +#define CKM_CDMF_MAC                   0x00000143
13042 +#define CKM_CDMF_MAC_GENERAL           0x00000144
13043 +#define CKM_CDMF_CBC_PAD               0x00000145
13045 +/* the following four DES mechanisms are new for v2.20 */
13046 +#define CKM_DES_OFB64                  0x00000150
13047 +#define CKM_DES_OFB8                   0x00000151
13048 +#define CKM_DES_CFB64                  0x00000152
13049 +#define CKM_DES_CFB8                   0x00000153
13051 +#define CKM_MD2                        0x00000200
13053 +/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
13054 +#define CKM_MD2_HMAC                   0x00000201
13055 +#define CKM_MD2_HMAC_GENERAL           0x00000202
13057 +#define CKM_MD5                        0x00000210
13059 +/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
13060 +#define CKM_MD5_HMAC                   0x00000211
13061 +#define CKM_MD5_HMAC_GENERAL           0x00000212
13063 +#define CKM_SHA_1                      0x00000220
13065 +/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
13066 +#define CKM_SHA_1_HMAC                 0x00000221
13067 +#define CKM_SHA_1_HMAC_GENERAL         0x00000222
13069 +/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
13070 + * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
13071 + * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
13072 +#define CKM_RIPEMD128                  0x00000230
13073 +#define CKM_RIPEMD128_HMAC             0x00000231
13074 +#define CKM_RIPEMD128_HMAC_GENERAL     0x00000232
13075 +#define CKM_RIPEMD160                  0x00000240
13076 +#define CKM_RIPEMD160_HMAC             0x00000241
13077 +#define CKM_RIPEMD160_HMAC_GENERAL     0x00000242
13079 +/* CKM_SHA256/384/512 are new for v2.20 */
13080 +#define CKM_SHA256                     0x00000250
13081 +#define CKM_SHA256_HMAC                0x00000251
13082 +#define CKM_SHA256_HMAC_GENERAL        0x00000252
13084 +/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
13085 +#define CKM_SHA224                     0x00000255
13086 +#define CKM_SHA224_HMAC                0x00000256
13087 +#define CKM_SHA224_HMAC_GENERAL        0x00000257
13089 +#define CKM_SHA384                     0x00000260
13090 +#define CKM_SHA384_HMAC                0x00000261
13091 +#define CKM_SHA384_HMAC_GENERAL        0x00000262
13092 +#define CKM_SHA512                     0x00000270
13093 +#define CKM_SHA512_HMAC                0x00000271
13094 +#define CKM_SHA512_HMAC_GENERAL        0x00000272
13096 +/* SecurID is new for PKCS #11 v2.20 amendment 1 */
13097 +#define CKM_SECURID_KEY_GEN            0x00000280
13098 +#define CKM_SECURID                    0x00000282
13100 +/* HOTP is new for PKCS #11 v2.20 amendment 1 */
13101 +#define CKM_HOTP_KEY_GEN    0x00000290
13102 +#define CKM_HOTP            0x00000291
13104 +/* ACTI is new for PKCS #11 v2.20 amendment 1 */
13105 +#define CKM_ACTI            0x000002A0
13106 +#define CKM_ACTI_KEY_GEN    0x000002A1
13108 +/* All of the following mechanisms are new for v2.0 */
13109 +/* Note that CAST128 and CAST5 are the same algorithm */
13110 +#define CKM_CAST_KEY_GEN               0x00000300
13111 +#define CKM_CAST_ECB                   0x00000301
13112 +#define CKM_CAST_CBC                   0x00000302
13113 +#define CKM_CAST_MAC                   0x00000303
13114 +#define CKM_CAST_MAC_GENERAL           0x00000304
13115 +#define CKM_CAST_CBC_PAD               0x00000305
13116 +#define CKM_CAST3_KEY_GEN              0x00000310
13117 +#define CKM_CAST3_ECB                  0x00000311
13118 +#define CKM_CAST3_CBC                  0x00000312
13119 +#define CKM_CAST3_MAC                  0x00000313
13120 +#define CKM_CAST3_MAC_GENERAL          0x00000314
13121 +#define CKM_CAST3_CBC_PAD              0x00000315
13122 +#define CKM_CAST5_KEY_GEN              0x00000320
13123 +#define CKM_CAST128_KEY_GEN            0x00000320
13124 +#define CKM_CAST5_ECB                  0x00000321
13125 +#define CKM_CAST128_ECB                0x00000321
13126 +#define CKM_CAST5_CBC                  0x00000322
13127 +#define CKM_CAST128_CBC                0x00000322
13128 +#define CKM_CAST5_MAC                  0x00000323
13129 +#define CKM_CAST128_MAC                0x00000323
13130 +#define CKM_CAST5_MAC_GENERAL          0x00000324
13131 +#define CKM_CAST128_MAC_GENERAL        0x00000324
13132 +#define CKM_CAST5_CBC_PAD              0x00000325
13133 +#define CKM_CAST128_CBC_PAD            0x00000325
13134 +#define CKM_RC5_KEY_GEN                0x00000330
13135 +#define CKM_RC5_ECB                    0x00000331
13136 +#define CKM_RC5_CBC                    0x00000332
13137 +#define CKM_RC5_MAC                    0x00000333
13138 +#define CKM_RC5_MAC_GENERAL            0x00000334
13139 +#define CKM_RC5_CBC_PAD                0x00000335
13140 +#define CKM_IDEA_KEY_GEN               0x00000340
13141 +#define CKM_IDEA_ECB                   0x00000341
13142 +#define CKM_IDEA_CBC                   0x00000342
13143 +#define CKM_IDEA_MAC                   0x00000343
13144 +#define CKM_IDEA_MAC_GENERAL           0x00000344
13145 +#define CKM_IDEA_CBC_PAD               0x00000345
13146 +#define CKM_GENERIC_SECRET_KEY_GEN     0x00000350
13147 +#define CKM_CONCATENATE_BASE_AND_KEY   0x00000360
13148 +#define CKM_CONCATENATE_BASE_AND_DATA  0x00000362
13149 +#define CKM_CONCATENATE_DATA_AND_BASE  0x00000363
13150 +#define CKM_XOR_BASE_AND_DATA          0x00000364
13151 +#define CKM_EXTRACT_KEY_FROM_KEY       0x00000365
13152 +#define CKM_SSL3_PRE_MASTER_KEY_GEN    0x00000370
13153 +#define CKM_SSL3_MASTER_KEY_DERIVE     0x00000371
13154 +#define CKM_SSL3_KEY_AND_MAC_DERIVE    0x00000372
13156 +/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
13157 + * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
13158 + * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
13159 +#define CKM_SSL3_MASTER_KEY_DERIVE_DH  0x00000373
13160 +#define CKM_TLS_PRE_MASTER_KEY_GEN     0x00000374
13161 +#define CKM_TLS_MASTER_KEY_DERIVE      0x00000375
13162 +#define CKM_TLS_KEY_AND_MAC_DERIVE     0x00000376
13163 +#define CKM_TLS_MASTER_KEY_DERIVE_DH   0x00000377
13165 +/* CKM_TLS_PRF is new for v2.20 */
13166 +#define CKM_TLS_PRF                    0x00000378
13168 +#define CKM_SSL3_MD5_MAC               0x00000380
13169 +#define CKM_SSL3_SHA1_MAC              0x00000381
13170 +#define CKM_MD5_KEY_DERIVATION         0x00000390
13171 +#define CKM_MD2_KEY_DERIVATION         0x00000391
13172 +#define CKM_SHA1_KEY_DERIVATION        0x00000392
13174 +/* CKM_SHA256/384/512 are new for v2.20 */
13175 +#define CKM_SHA256_KEY_DERIVATION      0x00000393
13176 +#define CKM_SHA384_KEY_DERIVATION      0x00000394
13177 +#define CKM_SHA512_KEY_DERIVATION      0x00000395
13179 +/* SHA-224 key derivation is new for PKCS #11 v2.20 amendment 3 */
13180 +#define CKM_SHA224_KEY_DERIVATION      0x00000396
13182 +#define CKM_PBE_MD2_DES_CBC            0x000003A0
13183 +#define CKM_PBE_MD5_DES_CBC            0x000003A1
13184 +#define CKM_PBE_MD5_CAST_CBC           0x000003A2
13185 +#define CKM_PBE_MD5_CAST3_CBC          0x000003A3
13186 +#define CKM_PBE_MD5_CAST5_CBC          0x000003A4
13187 +#define CKM_PBE_MD5_CAST128_CBC        0x000003A4
13188 +#define CKM_PBE_SHA1_CAST5_CBC         0x000003A5
13189 +#define CKM_PBE_SHA1_CAST128_CBC       0x000003A5
13190 +#define CKM_PBE_SHA1_RC4_128           0x000003A6
13191 +#define CKM_PBE_SHA1_RC4_40            0x000003A7
13192 +#define CKM_PBE_SHA1_DES3_EDE_CBC      0x000003A8
13193 +#define CKM_PBE_SHA1_DES2_EDE_CBC      0x000003A9
13194 +#define CKM_PBE_SHA1_RC2_128_CBC       0x000003AA
13195 +#define CKM_PBE_SHA1_RC2_40_CBC        0x000003AB
13197 +/* CKM_PKCS5_PBKD2 is new for v2.10 */
13198 +#define CKM_PKCS5_PBKD2                0x000003B0
13200 +#define CKM_PBA_SHA1_WITH_SHA1_HMAC    0x000003C0
13202 +/* WTLS mechanisms are new for v2.20 */
13203 +#define CKM_WTLS_PRE_MASTER_KEY_GEN         0x000003D0
13204 +#define CKM_WTLS_MASTER_KEY_DERIVE          0x000003D1
13205 +#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC   0x000003D2
13206 +#define CKM_WTLS_PRF                        0x000003D3
13207 +#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE  0x000003D4
13208 +#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE  0x000003D5
13210 +#define CKM_KEY_WRAP_LYNKS             0x00000400
13211 +#define CKM_KEY_WRAP_SET_OAEP          0x00000401
13213 +/* CKM_CMS_SIG is new for v2.20 */
13214 +#define CKM_CMS_SIG                    0x00000500
13216 +/* CKM_KIP mechanisms are new for PKCS #11 v2.20 amendment 2 */
13217 +#define CKM_KIP_DERIVE                 0x00000510
13218 +#define CKM_KIP_WRAP                   0x00000511
13219 +#define CKM_KIP_MAC                    0x00000512
13221 +/* Camellia is new for PKCS #11 v2.20 amendment 3 */
13222 +#define CKM_CAMELLIA_KEY_GEN           0x00000550
13223 +#define CKM_CAMELLIA_ECB               0x00000551
13224 +#define CKM_CAMELLIA_CBC               0x00000552
13225 +#define CKM_CAMELLIA_MAC               0x00000553
13226 +#define CKM_CAMELLIA_MAC_GENERAL       0x00000554
13227 +#define CKM_CAMELLIA_CBC_PAD           0x00000555
13228 +#define CKM_CAMELLIA_ECB_ENCRYPT_DATA  0x00000556
13229 +#define CKM_CAMELLIA_CBC_ENCRYPT_DATA  0x00000557
13230 +#define CKM_CAMELLIA_CTR               0x00000558
13232 +/* ARIA is new for PKCS #11 v2.20 amendment 3 */
13233 +#define CKM_ARIA_KEY_GEN               0x00000560
13234 +#define CKM_ARIA_ECB                   0x00000561
13235 +#define CKM_ARIA_CBC                   0x00000562
13236 +#define CKM_ARIA_MAC                   0x00000563
13237 +#define CKM_ARIA_MAC_GENERAL           0x00000564
13238 +#define CKM_ARIA_CBC_PAD               0x00000565
13239 +#define CKM_ARIA_ECB_ENCRYPT_DATA      0x00000566
13240 +#define CKM_ARIA_CBC_ENCRYPT_DATA      0x00000567
13242 +/* Fortezza mechanisms */
13243 +#define CKM_SKIPJACK_KEY_GEN           0x00001000
13244 +#define CKM_SKIPJACK_ECB64             0x00001001
13245 +#define CKM_SKIPJACK_CBC64             0x00001002
13246 +#define CKM_SKIPJACK_OFB64             0x00001003
13247 +#define CKM_SKIPJACK_CFB64             0x00001004
13248 +#define CKM_SKIPJACK_CFB32             0x00001005
13249 +#define CKM_SKIPJACK_CFB16             0x00001006
13250 +#define CKM_SKIPJACK_CFB8              0x00001007
13251 +#define CKM_SKIPJACK_WRAP              0x00001008
13252 +#define CKM_SKIPJACK_PRIVATE_WRAP      0x00001009
13253 +#define CKM_SKIPJACK_RELAYX            0x0000100a
13254 +#define CKM_KEA_KEY_PAIR_GEN           0x00001010
13255 +#define CKM_KEA_KEY_DERIVE             0x00001011
13256 +#define CKM_FORTEZZA_TIMESTAMP         0x00001020
13257 +#define CKM_BATON_KEY_GEN              0x00001030
13258 +#define CKM_BATON_ECB128               0x00001031
13259 +#define CKM_BATON_ECB96                0x00001032
13260 +#define CKM_BATON_CBC128               0x00001033
13261 +#define CKM_BATON_COUNTER              0x00001034
13262 +#define CKM_BATON_SHUFFLE              0x00001035
13263 +#define CKM_BATON_WRAP                 0x00001036
13265 +/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
13266 + * CKM_EC_KEY_PAIR_GEN is preferred */
13267 +#define CKM_ECDSA_KEY_PAIR_GEN         0x00001040
13268 +#define CKM_EC_KEY_PAIR_GEN            0x00001040
13270 +#define CKM_ECDSA                      0x00001041
13271 +#define CKM_ECDSA_SHA1                 0x00001042
13273 +/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
13274 + * are new for v2.11 */
13275 +#define CKM_ECDH1_DERIVE               0x00001050
13276 +#define CKM_ECDH1_COFACTOR_DERIVE      0x00001051
13277 +#define CKM_ECMQV_DERIVE               0x00001052
13279 +#define CKM_JUNIPER_KEY_GEN            0x00001060
13280 +#define CKM_JUNIPER_ECB128             0x00001061
13281 +#define CKM_JUNIPER_CBC128             0x00001062
13282 +#define CKM_JUNIPER_COUNTER            0x00001063
13283 +#define CKM_JUNIPER_SHUFFLE            0x00001064
13284 +#define CKM_JUNIPER_WRAP               0x00001065
13285 +#define CKM_FASTHASH                   0x00001070
13287 +/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
13288 + * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
13289 + * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
13290 + * new for v2.11 */
13291 +#define CKM_AES_KEY_GEN                0x00001080
13292 +#define CKM_AES_ECB                    0x00001081
13293 +#define CKM_AES_CBC                    0x00001082
13294 +#define CKM_AES_MAC                    0x00001083
13295 +#define CKM_AES_MAC_GENERAL            0x00001084
13296 +#define CKM_AES_CBC_PAD                0x00001085
13298 +/* AES counter mode is new for PKCS #11 v2.20 amendment 3 */
13299 +#define CKM_AES_CTR                    0x00001086
13301 +/* BlowFish and TwoFish are new for v2.20 */
13302 +#define CKM_BLOWFISH_KEY_GEN           0x00001090
13303 +#define CKM_BLOWFISH_CBC               0x00001091
13304 +#define CKM_TWOFISH_KEY_GEN            0x00001092
13305 +#define CKM_TWOFISH_CBC                0x00001093
13308 +/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */
13309 +#define CKM_DES_ECB_ENCRYPT_DATA       0x00001100
13310 +#define CKM_DES_CBC_ENCRYPT_DATA       0x00001101
13311 +#define CKM_DES3_ECB_ENCRYPT_DATA      0x00001102
13312 +#define CKM_DES3_CBC_ENCRYPT_DATA      0x00001103
13313 +#define CKM_AES_ECB_ENCRYPT_DATA       0x00001104
13314 +#define CKM_AES_CBC_ENCRYPT_DATA       0x00001105
13316 +#define CKM_DSA_PARAMETER_GEN          0x00002000
13317 +#define CKM_DH_PKCS_PARAMETER_GEN      0x00002001
13318 +#define CKM_X9_42_DH_PARAMETER_GEN     0x00002002
13320 +#define CKM_VENDOR_DEFINED             0x80000000
13322 +typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
13325 +/* CK_MECHANISM is a structure that specifies a particular
13326 + * mechanism  */
13327 +typedef struct CK_MECHANISM {
13328 +  CK_MECHANISM_TYPE mechanism;
13329 +  CK_VOID_PTR       pParameter;
13331 +  /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
13332 +   * v2.0 */
13333 +  CK_ULONG          ulParameterLen;  /* in bytes */
13334 +} CK_MECHANISM;
13336 +typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
13339 +/* CK_MECHANISM_INFO provides information about a particular
13340 + * mechanism */
13341 +typedef struct CK_MECHANISM_INFO {
13342 +    CK_ULONG    ulMinKeySize;
13343 +    CK_ULONG    ulMaxKeySize;
13344 +    CK_FLAGS    flags;
13345 +} CK_MECHANISM_INFO;
13347 +/* The flags are defined as follows:
13348 + *      Bit Flag               Mask        Meaning */
13349 +#define CKF_HW                 0x00000001  /* performed by HW */
13351 +/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
13352 + * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
13353 + * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
13354 + * and CKF_DERIVE are new for v2.0.  They specify whether or not
13355 + * a mechanism can be used for a particular task */
13356 +#define CKF_ENCRYPT            0x00000100
13357 +#define CKF_DECRYPT            0x00000200
13358 +#define CKF_DIGEST             0x00000400
13359 +#define CKF_SIGN               0x00000800
13360 +#define CKF_SIGN_RECOVER       0x00001000
13361 +#define CKF_VERIFY             0x00002000
13362 +#define CKF_VERIFY_RECOVER     0x00004000
13363 +#define CKF_GENERATE           0x00008000
13364 +#define CKF_GENERATE_KEY_PAIR  0x00010000
13365 +#define CKF_WRAP               0x00020000
13366 +#define CKF_UNWRAP             0x00040000
13367 +#define CKF_DERIVE             0x00080000
13369 +/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
13370 + * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
13371 + * describe a token's EC capabilities not available in mechanism
13372 + * information. */
13373 +#define CKF_EC_F_P             0x00100000
13374 +#define CKF_EC_F_2M            0x00200000
13375 +#define CKF_EC_ECPARAMETERS    0x00400000
13376 +#define CKF_EC_NAMEDCURVE      0x00800000
13377 +#define CKF_EC_UNCOMPRESS      0x01000000
13378 +#define CKF_EC_COMPRESS        0x02000000
13380 +#define CKF_EXTENSION          0x80000000 /* FALSE for this version */
13382 +typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
13385 +/* CK_RV is a value that identifies the return value of a
13386 + * Cryptoki function */
13387 +/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
13388 +typedef CK_ULONG          CK_RV;
13390 +#define CKR_OK                                0x00000000
13391 +#define CKR_CANCEL                            0x00000001
13392 +#define CKR_HOST_MEMORY                       0x00000002
13393 +#define CKR_SLOT_ID_INVALID                   0x00000003
13395 +/* CKR_FLAGS_INVALID was removed for v2.0 */
13397 +/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
13398 +#define CKR_GENERAL_ERROR                     0x00000005
13399 +#define CKR_FUNCTION_FAILED                   0x00000006
13401 +/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
13402 + * and CKR_CANT_LOCK are new for v2.01 */
13403 +#define CKR_ARGUMENTS_BAD                     0x00000007
13404 +#define CKR_NO_EVENT                          0x00000008
13405 +#define CKR_NEED_TO_CREATE_THREADS            0x00000009
13406 +#define CKR_CANT_LOCK                         0x0000000A
13408 +#define CKR_ATTRIBUTE_READ_ONLY               0x00000010
13409 +#define CKR_ATTRIBUTE_SENSITIVE               0x00000011
13410 +#define CKR_ATTRIBUTE_TYPE_INVALID            0x00000012
13411 +#define CKR_ATTRIBUTE_VALUE_INVALID           0x00000013
13412 +#define CKR_DATA_INVALID                      0x00000020
13413 +#define CKR_DATA_LEN_RANGE                    0x00000021
13414 +#define CKR_DEVICE_ERROR                      0x00000030
13415 +#define CKR_DEVICE_MEMORY                     0x00000031
13416 +#define CKR_DEVICE_REMOVED                    0x00000032
13417 +#define CKR_ENCRYPTED_DATA_INVALID            0x00000040
13418 +#define CKR_ENCRYPTED_DATA_LEN_RANGE          0x00000041
13419 +#define CKR_FUNCTION_CANCELED                 0x00000050
13420 +#define CKR_FUNCTION_NOT_PARALLEL             0x00000051
13422 +/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
13423 +#define CKR_FUNCTION_NOT_SUPPORTED            0x00000054
13425 +#define CKR_KEY_HANDLE_INVALID                0x00000060
13427 +/* CKR_KEY_SENSITIVE was removed for v2.0 */
13429 +#define CKR_KEY_SIZE_RANGE                    0x00000062
13430 +#define CKR_KEY_TYPE_INCONSISTENT             0x00000063
13432 +/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
13433 + * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
13434 + * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
13435 + * v2.0 */
13436 +#define CKR_KEY_NOT_NEEDED                    0x00000064
13437 +#define CKR_KEY_CHANGED                       0x00000065
13438 +#define CKR_KEY_NEEDED                        0x00000066
13439 +#define CKR_KEY_INDIGESTIBLE                  0x00000067
13440 +#define CKR_KEY_FUNCTION_NOT_PERMITTED        0x00000068
13441 +#define CKR_KEY_NOT_WRAPPABLE                 0x00000069
13442 +#define CKR_KEY_UNEXTRACTABLE                 0x0000006A
13444 +#define CKR_MECHANISM_INVALID                 0x00000070
13445 +#define CKR_MECHANISM_PARAM_INVALID           0x00000071
13447 +/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
13448 + * were removed for v2.0 */
13449 +#define CKR_OBJECT_HANDLE_INVALID             0x00000082
13450 +#define CKR_OPERATION_ACTIVE                  0x00000090
13451 +#define CKR_OPERATION_NOT_INITIALIZED         0x00000091
13452 +#define CKR_PIN_INCORRECT                     0x000000A0
13453 +#define CKR_PIN_INVALID                       0x000000A1
13454 +#define CKR_PIN_LEN_RANGE                     0x000000A2
13456 +/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
13457 +#define CKR_PIN_EXPIRED                       0x000000A3
13458 +#define CKR_PIN_LOCKED                        0x000000A4
13460 +#define CKR_SESSION_CLOSED                    0x000000B0
13461 +#define CKR_SESSION_COUNT                     0x000000B1
13462 +#define CKR_SESSION_HANDLE_INVALID            0x000000B3
13463 +#define CKR_SESSION_PARALLEL_NOT_SUPPORTED    0x000000B4
13464 +#define CKR_SESSION_READ_ONLY                 0x000000B5
13465 +#define CKR_SESSION_EXISTS                    0x000000B6
13467 +/* CKR_SESSION_READ_ONLY_EXISTS and
13468 + * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
13469 +#define CKR_SESSION_READ_ONLY_EXISTS          0x000000B7
13470 +#define CKR_SESSION_READ_WRITE_SO_EXISTS      0x000000B8
13472 +#define CKR_SIGNATURE_INVALID                 0x000000C0
13473 +#define CKR_SIGNATURE_LEN_RANGE               0x000000C1
13474 +#define CKR_TEMPLATE_INCOMPLETE               0x000000D0
13475 +#define CKR_TEMPLATE_INCONSISTENT             0x000000D1
13476 +#define CKR_TOKEN_NOT_PRESENT                 0x000000E0
13477 +#define CKR_TOKEN_NOT_RECOGNIZED              0x000000E1
13478 +#define CKR_TOKEN_WRITE_PROTECTED             0x000000E2
13479 +#define CKR_UNWRAPPING_KEY_HANDLE_INVALID     0x000000F0
13480 +#define CKR_UNWRAPPING_KEY_SIZE_RANGE         0x000000F1
13481 +#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT  0x000000F2
13482 +#define CKR_USER_ALREADY_LOGGED_IN            0x00000100
13483 +#define CKR_USER_NOT_LOGGED_IN                0x00000101
13484 +#define CKR_USER_PIN_NOT_INITIALIZED          0x00000102
13485 +#define CKR_USER_TYPE_INVALID                 0x00000103
13487 +/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
13488 + * are new to v2.01 */
13489 +#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN    0x00000104
13490 +#define CKR_USER_TOO_MANY_TYPES               0x00000105
13492 +#define CKR_WRAPPED_KEY_INVALID               0x00000110
13493 +#define CKR_WRAPPED_KEY_LEN_RANGE             0x00000112
13494 +#define CKR_WRAPPING_KEY_HANDLE_INVALID       0x00000113
13495 +#define CKR_WRAPPING_KEY_SIZE_RANGE           0x00000114
13496 +#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT    0x00000115
13497 +#define CKR_RANDOM_SEED_NOT_SUPPORTED         0x00000120
13499 +/* These are new to v2.0 */
13500 +#define CKR_RANDOM_NO_RNG                     0x00000121
13502 +/* These are new to v2.11 */
13503 +#define CKR_DOMAIN_PARAMS_INVALID             0x00000130
13505 +/* These are new to v2.0 */
13506 +#define CKR_BUFFER_TOO_SMALL                  0x00000150
13507 +#define CKR_SAVED_STATE_INVALID               0x00000160
13508 +#define CKR_INFORMATION_SENSITIVE             0x00000170
13509 +#define CKR_STATE_UNSAVEABLE                  0x00000180
13511 +/* These are new to v2.01 */
13512 +#define CKR_CRYPTOKI_NOT_INITIALIZED          0x00000190
13513 +#define CKR_CRYPTOKI_ALREADY_INITIALIZED      0x00000191
13514 +#define CKR_MUTEX_BAD                         0x000001A0
13515 +#define CKR_MUTEX_NOT_LOCKED                  0x000001A1
13517 +/* The following return values are new for PKCS #11 v2.20 amendment 3 */
13518 +#define CKR_NEW_PIN_MODE                      0x000001B0
13519 +#define CKR_NEXT_OTP                          0x000001B1
13521 +/* This is new to v2.20 */
13522 +#define CKR_FUNCTION_REJECTED                 0x00000200
13524 +#define CKR_VENDOR_DEFINED                    0x80000000
13527 +/* CK_NOTIFY is an application callback that processes events */
13528 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
13529 +  CK_SESSION_HANDLE hSession,     /* the session's handle */
13530 +  CK_NOTIFICATION   event,
13531 +  CK_VOID_PTR       pApplication  /* passed to C_OpenSession */
13535 +/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
13536 + * version and pointers of appropriate types to all the
13537 + * Cryptoki functions */
13538 +/* CK_FUNCTION_LIST is new for v2.0 */
13539 +typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
13541 +typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
13543 +typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
13546 +/* CK_CREATEMUTEX is an application callback for creating a
13547 + * mutex object */
13548 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
13549 +  CK_VOID_PTR_PTR ppMutex  /* location to receive ptr to mutex */
13553 +/* CK_DESTROYMUTEX is an application callback for destroying a
13554 + * mutex object */
13555 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
13556 +  CK_VOID_PTR pMutex  /* pointer to mutex */
13560 +/* CK_LOCKMUTEX is an application callback for locking a mutex */
13561 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
13562 +  CK_VOID_PTR pMutex  /* pointer to mutex */
13566 +/* CK_UNLOCKMUTEX is an application callback for unlocking a
13567 + * mutex */
13568 +typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
13569 +  CK_VOID_PTR pMutex  /* pointer to mutex */
13573 +/* CK_C_INITIALIZE_ARGS provides the optional arguments to
13574 + * C_Initialize */
13575 +typedef struct CK_C_INITIALIZE_ARGS {
13576 +  CK_CREATEMUTEX CreateMutex;
13577 +  CK_DESTROYMUTEX DestroyMutex;
13578 +  CK_LOCKMUTEX LockMutex;
13579 +  CK_UNLOCKMUTEX UnlockMutex;
13580 +  CK_FLAGS flags;
13581 +  CK_VOID_PTR pReserved;
13582 +} CK_C_INITIALIZE_ARGS;
13584 +/* flags: bit flags that provide capabilities of the slot
13585 + *      Bit Flag                           Mask       Meaning
13586 + */
13587 +#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
13588 +#define CKF_OS_LOCKING_OK                  0x00000002
13590 +typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
13593 +/* additional flags for parameters to functions */
13595 +/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
13596 +#define CKF_DONT_BLOCK     1
13598 +/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
13599 + * CK_RSA_PKCS_OAEP_MGF_TYPE  is used to indicate the Message
13600 + * Generation Function (MGF) applied to a message block when
13601 + * formatting a message block for the PKCS #1 OAEP encryption
13602 + * scheme. */
13603 +typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
13605 +typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
13607 +/* The following MGFs are defined */
13608 +/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512
13609 + * are new for v2.20 */
13610 +#define CKG_MGF1_SHA1         0x00000001
13611 +#define CKG_MGF1_SHA256       0x00000002
13612 +#define CKG_MGF1_SHA384       0x00000003
13613 +#define CKG_MGF1_SHA512       0x00000004
13614 +/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
13615 +#define CKG_MGF1_SHA224       0x00000005
13617 +/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
13618 + * CK_RSA_PKCS_OAEP_SOURCE_TYPE  is used to indicate the source
13619 + * of the encoding parameter when formatting a message block
13620 + * for the PKCS #1 OAEP encryption scheme. */
13621 +typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
13623 +typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
13625 +/* The following encoding parameter sources are defined */
13626 +#define CKZ_DATA_SPECIFIED    0x00000001
13628 +/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
13629 + * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
13630 + * CKM_RSA_PKCS_OAEP mechanism. */
13631 +typedef struct CK_RSA_PKCS_OAEP_PARAMS {
13632 +        CK_MECHANISM_TYPE hashAlg;
13633 +        CK_RSA_PKCS_MGF_TYPE mgf;
13634 +        CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
13635 +        CK_VOID_PTR pSourceData;
13636 +        CK_ULONG ulSourceDataLen;
13637 +} CK_RSA_PKCS_OAEP_PARAMS;
13639 +typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
13641 +/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11.
13642 + * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
13643 + * CKM_RSA_PKCS_PSS mechanism(s). */
13644 +typedef struct CK_RSA_PKCS_PSS_PARAMS {
13645 +        CK_MECHANISM_TYPE    hashAlg;
13646 +        CK_RSA_PKCS_MGF_TYPE mgf;
13647 +        CK_ULONG             sLen;
13648 +} CK_RSA_PKCS_PSS_PARAMS;
13650 +typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
13652 +/* CK_EC_KDF_TYPE is new for v2.11. */
13653 +typedef CK_ULONG CK_EC_KDF_TYPE;
13655 +/* The following EC Key Derivation Functions are defined */
13656 +#define CKD_NULL                 0x00000001
13657 +#define CKD_SHA1_KDF             0x00000002
13659 +/* CK_ECDH1_DERIVE_PARAMS is new for v2.11.
13660 + * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
13661 + * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
13662 + * where each party contributes one key pair.
13663 + */
13664 +typedef struct CK_ECDH1_DERIVE_PARAMS {
13665 +  CK_EC_KDF_TYPE kdf;
13666 +  CK_ULONG ulSharedDataLen;
13667 +  CK_BYTE_PTR pSharedData;
13668 +  CK_ULONG ulPublicDataLen;
13669 +  CK_BYTE_PTR pPublicData;
13670 +} CK_ECDH1_DERIVE_PARAMS;
13672 +typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
13675 +/* CK_ECDH2_DERIVE_PARAMS is new for v2.11.
13676 + * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
13677 + * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */
13678 +typedef struct CK_ECDH2_DERIVE_PARAMS {
13679 +  CK_EC_KDF_TYPE kdf;
13680 +  CK_ULONG ulSharedDataLen;
13681 +  CK_BYTE_PTR pSharedData;
13682 +  CK_ULONG ulPublicDataLen;
13683 +  CK_BYTE_PTR pPublicData;
13684 +  CK_ULONG ulPrivateDataLen;
13685 +  CK_OBJECT_HANDLE hPrivateData;
13686 +  CK_ULONG ulPublicDataLen2;
13687 +  CK_BYTE_PTR pPublicData2;
13688 +} CK_ECDH2_DERIVE_PARAMS;
13690 +typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
13692 +typedef struct CK_ECMQV_DERIVE_PARAMS {
13693 +  CK_EC_KDF_TYPE kdf;
13694 +  CK_ULONG ulSharedDataLen;
13695 +  CK_BYTE_PTR pSharedData;
13696 +  CK_ULONG ulPublicDataLen;
13697 +  CK_BYTE_PTR pPublicData;
13698 +  CK_ULONG ulPrivateDataLen;
13699 +  CK_OBJECT_HANDLE hPrivateData;
13700 +  CK_ULONG ulPublicDataLen2;
13701 +  CK_BYTE_PTR pPublicData2;
13702 +  CK_OBJECT_HANDLE publicKey;
13703 +} CK_ECMQV_DERIVE_PARAMS;
13705 +typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
13707 +/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
13708 + * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */
13709 +typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
13710 +typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
13712 +/* The following X9.42 DH key derivation functions are defined
13713 +   (besides CKD_NULL already defined : */
13714 +#define CKD_SHA1_KDF_ASN1        0x00000003
13715 +#define CKD_SHA1_KDF_CONCATENATE 0x00000004
13717 +/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11.
13718 + * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
13719 + * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
13720 + * contributes one key pair */
13721 +typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
13722 +  CK_X9_42_DH_KDF_TYPE kdf;
13723 +  CK_ULONG ulOtherInfoLen;
13724 +  CK_BYTE_PTR pOtherInfo;
13725 +  CK_ULONG ulPublicDataLen;
13726 +  CK_BYTE_PTR pPublicData;
13727 +} CK_X9_42_DH1_DERIVE_PARAMS;
13729 +typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
13731 +/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11.
13732 + * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
13733 + * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
13734 + * mechanisms, where each party contributes two key pairs */
13735 +typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
13736 +  CK_X9_42_DH_KDF_TYPE kdf;
13737 +  CK_ULONG ulOtherInfoLen;
13738 +  CK_BYTE_PTR pOtherInfo;
13739 +  CK_ULONG ulPublicDataLen;
13740 +  CK_BYTE_PTR pPublicData;
13741 +  CK_ULONG ulPrivateDataLen;
13742 +  CK_OBJECT_HANDLE hPrivateData;
13743 +  CK_ULONG ulPublicDataLen2;
13744 +  CK_BYTE_PTR pPublicData2;
13745 +} CK_X9_42_DH2_DERIVE_PARAMS;
13747 +typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
13749 +typedef struct CK_X9_42_MQV_DERIVE_PARAMS {
13750 +  CK_X9_42_DH_KDF_TYPE kdf;
13751 +  CK_ULONG ulOtherInfoLen;
13752 +  CK_BYTE_PTR pOtherInfo;
13753 +  CK_ULONG ulPublicDataLen;
13754 +  CK_BYTE_PTR pPublicData;
13755 +  CK_ULONG ulPrivateDataLen;
13756 +  CK_OBJECT_HANDLE hPrivateData;
13757 +  CK_ULONG ulPublicDataLen2;
13758 +  CK_BYTE_PTR pPublicData2;
13759 +  CK_OBJECT_HANDLE publicKey;
13760 +} CK_X9_42_MQV_DERIVE_PARAMS;
13762 +typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
13764 +/* CK_KEA_DERIVE_PARAMS provides the parameters to the
13765 + * CKM_KEA_DERIVE mechanism */
13766 +/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
13767 +typedef struct CK_KEA_DERIVE_PARAMS {
13768 +  CK_BBOOL      isSender;
13769 +  CK_ULONG      ulRandomLen;
13770 +  CK_BYTE_PTR   pRandomA;
13771 +  CK_BYTE_PTR   pRandomB;
13772 +  CK_ULONG      ulPublicDataLen;
13773 +  CK_BYTE_PTR   pPublicData;
13774 +} CK_KEA_DERIVE_PARAMS;
13776 +typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
13779 +/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
13780 + * CKM_RC2_MAC mechanisms.  An instance of CK_RC2_PARAMS just
13781 + * holds the effective keysize */
13782 +typedef CK_ULONG          CK_RC2_PARAMS;
13784 +typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
13787 +/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
13788 + * mechanism */
13789 +typedef struct CK_RC2_CBC_PARAMS {
13790 +  /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
13791 +   * v2.0 */
13792 +  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
13794 +  CK_BYTE       iv[8];            /* IV for CBC mode */
13795 +} CK_RC2_CBC_PARAMS;
13797 +typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
13800 +/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
13801 + * CKM_RC2_MAC_GENERAL mechanism */
13802 +/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
13803 +typedef struct CK_RC2_MAC_GENERAL_PARAMS {
13804 +  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
13805 +  CK_ULONG      ulMacLength;      /* Length of MAC in bytes */
13806 +} CK_RC2_MAC_GENERAL_PARAMS;
13808 +typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
13809 +  CK_RC2_MAC_GENERAL_PARAMS_PTR;
13812 +/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
13813 + * CKM_RC5_MAC mechanisms */
13814 +/* CK_RC5_PARAMS is new for v2.0 */
13815 +typedef struct CK_RC5_PARAMS {
13816 +  CK_ULONG      ulWordsize;  /* wordsize in bits */
13817 +  CK_ULONG      ulRounds;    /* number of rounds */
13818 +} CK_RC5_PARAMS;
13820 +typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
13823 +/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
13824 + * mechanism */
13825 +/* CK_RC5_CBC_PARAMS is new for v2.0 */
13826 +typedef struct CK_RC5_CBC_PARAMS {
13827 +  CK_ULONG      ulWordsize;  /* wordsize in bits */
13828 +  CK_ULONG      ulRounds;    /* number of rounds */
13829 +  CK_BYTE_PTR   pIv;         /* pointer to IV */
13830 +  CK_ULONG      ulIvLen;     /* length of IV in bytes */
13831 +} CK_RC5_CBC_PARAMS;
13833 +typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
13836 +/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
13837 + * CKM_RC5_MAC_GENERAL mechanism */
13838 +/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
13839 +typedef struct CK_RC5_MAC_GENERAL_PARAMS {
13840 +  CK_ULONG      ulWordsize;   /* wordsize in bits */
13841 +  CK_ULONG      ulRounds;     /* number of rounds */
13842 +  CK_ULONG      ulMacLength;  /* Length of MAC in bytes */
13843 +} CK_RC5_MAC_GENERAL_PARAMS;
13845 +typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
13846 +  CK_RC5_MAC_GENERAL_PARAMS_PTR;
13849 +/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
13850 + * ciphers' MAC_GENERAL mechanisms.  Its value is the length of
13851 + * the MAC */
13852 +/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
13853 +typedef CK_ULONG          CK_MAC_GENERAL_PARAMS;
13855 +typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
13857 +/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
13858 +typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
13859 +  CK_BYTE      iv[8];
13860 +  CK_BYTE_PTR  pData;
13861 +  CK_ULONG     length;
13862 +} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
13864 +typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
13866 +typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
13867 +  CK_BYTE      iv[16];
13868 +  CK_BYTE_PTR  pData;
13869 +  CK_ULONG     length;
13870 +} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
13872 +typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
13874 +/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
13875 + * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
13876 +/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
13877 +typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
13878 +  CK_ULONG      ulPasswordLen;
13879 +  CK_BYTE_PTR   pPassword;
13880 +  CK_ULONG      ulPublicDataLen;
13881 +  CK_BYTE_PTR   pPublicData;
13882 +  CK_ULONG      ulPAndGLen;
13883 +  CK_ULONG      ulQLen;
13884 +  CK_ULONG      ulRandomLen;
13885 +  CK_BYTE_PTR   pRandomA;
13886 +  CK_BYTE_PTR   pPrimeP;
13887 +  CK_BYTE_PTR   pBaseG;
13888 +  CK_BYTE_PTR   pSubprimeQ;
13889 +} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
13891 +typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
13892 +  CK_SKIPJACK_PRIVATE_WRAP_PTR;
13895 +/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
13896 + * CKM_SKIPJACK_RELAYX mechanism */
13897 +/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
13898 +typedef struct CK_SKIPJACK_RELAYX_PARAMS {
13899 +  CK_ULONG      ulOldWrappedXLen;
13900 +  CK_BYTE_PTR   pOldWrappedX;
13901 +  CK_ULONG      ulOldPasswordLen;
13902 +  CK_BYTE_PTR   pOldPassword;
13903 +  CK_ULONG      ulOldPublicDataLen;
13904 +  CK_BYTE_PTR   pOldPublicData;
13905 +  CK_ULONG      ulOldRandomLen;
13906 +  CK_BYTE_PTR   pOldRandomA;
13907 +  CK_ULONG      ulNewPasswordLen;
13908 +  CK_BYTE_PTR   pNewPassword;
13909 +  CK_ULONG      ulNewPublicDataLen;
13910 +  CK_BYTE_PTR   pNewPublicData;
13911 +  CK_ULONG      ulNewRandomLen;
13912 +  CK_BYTE_PTR   pNewRandomA;
13913 +} CK_SKIPJACK_RELAYX_PARAMS;
13915 +typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
13916 +  CK_SKIPJACK_RELAYX_PARAMS_PTR;
13919 +typedef struct CK_PBE_PARAMS {
13920 +  CK_BYTE_PTR      pInitVector;
13921 +  CK_UTF8CHAR_PTR  pPassword;
13922 +  CK_ULONG         ulPasswordLen;
13923 +  CK_BYTE_PTR      pSalt;
13924 +  CK_ULONG         ulSaltLen;
13925 +  CK_ULONG         ulIteration;
13926 +} CK_PBE_PARAMS;
13928 +typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
13931 +/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
13932 + * CKM_KEY_WRAP_SET_OAEP mechanism */
13933 +/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
13934 +typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
13935 +  CK_BYTE       bBC;     /* block contents byte */
13936 +  CK_BYTE_PTR   pX;      /* extra data */
13937 +  CK_ULONG      ulXLen;  /* length of extra data in bytes */
13938 +} CK_KEY_WRAP_SET_OAEP_PARAMS;
13940 +typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
13941 +  CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
13944 +typedef struct CK_SSL3_RANDOM_DATA {
13945 +  CK_BYTE_PTR  pClientRandom;
13946 +  CK_ULONG     ulClientRandomLen;
13947 +  CK_BYTE_PTR  pServerRandom;
13948 +  CK_ULONG     ulServerRandomLen;
13949 +} CK_SSL3_RANDOM_DATA;
13952 +typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
13953 +  CK_SSL3_RANDOM_DATA RandomInfo;
13954 +  CK_VERSION_PTR pVersion;
13955 +} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
13957 +typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
13958 +  CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
13961 +typedef struct CK_SSL3_KEY_MAT_OUT {
13962 +  CK_OBJECT_HANDLE hClientMacSecret;
13963 +  CK_OBJECT_HANDLE hServerMacSecret;
13964 +  CK_OBJECT_HANDLE hClientKey;
13965 +  CK_OBJECT_HANDLE hServerKey;
13966 +  CK_BYTE_PTR      pIVClient;
13967 +  CK_BYTE_PTR      pIVServer;
13968 +} CK_SSL3_KEY_MAT_OUT;
13970 +typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
13973 +typedef struct CK_SSL3_KEY_MAT_PARAMS {
13974 +  CK_ULONG                ulMacSizeInBits;
13975 +  CK_ULONG                ulKeySizeInBits;
13976 +  CK_ULONG                ulIVSizeInBits;
13977 +  CK_BBOOL                bIsExport;
13978 +  CK_SSL3_RANDOM_DATA     RandomInfo;
13979 +  CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
13980 +} CK_SSL3_KEY_MAT_PARAMS;
13982 +typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
13984 +/* CK_TLS_PRF_PARAMS is new for version 2.20 */
13985 +typedef struct CK_TLS_PRF_PARAMS {
13986 +  CK_BYTE_PTR  pSeed;
13987 +  CK_ULONG     ulSeedLen;
13988 +  CK_BYTE_PTR  pLabel;
13989 +  CK_ULONG     ulLabelLen;
13990 +  CK_BYTE_PTR  pOutput;
13991 +  CK_ULONG_PTR pulOutputLen;
13992 +} CK_TLS_PRF_PARAMS;
13994 +typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
13996 +/* WTLS is new for version 2.20 */
13997 +typedef struct CK_WTLS_RANDOM_DATA {
13998 +  CK_BYTE_PTR pClientRandom;
13999 +  CK_ULONG    ulClientRandomLen;
14000 +  CK_BYTE_PTR pServerRandom;
14001 +  CK_ULONG    ulServerRandomLen;
14002 +} CK_WTLS_RANDOM_DATA;
14004 +typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
14006 +typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
14007 +  CK_MECHANISM_TYPE   DigestMechanism;
14008 +  CK_WTLS_RANDOM_DATA RandomInfo;
14009 +  CK_BYTE_PTR         pVersion;
14010 +} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
14012 +typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
14013 +  CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
14015 +typedef struct CK_WTLS_PRF_PARAMS {
14016 +  CK_MECHANISM_TYPE DigestMechanism;
14017 +  CK_BYTE_PTR       pSeed;
14018 +  CK_ULONG          ulSeedLen;
14019 +  CK_BYTE_PTR       pLabel;
14020 +  CK_ULONG          ulLabelLen;
14021 +  CK_BYTE_PTR       pOutput;
14022 +  CK_ULONG_PTR      pulOutputLen;
14023 +} CK_WTLS_PRF_PARAMS;
14025 +typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
14027 +typedef struct CK_WTLS_KEY_MAT_OUT {
14028 +  CK_OBJECT_HANDLE hMacSecret;
14029 +  CK_OBJECT_HANDLE hKey;
14030 +  CK_BYTE_PTR      pIV;
14031 +} CK_WTLS_KEY_MAT_OUT;
14033 +typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
14035 +typedef struct CK_WTLS_KEY_MAT_PARAMS {
14036 +  CK_MECHANISM_TYPE       DigestMechanism;
14037 +  CK_ULONG                ulMacSizeInBits;
14038 +  CK_ULONG                ulKeySizeInBits;
14039 +  CK_ULONG                ulIVSizeInBits;
14040 +  CK_ULONG                ulSequenceNumber;
14041 +  CK_BBOOL                bIsExport;
14042 +  CK_WTLS_RANDOM_DATA     RandomInfo;
14043 +  CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
14044 +} CK_WTLS_KEY_MAT_PARAMS;
14046 +typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
14048 +/* CMS is new for version 2.20 */
14049 +typedef struct CK_CMS_SIG_PARAMS {
14050 +  CK_OBJECT_HANDLE      certificateHandle;
14051 +  CK_MECHANISM_PTR      pSigningMechanism;
14052 +  CK_MECHANISM_PTR      pDigestMechanism;
14053 +  CK_UTF8CHAR_PTR       pContentType;
14054 +  CK_BYTE_PTR           pRequestedAttributes;
14055 +  CK_ULONG              ulRequestedAttributesLen;
14056 +  CK_BYTE_PTR           pRequiredAttributes;
14057 +  CK_ULONG              ulRequiredAttributesLen;
14058 +} CK_CMS_SIG_PARAMS;
14060 +typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
14062 +typedef struct CK_KEY_DERIVATION_STRING_DATA {
14063 +  CK_BYTE_PTR pData;
14064 +  CK_ULONG    ulLen;
14065 +} CK_KEY_DERIVATION_STRING_DATA;
14067 +typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
14068 +  CK_KEY_DERIVATION_STRING_DATA_PTR;
14071 +/* The CK_EXTRACT_PARAMS is used for the
14072 + * CKM_EXTRACT_KEY_FROM_KEY mechanism.  It specifies which bit
14073 + * of the base key should be used as the first bit of the
14074 + * derived key */
14075 +/* CK_EXTRACT_PARAMS is new for v2.0 */
14076 +typedef CK_ULONG CK_EXTRACT_PARAMS;
14078 +typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
14080 +/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
14081 + * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
14082 + * indicate the Pseudo-Random Function (PRF) used to generate
14083 + * key bits using PKCS #5 PBKDF2. */
14084 +typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
14086 +typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
14088 +/* The following PRFs are defined in PKCS #5 v2.0. */
14089 +#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
14092 +/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
14093 + * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
14094 + * source of the salt value when deriving a key using PKCS #5
14095 + * PBKDF2. */
14096 +typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
14098 +typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
14100 +/* The following salt value sources are defined in PKCS #5 v2.0. */
14101 +#define CKZ_SALT_SPECIFIED        0x00000001
14103 +/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
14104 + * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
14105 + * parameters to the CKM_PKCS5_PBKD2 mechanism. */
14106 +typedef struct CK_PKCS5_PBKD2_PARAMS {
14107 +        CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE           saltSource;
14108 +        CK_VOID_PTR                                pSaltSourceData;
14109 +        CK_ULONG                                   ulSaltSourceDataLen;
14110 +        CK_ULONG                                   iterations;
14111 +        CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
14112 +        CK_VOID_PTR                                pPrfData;
14113 +        CK_ULONG                                   ulPrfDataLen;
14114 +        CK_UTF8CHAR_PTR                            pPassword;
14115 +        CK_ULONG_PTR                               ulPasswordLen;
14116 +} CK_PKCS5_PBKD2_PARAMS;
14118 +typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
14120 +/* All CK_OTP structs are new for PKCS #11 v2.20 amendment 3 */
14122 +typedef CK_ULONG CK_OTP_PARAM_TYPE;
14123 +typedef CK_OTP_PARAM_TYPE CK_PARAM_TYPE; /* B/w compatibility */
14125 +typedef struct CK_OTP_PARAM {
14126 +    CK_OTP_PARAM_TYPE type;
14127 +    CK_VOID_PTR pValue;
14128 +    CK_ULONG ulValueLen;
14129 +} CK_OTP_PARAM;
14131 +typedef CK_OTP_PARAM CK_PTR CK_OTP_PARAM_PTR;
14133 +typedef struct CK_OTP_PARAMS {
14134 +    CK_OTP_PARAM_PTR pParams;
14135 +    CK_ULONG ulCount;
14136 +} CK_OTP_PARAMS;
14138 +typedef CK_OTP_PARAMS CK_PTR CK_OTP_PARAMS_PTR;
14140 +typedef struct CK_OTP_SIGNATURE_INFO {
14141 +    CK_OTP_PARAM_PTR pParams;
14142 +    CK_ULONG ulCount;
14143 +} CK_OTP_SIGNATURE_INFO;
14145 +typedef CK_OTP_SIGNATURE_INFO CK_PTR CK_OTP_SIGNATURE_INFO_PTR;
14147 +/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */
14148 +#define CK_OTP_VALUE          0
14149 +#define CK_OTP_PIN            1
14150 +#define CK_OTP_CHALLENGE      2
14151 +#define CK_OTP_TIME           3
14152 +#define CK_OTP_COUNTER        4
14153 +#define CK_OTP_FLAGS          5
14154 +#define CK_OTP_OUTPUT_LENGTH  6
14155 +#define CK_OTP_OUTPUT_FORMAT  7
14157 +/* The following OTP-related defines are new for PKCS #11 v2.20 amendment 1 */
14158 +#define CKF_NEXT_OTP          0x00000001
14159 +#define CKF_EXCLUDE_TIME      0x00000002
14160 +#define CKF_EXCLUDE_COUNTER   0x00000004
14161 +#define CKF_EXCLUDE_CHALLENGE 0x00000008
14162 +#define CKF_EXCLUDE_PIN       0x00000010
14163 +#define CKF_USER_FRIENDLY_OTP 0x00000020
14165 +/* CK_KIP_PARAMS is new for PKCS #11 v2.20 amendment 2 */
14166 +typedef struct CK_KIP_PARAMS {
14167 +    CK_MECHANISM_PTR  pMechanism;
14168 +    CK_OBJECT_HANDLE  hKey;
14169 +    CK_BYTE_PTR       pSeed;
14170 +    CK_ULONG          ulSeedLen;
14171 +} CK_KIP_PARAMS;
14173 +typedef CK_KIP_PARAMS CK_PTR CK_KIP_PARAMS_PTR;
14175 +/* CK_AES_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
14176 +typedef struct CK_AES_CTR_PARAMS {
14177 +    CK_ULONG ulCounterBits;
14178 +    CK_BYTE cb[16];
14179 +} CK_AES_CTR_PARAMS;
14181 +typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR;
14183 +/* CK_CAMELLIA_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
14184 +typedef struct CK_CAMELLIA_CTR_PARAMS {
14185 +    CK_ULONG ulCounterBits;
14186 +    CK_BYTE cb[16];
14187 +} CK_CAMELLIA_CTR_PARAMS;
14189 +typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR;
14191 +/* CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
14192 +typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS {
14193 +    CK_BYTE      iv[16];
14194 +    CK_BYTE_PTR  pData;
14195 +    CK_ULONG     length;
14196 +} CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS;
14198 +typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
14200 +/* CK_ARIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
14201 +typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS {
14202 +    CK_BYTE      iv[16];
14203 +    CK_BYTE_PTR  pData;
14204 +    CK_ULONG     length;
14205 +} CK_ARIA_CBC_ENCRYPT_DATA_PARAMS;
14207 +typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
14209 +#endif
14210 Index: openssl/util/libeay.num
14211 diff -u openssl/util/libeay.num:1.1.3.1 openssl/util/libeay.num:1.6
14212 --- openssl/util/libeay.num:1.1.3.1     Mon Feb  2 00:27:56 2009
14213 +++ openssl/util/libeay.num     Mon Oct  5 13:17:03 2009
14214 @@ -3725,3 +3725,5 @@
14215  JPAKE_STEP3A_init                       4111   EXIST::FUNCTION:JPAKE
14216  ERR_load_JPAKE_strings                  4112   EXIST::FUNCTION:JPAKE
14217  JPAKE_STEP2_init                        4113   EXIST::FUNCTION:JPAKE
14218 +ENGINE_load_pk11ca                      4114   EXIST::FUNCTION:HW_PKCS11CA,ENGINE
14219 +ENGINE_load_pk11so                      4114   EXIST::FUNCTION:HW_PKCS11SO,ENGINE
14220 Index: openssl/util/mk1mf.pl
14221 diff -u openssl/util/mk1mf.pl:1.1.3.1 openssl/util/mk1mf.pl:1.7
14222 --- openssl/util/mk1mf.pl:1.1.3.1       Tue Dec  2 23:50:21 2008
14223 +++ openssl/util/mk1mf.pl       Mon Oct  5 13:17:05 2009
14224 @@ -87,6 +87,8 @@
14225         no-ecdh                                 - No ECDH
14226         no-engine                               - No engine
14227         no-hw                                   - No hw
14228 +       no-hw-pkcs11ca                          - No hw PKCS#11 CA flavor
14229 +       no-hw-pkcs11so                          - No hw PKCS#11 SO flavor
14230         nasm                                    - Use NASM for x86 asm
14231         nw-nasm                                 - Use NASM x86 asm for NetWare
14232         nw-mwasm                                - Use Metrowerks x86 asm for NetWare
14233 @@ -242,6 +244,8 @@
14234  $cflags.=" -DOPENSSL_NO_ECDH" if $no_ecdh;
14235  $cflags.=" -DOPENSSL_NO_ENGINE"   if $no_engine;
14236  $cflags.=" -DOPENSSL_NO_HW"   if $no_hw;
14237 +$cflags.=" -DOPENSSL_NO_HW_PKCS11CA"   if $no_hw_pkcs11ca;
14238 +$cflags.=" -DOPENSSL_NO_HW_PKCS11SO"   if $no_hw_pkcs11so;
14239  $cflags.=" -DOPENSSL_FIPS"    if $fips;
14240  $cflags.= " -DZLIB" if $zlib_opt;
14241  $cflags.= " -DZLIB_SHARED" if $zlib_opt == 2;
14242 @@ -322,6 +326,9 @@
14243         if ($key eq "ZLIB_INCLUDE")
14244                 { $cflags .= " $val" if $val ne "";}
14246 +       if ($key eq "PK11_LIB_LOCATION")
14247 +               { $cflags .= " -D$key=\\\"$val\\\"" if $val ne "";}
14249         if ($key eq "LIBZLIB")
14250                 { $zlib_lib = "$val" if $val ne "";}
14252 @@ -1300,6 +1307,8 @@
14253                 "no-ecdh" => \$no_ecdh,
14254                 "no-engine" => \$no_engine,
14255                 "no-hw" => \$no_hw,
14256 +               "no-hw-pkcs11ca" => \$no_hw_pkcs11ca,
14257 +               "no-hw-pkcs11so" => \$no_hw_pkcs11so,
14258                 "just-ssl" =>
14259                         [\$no_rc2, \$no_idea, \$no_des, \$no_bf, \$no_cast,
14260                           \$no_md2, \$no_sha, \$no_mdc2, \$no_dsa, \$no_dh,
14261 Index: openssl/util/mkdef.pl
14262 diff -u openssl/util/mkdef.pl:1.1.3.1 openssl/util/mkdef.pl:1.5
14263 --- openssl/util/mkdef.pl:1.1.3.1       Mon Nov 24 16:14:15 2008
14264 +++ openssl/util/mkdef.pl       Mon Oct  5 13:17:05 2009
14265 @@ -93,7 +93,7 @@
14266                          # External "algorithms"
14267                          "FP_API", "STDIO", "SOCK", "KRB5", "DGRAM",
14268                          # Engines
14269 -                        "STATIC_ENGINE", "ENGINE", "HW", "GMP",
14270 +                        "STATIC_ENGINE", "ENGINE", "HW", "GMP", "HW_PKCS11CA", "HW_PKCS11SO",
14271                          # RFC3779 support 
14272                          "RFC3779",
14273                          # TLS extension support
14274 @@ -122,6 +122,7 @@
14275  my $no_md2; my $no_md4; my $no_md5; my $no_sha; my $no_ripemd; my $no_mdc2;
14276  my $no_rsa; my $no_dsa; my $no_dh; my $no_hmac=0; my $no_aes; my $no_krb5;
14277  my $no_ec; my $no_ecdsa; my $no_ecdh; my $no_engine; my $no_hw; my $no_camellia;
14278 +my $no_pkcs11ca; my $no_pkcs11so;
14279  my $no_seed;
14280  my $no_fp_api; my $no_static_engine; my $no_gmp; my $no_deprecated;
14281  my $no_rfc3779; my $no_tlsext; my $no_cms; my $no_capieng; my $no_jpake;
14282 @@ -214,6 +215,8 @@
14283         elsif (/^no-cms$/)      { $no_cms=1; }
14284         elsif (/^no-capieng$/)  { $no_capieng=1; }
14285         elsif (/^no-jpake$/)    { $no_jpake=1; }
14286 +       elsif (/^no-hw-pkcs11ca$/) { $no_pkcs11ca=1; }
14287 +       elsif (/^no-hw-pkcs11so$/) { $no_pkcs11so=1; }
14288         }
14291 @@ -1138,6 +1141,8 @@
14292                         if ($keyword eq "KRB5" && $no_krb5) { return 0; }
14293                         if ($keyword eq "ENGINE" && $no_engine) { return 0; }
14294                         if ($keyword eq "HW" && $no_hw) { return 0; }
14295 +                       if ($keyword eq "HW_PKCS11CA" && $no_pkcs11ca) { return 0; }
14296 +                       if ($keyword eq "HW_PKCS11SO" && $no_pkcs11so) { return 0; }
14297                         if ($keyword eq "FP_API" && $no_fp_api) { return 0; }
14298                         if ($keyword eq "STATIC_ENGINE" && $no_static_engine) { return 0; }
14299                         if ($keyword eq "GMP" && $no_gmp) { return 0; }
14300 Index: openssl/util/pl/VC-32.pl
14301 diff -u openssl/util/pl/VC-32.pl:1.1.3.1 openssl/util/pl/VC-32.pl:1.5
14302 --- openssl/util/pl/VC-32.pl:1.1.3.1    Mon Mar  9 12:14:08 2009
14303 +++ openssl/util/pl/VC-32.pl    Fri Sep  4 10:43:23 2009
14304 @@ -113,7 +113,7 @@
14305      my $f = $shlib || $fips ?' /MD':' /MT';
14306      $lib_cflag='/Zl' if (!$shlib);     # remove /DEFAULTLIBs from static lib
14307      $opt_cflags=$f.' /Ox /O2 /Ob2';
14308 -    $dbg_cflags=$f.'d /Od -DDEBUG -D_DEBUG';
14309 +    $dbg_cflags=$f.'d /Od /Zi -DDEBUG -D_DEBUG';
14310      $lflags="/nologo /subsystem:console /opt:ref";
14311      }
14312  $mlflags='';